private void processHead(ChannelHandlerContext context, FullHttpRequest request) { HttpHeaders headers = request.headers(); FullHttpResponse response = null; if (headers.contains(Names.CONTENT_LENGTH)) { try { File file = getRequestedFile(request.getUri()); response = new DefaultFullHttpResponse( HTTP_1_1, request.getDecoderResult().isSuccess() ? OK : BAD_REQUEST); HttpHeaders.setContentLength(response, file.length()); } catch (FileNotFoundException | URISyntaxException e) { response = getBadRequest(e.getMessage()); } } context.writeAndFlush(response); }
private static void writeHttpResponse( ChannelHandlerContext ctx, FullHttpRequest req, FullHttpResponse res, Boolean close) { if (!omitDateHeader && !res.headers().contains(DefaultHttpHeaders.Names.DATE)) DefaultHttpHeaders.addDateHeader(res, DefaultHttpHeaders.Names.DATE, new Date()); // Send the response and close the connection if necessary. if (!HttpHeaders.isKeepAlive(req) || res.getStatus().code() != 200 || close == null || close) { res.headers().set(CONNECTION, HttpHeaders.Values.CLOSE); ctx.writeAndFlush(res).addListener(ChannelFutureListener.CLOSE); } else { res.headers().set(CONNECTION, HttpHeaders.Values.KEEP_ALIVE); write(ctx, res); } }
private void processGet(ChannelHandlerContext context, FullHttpRequest request) { try { File file = getRequestedFile(request.getUri()); RandomAccessFile raf = new RandomAccessFile(file, "r"); long fileLength = raf.length(); HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK); HttpHeaders.setContentLength(response, fileLength); setContentTypeHeader(response, file); context.write(response); context.write(new DefaultFileRegion(raf.getChannel(), 0, fileLength)); // Write the end marker. ChannelFuture future = context.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT); future.addListener(ChannelFutureListener.CLOSE); } catch (IOException | URISyntaxException e) { context.writeAndFlush(getBadRequest(e.getMessage())); } }
private static void sendHttpRedirect( ChannelHandlerContext ctx, FullHttpRequest req, String newUri) { final FullHttpResponse res = new DefaultFullHttpResponse(req.getProtocolVersion(), FOUND); HttpHeaders.setHeader(res, LOCATION, newUri); writeHttpResponse(ctx, req, res, true); }
@Override public final boolean trySend(HttpResponse message) { try { final HttpRequestWrapper nettyRequest = (HttpRequestWrapper) message.getRequest(); final FullHttpRequest req = nettyRequest.req; final ChannelHandlerContext ctx = nettyRequest.ctx; final HttpResponseStatus status = HttpResponseStatus.valueOf(message.getStatus()); if (message.getStatus() >= 400 && message.getStatus() < 600) { sendHttpResponse( ctx, req, new DefaultFullHttpResponse(req.getProtocolVersion(), status), false); close(); return true; } if (message.getRedirectPath() != null) { sendHttpRedirect(ctx, req, message.getRedirectPath()); close(); return true; } FullHttpResponse res; if (message.getStringBody() != null) res = new DefaultFullHttpResponse( req.getProtocolVersion(), status, Unpooled.wrappedBuffer(message.getStringBody().getBytes())); else if (message.getByteBufferBody() != null) res = new DefaultFullHttpResponse( req.getProtocolVersion(), status, Unpooled.wrappedBuffer(message.getByteBufferBody())); else res = new DefaultFullHttpResponse(req.getProtocolVersion(), status); if (message.getCookies() != null) { final ServerCookieEncoder enc = ServerCookieEncoder.STRICT; for (final Cookie c : message.getCookies()) HttpHeaders.setHeader(res, COOKIE, enc.encode(getNettyCookie(c))); } if (message.getHeaders() != null) { for (final Map.Entry<String, String> h : message.getHeaders().entries()) HttpHeaders.setHeader(res, h.getKey(), h.getValue()); } if (message.getContentType() != null) { String ct = message.getContentType(); if (message.getCharacterEncoding() != null) ct = ct + "; charset=" + message.getCharacterEncoding().name(); HttpHeaders.setHeader(res, CONTENT_TYPE, ct); } final boolean sseStarted = message.shouldStartActor(); if (trackSession(sseStarted)) { final String sessionId = UUID.randomUUID().toString(); res.headers() .add(SET_COOKIE, ServerCookieEncoder.STRICT.encode(SESSION_COOKIE_KEY, sessionId)); startSession(sessionId, actorContext); } if (!sseStarted) { final String stringBody = message.getStringBody(); long contentLength = 0L; if (stringBody != null) contentLength = stringBody.getBytes().length; else { final ByteBuffer byteBufferBody = message.getByteBufferBody(); if (byteBufferBody != null) contentLength = byteBufferBody.remaining(); } res.headers().add(CONTENT_LENGTH, contentLength); } final HttpStreamActorAdapter httpStreamActorAdapter; if (sseStarted) // This will copy the request content, which must still be referenceable, doing before the // request handler // unallocates it (unfortunately it is explicitly reference-counted in Netty) httpStreamActorAdapter = new HttpStreamActorAdapter(ctx, req); else httpStreamActorAdapter = null; sendHttpResponse(ctx, req, res, false); if (sseStarted) { if (httpResponseEncoderName != null) { ctx.pipeline().remove(httpResponseEncoderName); } else { final ChannelPipeline pl = ctx.pipeline(); final List<String> handlerKeysToBeRemoved = new ArrayList<>(); for (final Map.Entry<String, ChannelHandler> e : pl) { if (e.getValue() instanceof HttpResponseEncoder) handlerKeysToBeRemoved.add(e.getKey()); } for (final String k : handlerKeysToBeRemoved) pl.remove(k); } try { message.getFrom().send(new HttpStreamOpened(httpStreamActorAdapter.ref(), message)); } catch (SuspendExecution e) { throw new AssertionError(e); } } return true; } finally { if (actor != null) actor.unwatch(); } }