buf.writeBytes(request.getProtocolVersion().toString().getBytes("ASCII")); buf.writeByte(CR); buf.writeByte(LF);
@Override protected void encodeInitialLine(ChannelBuffer buf, HttpMessage message) throws Exception { HttpRequest request = (HttpRequest) message; buf.writeBytes(request.getMethod().toString().getBytes("ASCII")); buf.writeByte((byte) ' '); buf.writeBytes(request.getUri().getBytes("UTF-8")); buf.writeByte((byte) ' '); buf.writeBytes(request.getProtocolVersion().toString().getBytes("ASCII")); buf.writeByte((byte) '\r'); buf.writeByte((byte) '\n'); } }
/** * Implemented in accordance with RFC 7230 section 6.1 * https://tools.ietf.org/html/rfc7230#section-6.1 */ @Override public boolean keepAlive(HttpRequest request, HttpResponse response) { String responseConnectionHeader = connectionHeader(response); if (CLOSE.equalsIgnoreCase(responseConnectionHeader)) { return false; } else { String requestConnectionHeader = connectionHeader(request); if (request.getProtocolVersion() == HttpVersion.HTTP_1_0) { // only use keep-alive if both parties agreed upon it return KEEP_ALIVE.equalsIgnoreCase(requestConnectionHeader) && KEEP_ALIVE.equalsIgnoreCase(responseConnectionHeader); } else { // 1.1+, keep-alive is default behavior return !CLOSE.equalsIgnoreCase(requestConnectionHeader); } } }
private boolean isHttp10() { return nettyRequest.getProtocolVersion().equals(HttpVersion.HTTP_1_0); }
/** * Implemented in accordance with RFC 7230 section 6.1 * https://tools.ietf.org/html/rfc7230#section-6.1 */ @Override public boolean keepAlive(HttpRequest request, HttpResponse response) { String responseConnectionHeader = connectionHeader(response); if (CLOSE.equalsIgnoreCase(responseConnectionHeader)) { return false; } else { String requestConnectionHeader = connectionHeader(request); if (request.getProtocolVersion() == HttpVersion.HTTP_1_0) { // only use keep-alive if both parties agreed upon it return KEEP_ALIVE.equalsIgnoreCase(requestConnectionHeader) && KEEP_ALIVE.equalsIgnoreCase(responseConnectionHeader); } else { // 1.1+, keep-alive is default behavior return !CLOSE.equalsIgnoreCase(requestConnectionHeader); } } }
/** * Implemented in accordance with RFC 7230 section 6.1 * https://tools.ietf.org/html/rfc7230#section-6.1 */ @Override public boolean keepAlive(HttpRequest request, HttpResponse response) { String responseConnectionHeader = connectionHeader(response); if (CLOSE.equalsIgnoreCase(responseConnectionHeader)) { return false; } else { String requestConnectionHeader = connectionHeader(request); if (request.getProtocolVersion() == HttpVersion.HTTP_1_0) { // only use keep-alive if both parties agreed upon it return KEEP_ALIVE.equalsIgnoreCase(requestConnectionHeader) && KEEP_ALIVE.equalsIgnoreCase(responseConnectionHeader); } else { // 1.1+, keep-alive is default behavior return !CLOSE.equalsIgnoreCase(requestConnectionHeader); } } }
@Override public void closeRequested(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { // request can be null since close can be requested prior to receiving a message. if (request != null && request.getProtocolVersion() == HttpVersion.HTTP_1_1 && lastChunkSent.compareAndSet(false, true)) { e.getChannel().write(HttpChunk.LAST_CHUNK).addListener(ChannelFutureListener.CLOSE); } else { super.closeRequested(ctx, e); } }
@Override public void close() { boolean http10 = request.getProtocolVersion().equals(HttpVersion.HTTP_1_0); boolean close = HttpHeaders.Values.CLOSE.equalsIgnoreCase(request.getHeader(HttpHeaders.Names.CONNECTION)) || (http10 && !HttpHeaders.Values.KEEP_ALIVE.equalsIgnoreCase(request.getHeader(HttpHeaders.Names.CONNECTION))); logger.debug("netty http close = {}", close); if (close) { channel.close(); } }
private static void forbidden(final ChannelHandlerContext ctx, final HttpRequest request) { ctx.getChannel().write(new DefaultHttpResponse(request.getProtocolVersion(), FORBIDDEN)) .addListener(ChannelFutureListener.CLOSE); }
@Override protected HttpResponse createResponse(String contentType) { HttpResponse response = super.createResponse(contentType); if (request.getProtocolVersion().equals(HttpVersion.HTTP_1_1)) { response.setHeader(HttpHeaders.Names.TRANSFER_ENCODING, HttpHeaders.Values.CHUNKED); } return response; } }
private void writeResponse(Channel channel) { ChannelBuffer buf = ChannelBuffers.copiedBuffer( this.responseContent.toString(), CharsetUtil.UTF_8); this.responseContent.setLength(0); boolean close = ("close".equalsIgnoreCase(this.request .getHeader("Connection"))) || ((this.request.getProtocolVersion() .equals(HttpVersion.HTTP_1_0)) && (!"keep-alive" .equalsIgnoreCase(this.request.getHeader("Connection")))); HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); response.setContent(buf); response.setHeader("Content-Type", "text/plain; charset=UTF-8"); if (!close) { response.setHeader("Content-Length", String.valueOf(buf.readableBytes())); } ChannelFuture future = channel.write(response); if (close) future.addListener(ChannelFutureListener.CLOSE); }
/** Handle conditional connection close depending on keep-alive */ private void writeResponse(Channel channel, HttpRequest request, HttpResponse response) { response.setHeader(CONTENT_LENGTH, response.getContent().readableBytes()); boolean hasKeepAliveHeader = KEEP_ALIVE.equalsIgnoreCase(request.getHeader(CONNECTION)); if (!request.getProtocolVersion().isKeepAliveDefault() && hasKeepAliveHeader) { response.setHeader(CONNECTION, KEEP_ALIVE); } ChannelFuture wf = channel.write(response); if (!HttpHeaders.isKeepAlive(request)) { wf.addListener(ChannelFutureListener.CLOSE); } }
@Override public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception { final Channel channel = ctx.getChannel(); if (e instanceof ClosedChannelException || channel == null || !channel.isOpen()) { log.debug("Not writing any response, channel is already closed.", e.getCause()); return; } log.error("Uncaught exception during jersey resource handling", e.getCause()); final HttpRequest request = (HttpRequest) ctx.getAttachment(); final HttpVersion protocolVersion; if (request != null && request.getProtocolVersion() != null) { protocolVersion = request.getProtocolVersion(); } else { protocolVersion = HttpVersion.HTTP_1_0; } final DefaultHttpResponse response = new DefaultHttpResponse(protocolVersion, HttpResponseStatus.INTERNAL_SERVER_ERROR); final ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); new ChannelBufferOutputStream(buffer).writeBytes(e.toString()); response.setContent(buffer); final ChannelFuture channelFuture = channel.write(response); if ((protocolVersion == HttpVersion.HTTP_1_0) || request == null || HttpHeaders.getHeader(request, HttpHeaders.Names.CONNECTION).equalsIgnoreCase("close")) { channelFuture.addListener(ChannelFutureListener.CLOSE); } }
protected HttpResponse createResponse(String contentType) { final HttpVersion version = request.getProtocolVersion(); HttpResponse response = new DefaultHttpResponse(version, HttpResponseStatus.OK); response.setHeader(CONTENT_TYPE, contentType); response.setHeader(CACHE_CONTROL, "no-store, no-cache, must-revalidate, max-age=0"); response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Credentials", "true"); response.setHeader(SET_COOKIE, cookie); // FIXME: Check if cookies are enabled return response; }
@Override public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { HttpRequest request = (HttpRequest)e.getMessage(); if (logger.isDebugEnabled()) logger.debug("URI " + request.getUri()); for (Service service : services.values()) { // Check if there's a service registered with this URL if (request.getUri().startsWith(service.getUrl())) { handleService(ctx, e, service); super.messageReceived(ctx, e); return; } } // No match for service found, return 404 HttpResponse response = new DefaultHttpResponse(request.getProtocolVersion(), HttpResponseStatus.NOT_FOUND); response.setContent(ChannelBuffers.copiedBuffer("Not found", CharsetUtil.UTF_8)); writeResponse(e.getChannel(), request, response); }
private void handlePreflight(final ChannelHandlerContext ctx, final HttpRequest request) { final HttpResponse response = new DefaultHttpResponse(request.getProtocolVersion(), OK); if (setOrigin(response)) { setAllowMethods(response); setAllowHeaders(response); setAllowCredentials(response); setMaxAge(response); setPreflightHeaders(response); ctx.getChannel().write(response).addListener(ChannelFutureListener.CLOSE); } else { forbidden(ctx, request); } }
@Override public void messageReceived(final ChannelHandlerContext ctx, final MessageEvent e) throws Exception { final Channel channel = e.getChannel(); final HttpRequest request = (HttpRequest) e.getMessage(); final boolean keepAlive = isKeepAlive(request); final HttpVersion httpRequestVersion = request.getProtocolVersion(); final String origin = request.headers().get(Names.ORIGIN); // to allow for future changes, let's be at least a little strict in what we accept here. if (request.getMethod() != HttpMethod.POST) { writeResponse(channel, keepAlive, httpRequestVersion, METHOD_NOT_ALLOWED, origin); return; } final ChannelBuffer buffer = request.getContent(); if ("/gelf".equals(request.getUri())) { // send on to raw message handler writeResponse(channel, keepAlive, httpRequestVersion, ACCEPTED, origin); fireMessageReceived(ctx, buffer); } else { writeResponse(channel, keepAlive, httpRequestVersion, NOT_FOUND, origin); } }
@Override public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { if (e.getMessage() instanceof HttpRequest) { HttpRequest request = (HttpRequest)e.getMessage(); String originHeader = request.getHeader("Origin"); if (originHeader != null) origin = originHeader; corsHeaders = request.getHeader("Access-Control-Request-Headers"); if (request.getMethod().equals(HttpMethod.OPTIONS)) { HttpResponse response = new DefaultHttpResponse(request.getProtocolVersion(), HttpResponseStatus.NO_CONTENT); response.setHeader(HttpHeaders.Names.CONTENT_TYPE, "text/plain; charset=UTF-8"); response.setHeader(HttpHeaders.Names.CACHE_CONTROL, "max-age=31536000, public"); response.setHeader("Access-Control-Max-Age", "31536000"); // FIXME: Dirty, handle per transport? if (request.getUri().contains("/xhr")) { response.setHeader("Access-Control-Allow-Methods", "OPTIONS, POST"); } else { response.setHeader("Access-Control-Allow-Methods", "OPTIONS, GET"); } response.setHeader("Access-Control-Allow-Headers", "Content-Type"); response.setHeader("Access-Control-Allow-Credentials", "true"); response.setHeader(HttpHeaders.Names.EXPIRES, "FIXME"); // FIXME: Fix this response.setHeader(HttpHeaders.Names.SET_COOKIE, "JSESSIONID=dummy; path=/"); ctx.getChannel().write(response).addListener(ChannelFutureListener.CLOSE); return; } } super.messageReceived(ctx, e); }
@Override public void sendHeader(ActionResponse response) { // Decide whether to close the connection or not. boolean http10 = request.getProtocolVersion().equals(HttpVersion.HTTP_1_0); boolean close = HttpHeaders.Values.CLOSE.equalsIgnoreCase(request.getHeader(HttpHeaders.Names.CONNECTION)) || (http10 && !HttpHeaders.Values.KEEP_ALIVE.equalsIgnoreCase(request.getHeader(HttpHeaders.Names.CONNECTION))); // Build the response object. HttpResponseStatus status = HttpResponseStatus.OK; HttpResponse resp = null; if (http10) { resp = new DefaultHttpResponse(HttpVersion.HTTP_1_0, status); if (!close) { resp.addHeader(HttpHeaders.Names.CONNECTION, "Keep-Alive"); } } else { resp = new DefaultHttpResponse(HttpVersion.HTTP_1_1, status); } if (response.responseCookie() != null) { resp.addHeader(HttpHeaders.Names.COOKIE, response.responseCookie()); } if (response.responseSetCookie() != null) { resp.addHeader(HttpHeaders.Names.SET_COOKIE, response.responseSetCookie()); } resp.setHeader(HttpHeaders.Names.CONTENT_TYPE, response.contentType()); }
@Override public void messageReceived(final ChannelHandlerContext ctx, final MessageEvent e) throws Exception { final Channel channel = e.getChannel(); final HttpRequest request = (HttpRequest) e.getMessage(); final boolean keepAlive = isKeepAlive(request); final HttpVersion httpRequestVersion = request.getProtocolVersion(); final String origin = request.headers().get(Names.ORIGIN); // to allow for future changes, let's be at least a little strict in what we accept here. if (HttpMethod.OPTIONS.equals(request.getMethod())) { writeResponse(channel, keepAlive, httpRequestVersion, OK, origin); return; } else if (!HttpMethod.POST.equals(request.getMethod())) { writeResponse(channel, keepAlive, httpRequestVersion, METHOD_NOT_ALLOWED, origin); return; } final ChannelBuffer buffer = request.getContent(); final boolean correctPath = "/gelf".equals(request.getUri()); if (!correctPath) { writeResponse(channel, keepAlive, httpRequestVersion, NOT_FOUND, origin); } else { // send on to raw message handler writeResponse(channel, keepAlive, httpRequestVersion, ACCEPTED, origin); fireMessageReceived(ctx, buffer); } }