@Override protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception { FullHttpRequest req = (FullHttpRequest) msg; String upgrade = req.headers().get(HttpHeaders.Names.UPGRADE); if (HttpHeaders.Values.WEBSOCKET.equalsIgnoreCase(upgrade)) { WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(req.getUri(), null, false); WebSocketServerHandshaker handshaker = wsFactory.newHandshaker(req); if (handshaker == null) { WebSocketServerHandshakerFactory.sendUnsupportedWebSocketVersionResponse(ctx.channel()); } else { ChannelFuture future = handshaker.handshake(ctx.channel(), req); future.addListener( f -> { this.configurator.switchToWebSockets(ctx.pipeline()); }); } } else { ReferenceCountUtil.retain(msg); this.configurator.switchToPlainHttp(ctx.pipeline()); ChannelHandlerContext agg = ctx.pipeline().context(HttpObjectAggregator.class); agg.fireChannelRead(msg); } }
@Override protected void channelRead( final C connection, final ContextImpl context, final ChannelHandlerContext chctx, final Object msg) throws Exception { if (msg instanceof HttpObject) { DecoderResult result = ((HttpObject) msg).getDecoderResult(); if (result.isFailure()) { chctx.pipeline().fireExceptionCaught(result.cause()); return; } } if (connection != null) { // we are reading from the channel // We need to do this since it's possible the server is being used from a worker context context.execute(() -> doMessageReceived(connection, chctx, msg), true); } else { // We execute this directly as we don't have a context yet, the context will have to be set // manually // inside doMessageReceived(); try { doMessageReceived(null, chctx, msg); } catch (Throwable t) { chctx.pipeline().fireExceptionCaught(t); } } }
@Override public SocksRequest decode(ChannelHandlerContext ctx, ByteBuf byteBuf) throws Exception { switch (state()) { case CHECK_PROTOCOL_VERSION: { version = SocksMessage.ProtocolVersion.fromByte(byteBuf.readByte()); if (version != SocksMessage.ProtocolVersion.SOCKS5) { break; } checkpoint(State.READ_AUTH_SCHEMES); } case READ_AUTH_SCHEMES: { authSchemes.clear(); authSchemeNum = byteBuf.readByte(); for (int i = 0; i < authSchemeNum; i++) { authSchemes.add(SocksMessage.AuthScheme.fromByte(byteBuf.readByte())); } msg = new SocksInitRequest(authSchemes); break; } } ctx.pipeline().remove(this); return msg; }
/** * Create an instance of NettyResponseChannel that will use {@code ctx} to return responses. * * @param ctx the {@link ChannelHandlerContext} to use. * @param nettyMetrics the {@link NettyMetrics} instance to use. */ public NettyResponseChannel(ChannelHandlerContext ctx, NettyMetrics nettyMetrics) { this.ctx = ctx; this.nettyMetrics = nettyMetrics; chunkedWriteHandler = ctx.pipeline().get(ChunkedWriteHandler.class); writeFuture = ctx.newProgressivePromise(); logger.trace("Instantiated NettyResponseChannel"); }
@Override protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List<Object> out) throws Exception { switch (state()) { case CHECK_NULL_BYTE: { if (byteBuf.readByte() != (byte) 0x00) { break; } checkpoint(State.READ_CMD_HEADER); } case READ_CMD_HEADER: { cmdStatus = Socks4CmdStatus.valueOf(byteBuf.readByte()); checkpoint(State.READ_CMD_ADDRESS); } case READ_CMD_ADDRESS: { port = byteBuf.readUnsignedShort(); host = Socks4CommonUtils.intToIp(byteBuf.readInt()); msg = new Socks4CmdResponse(cmdStatus, host, port); } } ctx.pipeline().remove(this); out.add(msg); }
@Override public void channelActive(final ChannelHandlerContext ctx) { // Once session is secured, send a greeting and register the channel to the global channel // list so the channel received the messages from others. ctx.pipeline() .get(SslHandler.class) .handshakeFuture() .addListener( new GenericFutureListener<Future<Channel>>() { @Override public void operationComplete(Future<Channel> future) throws Exception { ctx.writeAndFlush( "Welcome to " + InetAddress.getLocalHost().getHostName() + " secure chat service!\n"); ctx.writeAndFlush( "Your session is protected by " + ctx.pipeline() .get(SslHandler.class) .engine() .getSession() .getCipherSuite() + " cipher suite.\n"); channels.add(ctx.channel()); } }); }
@Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { log.debug( "channelIdle on OFChannelHandler {}", String.format("%08x", System.identityHashCode(this))); OFChannelHandler handler = ctx.pipeline().get(OFChannelHandler.class); handler.sendEchoRequest(); }
@Override protected boolean handleProxyProtocol(ChannelHandlerContext ctx, Object msg) throws Exception { Socks4CommandRequest req = (Socks4CommandRequest) msg; boolean authzSuccess = authenticate(ctx, req); Socks4CommandResponse res; boolean sendGreeting = false; if (!authzSuccess) { res = new DefaultSocks4CommandResponse(Socks4CommandStatus.IDENTD_AUTH_FAILURE); } else if (!req.dstAddr().equals(destination.getHostString()) || req.dstPort() != destination.getPort()) { res = new DefaultSocks4CommandResponse(Socks4CommandStatus.REJECTED_OR_FAILED); } else { res = new DefaultSocks4CommandResponse(Socks4CommandStatus.SUCCESS); sendGreeting = true; } ctx.write(res); ctx.pipeline().remove(Socks4ServerDecoder.class); ctx.pipeline().remove(Socks4ServerEncoder.class); if (sendGreeting) { ctx.write(Unpooled.copiedBuffer("0\n", CharsetUtil.US_ASCII)); } return true; }
@Override protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { ChannelPipeline p = ctx.pipeline(); SocksProtocolVersion version = SocksProtocolVersion.valueOf(in.readByte()); System.out.println(version); in.resetReaderIndex(); switch (version) { case SOCKS4a: p.addLast(new Socks4CmdRequestDecoder()); p.addLast(Socks4MessageEncoder.INSTANCE); break; case SOCKS5: p.addLast(new Socks5InitRequestDecoder()); p.addLast(Socks5MessageEncoder.INSTANCE); break; case UNKNOWN: in.clear(); ctx.close(); return; } p.addLast(SocksServerHandler.INSTANCE); p.remove(this); }
private boolean initPipeline(ChannelHandlerContext var1) { SslHandler var2 = (SslHandler) var1.pipeline().get(SslHandler.class); if (var2 == null) { throw new IllegalStateException("SslHandler is needed for SPDY"); } else { SpdyOrHttpChooser.SelectedProtocol var3 = this.getProtocol(var2.engine()); switch (SpdyOrHttpChooser.SyntheticClass_1 .$SwitchMap$io$netty$handler$codec$spdy$SpdyOrHttpChooser$SelectedProtocol[ var3.ordinal()]) { case 1: return false; case 2: this.addSpdyHandlers(var1, SpdyVersion.SPDY_3_1); break; case 3: case 4: this.addHttpHandlers(var1); break; default: throw new IllegalStateException("Unknown SelectedProtocol"); } return true; } }
private void onCreate(ChannelHandlerContext ctx) throws IOException, URISyntaxException { writeContinueHeader(ctx); final String nnId = params.namenodeId(); final int bufferSize = params.bufferSize(); final short replication = params.replication(); final long blockSize = params.blockSize(); final FsPermission permission = params.permission(); EnumSet<CreateFlag> flags = params.overwrite() ? EnumSet.of(CreateFlag.CREATE, CreateFlag.OVERWRITE) : EnumSet.of(CreateFlag.CREATE); final DFSClient dfsClient = newDfsClient(nnId, confForCreate); OutputStream out = dfsClient.createWrappedOutputStream( dfsClient.create( path, permission, flags, replication, blockSize, null, bufferSize, null), null); DefaultHttpResponse resp = new DefaultHttpResponse(HTTP_1_1, CREATED); final URI uri = new URI(HDFS_URI_SCHEME, nnId, path, null, null); resp.headers().set(LOCATION, uri.toString()); resp.headers().set(CONTENT_LENGTH, 0); ctx.pipeline() .replace(this, HdfsWriter.class.getSimpleName(), new HdfsWriter(dfsClient, out, resp)); }
@Override protected void channelRead0(ChannelHandlerContext ctx, LoginMessage message) throws Exception { String token = message.body.trim(); User user = userDao.tokenManager.getUserByToken(token); if (user == null) { log.debug( "HardwareLogic token is invalid. Token '{}', '{}'", token, ctx.channel().remoteAddress()); ctx.writeAndFlush(new ResponseMessage(message.id, Response.INVALID_TOKEN)); return; } final Integer dashId = UserDao.getDashIdByToken(user.dashTokens, token, message.id); // todo find out why this happen DashBoard dash = user.profile.getDashById(dashId); if (dash == null) { log.error( "User : {} requested token {} for non-existing {} dash id.", user.name, token, dashId); ctx.writeAndFlush(new ResponseMessage(message.id, Response.INVALID_TOKEN)); return; } ctx.pipeline().remove(this); ctx.pipeline().remove(UserNotLoggedHandler.class); ctx.pipeline() .addLast( new HardwareHandler( props, sessionDao, reportingDao, blockingIOProcessor, new HardwareStateHolder(dashId, user, token))); Session session = sessionDao.getSessionByUser(user, ctx.channel().eventLoop()); if (session.initialEventLoop != ctx.channel().eventLoop()) { log.debug("Re registering hard channel. {}", ctx.channel()); reRegisterChannel( ctx, session, channelFuture -> completeLogin(channelFuture.channel(), session, user, dash, message.id)); } else { completeLogin(ctx.channel(), session, user, dash, message.id); } }
protected void addHttpHandlers(ChannelHandlerContext var1) { ChannelPipeline var2 = var1.pipeline(); var2.addLast((String) "httpRequestDecoder", (ChannelHandler) (new HttpRequestDecoder())); var2.addLast((String) "httpResponseEncoder", (ChannelHandler) (new HttpResponseEncoder())); var2.addLast( (String) "httpChunkAggregator", (ChannelHandler) (new HttpObjectAggregator(this.maxHttpContentLength))); var2.addLast( (String) "httpRequestHandler", (ChannelHandler) this.createHttpRequestHandlerForHttp()); }
@Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { if (evt == WebSocketServerProtocolHandler.ServerHandshakeStateEvent.HANDSHAKE_COMPLETE) { ctx.pipeline().remove(HttpRequestHandler.class); group.writeAndFlush(new TextWebSocketFrame("Client " + ctx.channel() + " joined!")); group.add(ctx.channel()); } else { super.userEventTriggered(ctx, evt); } }
@Override protected void messageReceived(ChannelHandlerContext ctx, FullHttpResponse msg) throws Exception { if (!handshaker.isHandshakeComplete()) { handshaker.finishHandshake(ctx.channel(), msg); ctx.fireUserEventTriggered( WebSocketClientProtocolHandler.ClientHandshakeStateEvent.HANDSHAKE_COMPLETE); ctx.pipeline().remove(this); return; } throw new IllegalStateException("WebSocketClientHandshaker should have been non finished yet"); }
protected void decode(ChannelHandlerContext context, ByteBuf buffer) throws Exception { ChannelPipeline pipeline = context.pipeline(); if (detectSsl && SslHandler.isEncrypted(buffer)) { SSLEngine engine = SSL_SERVER_CONTEXT.getValue().createSSLEngine(); engine.setUseClientMode(false); pipeline.addLast( new SslHandler(engine), new ChunkedWriteHandler(), new PortUnificationServerHandler(delegatingHttpRequestHandler, false, detectGzip)); } else { int magic1 = buffer.getUnsignedByte(buffer.readerIndex()); int magic2 = buffer.getUnsignedByte(buffer.readerIndex() + 1); if (detectGzip && magic1 == 31 && magic2 == 139) { pipeline.addLast( new JZlibEncoder(ZlibWrapper.GZIP), new JdkZlibDecoder(ZlibWrapper.GZIP), new PortUnificationServerHandler(delegatingHttpRequestHandler, detectSsl, false)); } else if (isHttp(magic1, magic2)) { NettyUtil.initHttpHandlers(pipeline); pipeline.addLast(delegatingHttpRequestHandler); if (BuiltInServer.LOG.isDebugEnabled()) { pipeline.addLast( new ChannelOutboundHandlerAdapter() { @Override public void write( ChannelHandlerContext context, Object message, ChannelPromise promise) throws Exception { if (message instanceof HttpResponse) { // BuiltInServer.LOG.debug("OUT HTTP:\n" + message); HttpResponse response = (HttpResponse) message; BuiltInServer.LOG.debug( "OUT HTTP: " + response.getStatus().code() + " " + response.headers().get("Content-type")); } super.write(context, message, promise); } }); } } else if (magic1 == 'C' && magic2 == 'H') { buffer.skipBytes(2); pipeline.addLast(new CustomHandlerDelegator()); } else { BuiltInServer.LOG.warn("unknown request, first two bytes " + magic1 + " " + magic2); context.close(); } } // must be after new channels handlers addition (netty bug?) ensureThatExceptionHandlerIsLast(pipeline); pipeline.remove(this); context.fireChannelRead(buffer); }
private void onAppend(ChannelHandlerContext ctx) throws IOException { writeContinueHeader(ctx); final String nnId = params.namenodeId(); final int bufferSize = params.bufferSize(); DFSClient dfsClient = newDfsClient(nnId, conf); OutputStream out = dfsClient.append(path, bufferSize, EnumSet.of(CreateFlag.APPEND), null, null); DefaultHttpResponse resp = new DefaultHttpResponse(HTTP_1_1, OK); resp.headers().set(CONTENT_LENGTH, 0); ctx.pipeline() .replace(this, HdfsWriter.class.getSimpleName(), new HdfsWriter(dfsClient, out, resp)); }
protected void addSpdyHandlers(ChannelHandlerContext var1, SpdyVersion var2) { ChannelPipeline var3 = var1.pipeline(); var3.addLast((String) "spdyFrameCodec", (ChannelHandler) (new SpdyFrameCodec(var2))); var3.addLast( (String) "spdySessionHandler", (ChannelHandler) (new SpdySessionHandler(var2, true))); var3.addLast((String) "spdyHttpEncoder", (ChannelHandler) (new SpdyHttpEncoder(var2))); var3.addLast( (String) "spdyHttpDecoder", (ChannelHandler) (new SpdyHttpDecoder(var2, this.maxSpdyContentLength))); var3.addLast( (String) "spdyStreamIdHandler", (ChannelHandler) (new SpdyHttpResponseStreamIdHandler())); var3.addLast( (String) "httpRequestHandler", (ChannelHandler) this.createHttpRequestHandlerForSpdy()); }
@Override public void send(final InputStream stream) throws Exception { byte[] chunk = new byte[bufferSize]; int count = ByteStreams.read(stream, chunk, 0, bufferSize); if (count <= 0) { return; } ByteBuf buffer = Unpooled.wrappedBuffer(chunk, 0, count); if (count < bufferSize) { send(buffer); } else { DefaultHttpResponse rsp = new DefaultHttpResponse(HttpVersion.HTTP_1_1, status); if (!headers.contains(HttpHeaderNames.CONTENT_LENGTH)) { headers.set(HttpHeaderNames.TRANSFER_ENCODING, HttpHeaderValues.CHUNKED); } else { if (keepAlive) { headers.set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE); } } // dump headers rsp.headers().set(headers); ChannelHandlerContext ctx = this.ctx; ctx.attr(NettyRequest.NEED_FLUSH).set(false); // add chunker ChannelPipeline pipeline = ctx.pipeline(); if (pipeline.get("chunker") == null) { pipeline.addAfter("encoder", "chunker", new ChunkedWriteHandler()); } // group all write ctx.channel() .eventLoop() .execute( () -> { // send headers ctx.write(rsp); // send head chunk ctx.write(buffer); // send tail ctx.write(new ChunkedStream(stream, bufferSize)); keepAlive(ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT)); }); } committed = true; }
private boolean authenticate(ChannelHandlerContext ctx, Socks4CommandRequest req) { assertThat(req.type(), is(Socks4CommandType.CONNECT)); if (testMode != TestMode.INTERMEDIARY) { ctx.pipeline() .addBefore(ctx.name(), "lineDecoder", new LineBasedFrameDecoder(64, false, true)); } boolean authzSuccess; if (username != null) { authzSuccess = username.equals(req.userId()); } else { authzSuccess = true; } return authzSuccess; }
public NettyServerConnection createConnection( final ChannelHandlerContext ctx, String protocol, boolean httpEnabled) throws Exception { if (connectionsAllowed == -1 || connections.size() < connectionsAllowed) { super.channelActive(ctx); Listener connectionListener = new Listener(); NettyServerConnection nc = new NettyServerConnection( configuration, ctx.channel(), connectionListener, !httpEnabled && batchDelay > 0, directDeliver); connectionListener.connectionCreated(NettyAcceptor.this, nc, protocol); SslHandler sslHandler = ctx.pipeline().get(SslHandler.class); if (sslHandler != null) { sslHandler .handshakeFuture() .addListener( new GenericFutureListener<io.netty.util.concurrent.Future<Channel>>() { public void operationComplete( final io.netty.util.concurrent.Future<Channel> future) throws Exception { if (future.isSuccess()) { active = true; } else { future.getNow().close(); } } }); } else { active = true; } return nc; } else { if (ActiveMQServerLogger.LOGGER.isDebugEnabled()) { ActiveMQServerLogger.LOGGER.debug( new StringBuilder() .append("Connection limit of ") .append(connectionsAllowed) .append(" reached. Refusing connection from ") .append(ctx.channel().remoteAddress())); } throw new Exception(); } }
@Override protected boolean handleProxyProtocol(ChannelHandlerContext ctx, Object msg) throws Exception { Socks4CmdRequest req = (Socks4CmdRequest) msg; Socks4CmdResponse res; if (!authenticate(ctx, req)) { res = new Socks4CmdResponse(Socks4CmdStatus.IDENTD_AUTH_FAILURE); } else { res = new Socks4CmdResponse(Socks4CmdStatus.SUCCESS); intermediaryDestination = new InetSocketAddress(req.host(), req.port()); } ctx.write(res); ctx.pipeline().remove(Socks4MessageEncoder.class); return true; }
@Override protected void channelRead0(ChannelHandlerContext context, ByteBuf message) throws Exception { ByteBuf buffer = getBufferIfSufficient(message, UUID_LENGTH, context); if (buffer == null) { message.release(); } else { UUID uuid = new UUID(buffer.readLong(), buffer.readLong()); for (BinaryRequestHandler customHandler : BinaryRequestHandler.EP_NAME.getExtensions()) { if (uuid.equals(customHandler.getId())) { ChannelPipeline pipeline = context.pipeline(); pipeline.addLast(customHandler.getInboundHandler()); ensureThatExceptionHandlerIsLast(pipeline); pipeline.remove(this); context.fireChannelRead(buffer); break; } } } }
@Override public void write(ChannelHandlerContext ctx, Object msg) throws Exception { Assert.assertSame(t, Thread.currentThread()); // Don't let the write request go to the server-side channel - just swallow. boolean swallow = this == ctx.pipeline().first(); ByteBuf m = (ByteBuf) msg; int count = m.readableBytes() / 4; for (int j = 0; j < count; j++) { int actual = m.readInt(); int expected = outCnt++; Assert.assertEquals(expected, actual); if (!swallow) { ctx.write(actual); } } m.release(); }
@Override public void userEventTriggered(final ChannelHandlerContext ctx, Object evt) throws Exception { if (evt instanceof IdleStateEvent) { IdleStateEvent e = (IdleStateEvent) evt; if (e.state() == IdleState.ALL_IDLE) { CouchbaseRequest keepAlive = createKeepAliveRequest(); if (keepAlive != null) { keepAlive.observable().subscribe(new KeepAliveResponseAction(ctx)); onKeepAliveFired(ctx, keepAlive); Channel channel = ctx.channel(); if (channel.isActive() && channel.isWritable()) { ctx.pipeline().writeAndFlush(keepAlive); } } } } else { super.userEventTriggered(ctx, evt); } }
@Override protected void handleOversizedMessage(final ChannelHandlerContext ctx, HttpMessage oversized) throws Exception { if (oversized instanceof HttpRequest) { // send back a 413 and close the connection ChannelFuture future = ctx.writeAndFlush(TOO_LARGE.duplicate().retain()) .addListener( new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { if (!future.isSuccess()) { logger.debug( "Failed to send a 413 Request Entity Too Large.", future.cause()); ctx.close(); } } }); // If the client started to send data already, close because it's impossible to recover. // If keep-alive is off and 'Expect: 100-continue' is missing, no need to leave the connection // open. if (oversized instanceof FullHttpMessage || !HttpUtil.is100ContinueExpected(oversized) && !HttpUtil.isKeepAlive(oversized)) { future.addListener(ChannelFutureListener.CLOSE); } // If an oversized request was handled properly and the connection is still alive // (i.e. rejected 100-continue). the decoder should prepare to handle a new message. HttpObjectDecoder decoder = ctx.pipeline().get(HttpObjectDecoder.class); if (decoder != null) { decoder.reset(); } } else if (oversized instanceof HttpResponse) { ctx.close(); throw new TooLongFrameException("Response entity too large: " + oversized); } else { throw new IllegalStateException(); } }
@Override protected void channelRead( final C connection, final DefaultContext context, final ChannelHandlerContext chctx, final Object msg) throws Exception { if (connection != null) { // we are reading from the channel Channel ch = chctx.channel(); // We need to do this since it's possible the server is being used from a worker context if (context.isOnCorrectWorker(ch.eventLoop())) { try { vertx.setContext(context); doMessageReceived(connection, chctx, msg); } catch (Throwable t) { context.reportException(t); } } else { context.execute( new Runnable() { public void run() { try { doMessageReceived(connection, chctx, msg); } catch (Throwable t) { context.reportException(t); } } }); } } else { try { doMessageReceived(connection, chctx, msg); } catch (Throwable t) { chctx.pipeline().fireExceptionCaught(t); } } }
public static void replaceDefaultHandler( @NotNull ChannelHandlerContext context, @NotNull ChannelHandler channelHandler) { context .pipeline() .replace(DelegatingHttpRequestHandler.class, "replacedDefaultHandler", channelHandler); }
private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest request) { // Handle a bad request. if (!request.getDecoderResult().isSuccess()) { sendHttpResponse( ctx, request, new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.BAD_REQUEST)); return; } if (RouterHits.checkIfMappingExit(request)) { // Do Router Mapping First RouterHits.execute(ctx, request); return; } if ("/websocket".equals(request.getUri())) { // Handshake WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(getWebSocketLocation(request), null, true); handshaker = wsFactory.newHandshaker(request); if (handshaker == null) { WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel()); } else { handshaker.handshake(ctx.channel(), request); channels.add(ctx.channel()); } return; } final String uri = request.getUri(); // System.out.println("uri: " + uri); final String path = sanitizeUri("www", uri); // System.out.println("path: " + path); if (path == null) { sendHttpResponse( ctx, request, new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.FORBIDDEN)); return; } File file = new File(path); if (file.isHidden() || !file.exists()) { sendHttpResponse( ctx, request, new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.NOT_FOUND)); return; } if (file.isDirectory()) { if (uri.endsWith("/")) { File checkIndexFile = new File(file.getAbsolutePath() + File.separator + "index.html"); System.out.println(checkIndexFile.exists()); if (checkIndexFile.exists()) { file = checkIndexFile; } else { sendListing(ctx, file); return; } } else { sendRedirect(ctx, uri + '/'); } } if (!file.isFile()) { sendHttpResponse( ctx, request, new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.FORBIDDEN)); return; } // Cache Validation String ifModifiedSince = request.headers().get(IF_MODIFIED_SINCE); if (ifModifiedSince != null && !ifModifiedSince.isEmpty()) { SimpleDateFormat dateFormatter = new SimpleDateFormat(HTTP_DATE_FORMAT, Locale.US); Date ifModifiedSinceDate = null; try { ifModifiedSinceDate = dateFormatter.parse(ifModifiedSince); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } // Only compare up to the second because the datetime format we send to the client // does not have milliseconds long ifModifiedSinceDateSeconds = ifModifiedSinceDate.getTime() / 1000; long fileLastModifiedSeconds = file.lastModified() / 1000; if (ifModifiedSinceDateSeconds == fileLastModifiedSeconds) { sendNotModified(ctx); return; } } RandomAccessFile raf; try { raf = new RandomAccessFile(file, "r"); } catch (FileNotFoundException ignore) { sendHttpResponse( ctx, request, new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.NOT_FOUND)); return; } long fileLength = 0; try { fileLength = raf.length(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK); HttpHeaders.setContentLength(response, fileLength); setContentTypeHeader(response, file); setDateAndCacheHeaders(response, file); if (HttpHeaders.isKeepAlive(request)) { response.headers().set(CONNECTION, HttpHeaders.Values.KEEP_ALIVE); } // Write the initial line and the header. ctx.write(response); // Write the content. ChannelFuture sendFileFuture = null; ChannelFuture lastContentFuture; if (ctx.pipeline().get(SslHandler.class) == null) { sendFileFuture = ctx.write( new DefaultFileRegion(raf.getChannel(), 0, fileLength), ctx.newProgressivePromise()); // Write the end marker. lastContentFuture = ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT); } else { try { sendFileFuture = ctx.writeAndFlush( new HttpChunkedInput(new ChunkedFile(raf, 0, fileLength, 8192)), ctx.newProgressivePromise()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } // HttpChunkedInput will write the end marker (LastHttpContent) for us. lastContentFuture = sendFileFuture; } sendFileFuture.addListener( new ChannelProgressiveFutureListener() { @Override public void operationProgressed( ChannelProgressiveFuture future, long progress, long total) { if (total < 0) { // total unknown System.err.println(future.channel() + " Transfer progress: " + progress); } else { System.err.println( future.channel() + " Transfer progress: " + progress + " / " + total); } } @Override public void operationComplete(ChannelProgressiveFuture future) { System.err.println(future.channel() + " Transfer complete."); } }); // Decide whether to close the connection or not. if (!HttpHeaders.isKeepAlive(request)) { // Close the connection when the whole content is written out. lastContentFuture.addListener(ChannelFutureListener.CLOSE); } // // Send the demo page and favicon.ico // if ("/".equals(req.getUri()) && req.getMethod() == GET) { // ByteBuf content = WebSocketServerIndexPage.getContent(getWebSocketLocation(req)); // FullHttpResponse res = new DefaultFullHttpResponse(HTTP_1_1, OK, content); // // res.headers().set(CONTENT_TYPE, "text/html; charset=UTF-8"); // HttpHeaders.setContentLength(res, content.readableBytes()); // // sendHttpResponse(ctx, req, res); // return; // } // // if ("/favicon.ico".equals(req.getUri())) { // FullHttpResponse res = new DefaultFullHttpResponse(HTTP_1_1, NOT_FOUND); // sendHttpResponse(ctx, req, res); // return; // } sendHttpResponse( ctx, request, new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.FORBIDDEN)); return; }
protected void decode(ChannelHandlerContext var1, ByteBuf var2, List<Object> var3) throws Exception { if (this.initPipeline(var1)) { var1.pipeline().remove((ChannelHandler) this); } }