@Override protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg) throws Exception { ByteBuf buf = msg.content(); byte[] bytes = new byte[buf.readableBytes()]; buf.getBytes(0, bytes); YarRequest yarRequest = YarProtocol.buildRequest(bytes); YarResponse yarResponse = process(yarRequest); FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.wrappedBuffer(YarProtocol .toProtocolBytes(yarResponse))); response.headers().set(HttpHeaders.Names.CONTENT_TYPE, "application/x-www-form-urlencoded"); response.headers().set(HttpHeaders.Names.CONTENT_LENGTH, response.content().readableBytes()); if (HttpHeaders.isKeepAlive(msg)) { response.headers().set(HttpHeaders.Names.CONNECTION, Values.KEEP_ALIVE); } ctx.write(response); ctx.flush(); ctx.close(); }
@Override public void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception { if (msg instanceof HttpRequest) { HttpRequest req = (HttpRequest) msg; if (is100ContinueExpected(req)) { ctx.write(new DefaultFullHttpResponse(HTTP_1_1, CONTINUE)); } boolean keepAlive = isKeepAlive(req); ByteBuf content = RESPONSE_BYTES.duplicate(); FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, content); response.headers().set(CONTENT_TYPE, "text/html; charset=UTF-8"); response.headers().set(CONTENT_LENGTH, response.content().readableBytes()); if (!keepAlive) { ctx.write(response).addListener(ChannelFutureListener.CLOSE); } else { response.headers().set(CONNECTION, Values.KEEP_ALIVE); ctx.write(response); } } }
@Override public void handle(ChannelHandlerContext ctx, HttpRequest httpRequest, Map<String, List<String>> params, ByteBuf byteBuf) throws Exception { FullHttpResponse response = handle(httpRequest, params, byteBuf); if (HttpHeaders.isKeepAlive(httpRequest)) { response.headers().set(HttpHeaders.Names.CONNECTION, Values.KEEP_ALIVE); } if (response.getStatus()!= HttpResponseStatus.OK && response.getStatus()!=HttpResponseStatus.NO_CONTENT ) System.out.println(httpRequest.getUri()+" "+response.getStatus()); ChannelFuture future = ctx.writeAndFlush(response); if (!HttpHeaders.isKeepAlive(httpRequest)) { future.sync(); ctx.close(); } }
/** * <p> * Process server response: * </p> * * <pre> * HTTP/1.1 101 Switching Protocols * Upgrade: websocket * Connection: Upgrade * Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= * Sec-WebSocket-Protocol: chat * </pre> * * @param response * HTTP response returned from the server for the request sent by beginOpeningHandshake00(). * @throws WebSocketHandshakeException */ @Override protected void verify(FullHttpResponse response) { final HttpResponseStatus status = HttpResponseStatus.SWITCHING_PROTOCOLS; final HttpHeaders headers = response.headers(); if (!response.getStatus().equals(status)) { throw new WebSocketHandshakeException("Invalid handshake response getStatus: " + response.getStatus()); } String upgrade = headers.get(Names.UPGRADE); if (!Values.WEBSOCKET.equalsIgnoreCase(upgrade)) { throw new WebSocketHandshakeException("Invalid handshake response upgrade: " + upgrade); } String connection = headers.get(Names.CONNECTION); if (!Values.UPGRADE.equalsIgnoreCase(connection)) { throw new WebSocketHandshakeException("Invalid handshake response connection: " + connection); } String accept = headers.get(Names.SEC_WEBSOCKET_ACCEPT); if (accept == null || !accept.equals(expectedChallengeResponseString)) { throw new WebSocketHandshakeException(String.format( "Invalid challenge. Actual: %s. Expected: %s", accept, expectedChallengeResponseString)); } }
@Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { if (msg instanceof HttpRequest) { HttpRequest req = (HttpRequest) msg; if (is100ContinueExpected(req)) { ctx.write(new DefaultFullHttpResponse(HTTP_1_1, CONTINUE)); } boolean keepAlive = isKeepAlive(req); FullHttpResponse res = new DefaultFullHttpResponse(HTTP_1_1, OK, Unpooled.wrappedBuffer(CONTENT.getBytes())); res.headers().set(CONTENT_TYPE, "application/json"); res.headers().set(CONTENT_LENGTH, res.content().readableBytes()); if (!keepAlive) { ctx.write(res).addListener(ChannelFutureListener.CLOSE); } else { res.headers().set(CONNECTION, Values.KEEP_ALIVE); ctx.write(res); } } }
@Override public void channelRead( ChannelHandlerContext ctx, Object msg ) throws Exception { if ( msg instanceof HttpRequest ) { log.info( "Here in the ExampleServerHandler" ); HttpRequest req = (HttpRequest) msg; boolean keepAlive = isKeepAlive( req ); FullHttpResponse res = new DefaultFullHttpResponse( HTTP_1_1, OK, Unpooled.wrappedBuffer( CONTENT.getBytes() ) ); res.headers().set( CONTENT_TYPE, "application/json" ); res.headers().set( CONTENT_LENGTH, res.content().readableBytes() ); if ( !keepAlive ) { ctx.write( res ).addListener( ChannelFutureListener.CLOSE ); } else { res.headers().set( CONNECTION, Values.KEEP_ALIVE ); ctx.write( res ); } } }
protected void doPost(ChannelHandlerContext ctx, HttpRequest httpReq) { FullHttpRequest req = (FullHttpRequest) httpReq ; ByteBuf byteBuf = req.content() ; byte[] bytes = new byte[byteBuf.readableBytes()] ; byteBuf.readBytes(bytes) ; String reply = REPLY_MESSAGE + " - " + new String(bytes) ; ByteBuf contentBuf = Unpooled.wrappedBuffer(reply.getBytes()) ; FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, contentBuf); response.headers().set(CONTENT_TYPE, "text/plain"); response.headers().set(CONTENT_LENGTH, response.content().readableBytes()); boolean keepAlive = isKeepAlive(httpReq); if (!keepAlive) { ctx.write(response).addListener(ChannelFutureListener.CLOSE); } else { response.headers().set(CONNECTION, Values.KEEP_ALIVE); ctx.write(response); } ctx.flush() ; }
/** * <p> * Process server response: * </p> * * <pre> * HTTP/1.1 101 Switching Protocols * Upgrade: websocket * Connection: Upgrade * Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= * Sec-WebSocket-Protocol: chat * </pre> * * @param response * HTTP response returned from the server for the request sent by beginOpeningHandshake00(). * @throws WebSocketHandshakeException */ @Override protected void verify(FullHttpResponse response) { final HttpResponseStatus status = HttpResponseStatus.SWITCHING_PROTOCOLS; final HttpHeaders headers = response.headers(); if (!response.getStatus().equals(status)) { throw new WebSocketHandshakeException("Invalid handshake response getStatus: " + response.getStatus()); } String upgrade = headers.get(Names.UPGRADE); if (!HttpHeaders.equalsIgnoreCase(Values.WEBSOCKET, upgrade)) { throw new WebSocketHandshakeException("Invalid handshake response upgrade: " + upgrade); } String connection = headers.get(Names.CONNECTION); if (!HttpHeaders.equalsIgnoreCase(Values.UPGRADE, connection)) { throw new WebSocketHandshakeException("Invalid handshake response connection: " + connection); } String accept = headers.get(Names.SEC_WEBSOCKET_ACCEPT); if (accept == null || !accept.equals(expectedChallengeResponseString)) { throw new WebSocketHandshakeException(String.format( "Invalid challenge. Actual: %s. Expected: %s", accept, expectedChallengeResponseString)); } }
@Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { if (msg instanceof HttpRequest) { request = (HttpRequest) msg; String uri = request.getUri(); System.out.println("Uri:" + uri); } if (msg instanceof HttpContent) { HttpContent content = (HttpContent) msg; ByteBuf buf = content.content(); System.out.println(buf.toString(io.netty.util.CharsetUtil.UTF_8)); buf.release(); String res = "I am OK"; FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, Unpooled.wrappedBuffer(res.getBytes("UTF-8"))); response.headers().set(CONTENT_TYPE, "text/plain"); response.headers().set(CONTENT_LENGTH, response.content().readableBytes()); if (HttpHeaders.isKeepAlive(request)) { response.headers().set(CONNECTION, Values.KEEP_ALIVE); } ctx.write(response); ctx.flush(); } }
@Override protected void decode(ChannelHandlerContext ctx, HttpRequest msg, List<Object> out) throws Exception { String acceptedEncoding = msg.headers().get(HttpHeaders.Names.ACCEPT_ENCODING); if (acceptedEncoding == null) { acceptedEncoding = HttpHeaders.Values.IDENTITY; } acceptEncodingQueue.add(acceptedEncoding); out.add(ReferenceCountUtil.retain(msg)); }
/** * <p> * Process server response: * </p> * * <pre> * HTTP/1.1 101 WebSocket Protocol Handshake * Upgrade: WebSocket * Connection: Upgrade * Sec-WebSocket-Origin: http://example.com * Sec-WebSocket-Location: ws://example.com/demo * Sec-WebSocket-Protocol: sample * * 8jKS'y:G*Co,Wxa- * </pre> * * @param response * HTTP response returned from the server for the request sent by beginOpeningHandshake00(). * @throws WebSocketHandshakeException */ @Override protected void verify(FullHttpResponse response) { final HttpResponseStatus status = new HttpResponseStatus(101, "WebSocket Protocol Handshake"); if (!response.getStatus().equals(status)) { throw new WebSocketHandshakeException("Invalid handshake response getStatus: " + response.getStatus()); } HttpHeaders headers = response.headers(); String upgrade = headers.get(Names.UPGRADE); if (!Values.WEBSOCKET.equalsIgnoreCase(upgrade)) { throw new WebSocketHandshakeException("Invalid handshake response upgrade: " + upgrade); } String connection = headers.get(Names.CONNECTION); if (!Values.UPGRADE.equalsIgnoreCase(connection)) { throw new WebSocketHandshakeException("Invalid handshake response connection: " + connection); } ByteBuf challenge = response.content(); if (!challenge.equals(expectedChallengeResponseBytes)) { throw new WebSocketHandshakeException("Invalid challenge"); } }
@Test public void testChunkedContent() throws Exception { EmbeddedChannel ch = new EmbeddedChannel(new TestEncoder()); ch.writeInbound(new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/")); HttpResponse res = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); res.headers().set(Names.TRANSFER_ENCODING, Values.CHUNKED); ch.writeOutbound(res); assertEncodedResponse(ch); ch.writeOutbound(new DefaultHttpContent(Unpooled.wrappedBuffer(new byte[3]))); ch.writeOutbound(new DefaultHttpContent(Unpooled.wrappedBuffer(new byte[2]))); ch.writeOutbound(new DefaultLastHttpContent(Unpooled.wrappedBuffer(new byte[1]))); HttpContent chunk; chunk = (HttpContent) ch.readOutbound(); assertThat(chunk.content().toString(CharsetUtil.US_ASCII), is("3")); chunk.release(); chunk = (HttpContent) ch.readOutbound(); assertThat(chunk.content().toString(CharsetUtil.US_ASCII), is("2")); chunk.release(); chunk = (HttpContent) ch.readOutbound(); assertThat(chunk.content().toString(CharsetUtil.US_ASCII), is("1")); assertThat(chunk, is(instanceOf(HttpContent.class))); chunk.release(); chunk = (HttpContent) ch.readOutbound(); assertThat(chunk.content().isReadable(), is(false)); assertThat(chunk, is(instanceOf(LastHttpContent.class))); chunk.release(); assertThat(ch.readOutbound(), is(nullValue())); }
@Test public void testChunkedContentWithTrailingHeader() throws Exception { EmbeddedChannel ch = new EmbeddedChannel(new TestEncoder()); ch.writeInbound(new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/")); HttpResponse res = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); res.headers().set(Names.TRANSFER_ENCODING, Values.CHUNKED); ch.writeOutbound(res); assertEncodedResponse(ch); ch.writeOutbound(new DefaultHttpContent(Unpooled.wrappedBuffer(new byte[3]))); ch.writeOutbound(new DefaultHttpContent(Unpooled.wrappedBuffer(new byte[2]))); LastHttpContent content = new DefaultLastHttpContent(Unpooled.wrappedBuffer(new byte[1])); content.trailingHeaders().set("X-Test", "Netty"); ch.writeOutbound(content); HttpContent chunk; chunk = (HttpContent) ch.readOutbound(); assertThat(chunk.content().toString(CharsetUtil.US_ASCII), is("3")); chunk.release(); chunk = (HttpContent) ch.readOutbound(); assertThat(chunk.content().toString(CharsetUtil.US_ASCII), is("2")); chunk.release(); chunk = (HttpContent) ch.readOutbound(); assertThat(chunk.content().toString(CharsetUtil.US_ASCII), is("1")); assertThat(chunk, is(instanceOf(HttpContent.class))); chunk.release(); chunk = (HttpContent) ch.readOutbound(); assertThat(chunk.content().isReadable(), is(false)); assertThat(chunk, is(instanceOf(LastHttpContent.class))); assertEquals("Netty", ((LastHttpContent) chunk).trailingHeaders().get("X-Test")); chunk.release(); assertThat(ch.readOutbound(), is(nullValue())); }
@Test public void testChunkedContent() throws Exception { EmbeddedChannel ch = new EmbeddedChannel(new HttpContentCompressor()); ch.writeInbound(newRequest()); HttpResponse res = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); res.headers().set(Names.TRANSFER_ENCODING, Values.CHUNKED); ch.writeOutbound(res); assertEncodedResponse(ch); ch.writeOutbound(new DefaultHttpContent(Unpooled.copiedBuffer("Hell", CharsetUtil.US_ASCII))); ch.writeOutbound(new DefaultHttpContent(Unpooled.copiedBuffer("o, w", CharsetUtil.US_ASCII))); ch.writeOutbound(new DefaultLastHttpContent(Unpooled.copiedBuffer("orld", CharsetUtil.US_ASCII))); HttpContent chunk; chunk = (HttpContent) ch.readOutbound(); assertThat(ByteBufUtil.hexDump(chunk.content()), is("1f8b0800000000000000f248cdc901000000ffff")); chunk.release(); chunk = (HttpContent) ch.readOutbound(); assertThat(ByteBufUtil.hexDump(chunk.content()), is("cad7512807000000ffff")); chunk.release(); chunk = (HttpContent) ch.readOutbound(); assertThat(ByteBufUtil.hexDump(chunk.content()), is("ca2fca4901000000ffff")); chunk.release(); chunk = (HttpContent) ch.readOutbound(); assertThat(ByteBufUtil.hexDump(chunk.content()), is("0300c2a99ae70c000000")); assertThat(chunk, is(instanceOf(HttpContent.class))); chunk.release(); chunk = (HttpContent) ch.readOutbound(); assertThat(chunk.content().isReadable(), is(false)); assertThat(chunk, is(instanceOf(LastHttpContent.class))); chunk.release(); assertThat(ch.readOutbound(), is(nullValue())); }
/** * 将Response写入到客户端 * 如果为长连接就在Response head里设置Connection值为keep-alive * 否则就关闭连接 * * @param ctx * ChannelHandlerContext */ private void writeResponse(ChannelHandlerContext ctx) { FullHttpResponse fullHttpResponse = response.toFullHttpResponse(); if (keepalive && request != null && request.isKeepAlive()) { fullHttpResponse.headers().set(Names.CONNECTION, Values.KEEP_ALIVE); ctx.writeAndFlush(fullHttpResponse); logger.info("ChannelFuture {} is keep-alive , not close......", this); } else { ctx.writeAndFlush(fullHttpResponse).addListener(ChannelFutureListener.CLOSE); logger.info("ChannelFuture {} is closed......", this); } }
/** * @return 是否为长连接 */ public boolean isKeepAlive() { final String connection = getHeader(Names.CONNECTION.toString()); // 无论任何版本Connection为close时都关闭连接 if (Values.CLOSE.toString().equalsIgnoreCase(connection)) { return false; } // HTTP/1.0只有Connection为Keep-Alive时才会保持连接 if (HttpVersion.HTTP_1_0.text().equals(getHttpVersion()) && (!Values.KEEP_ALIVE.toString().equalsIgnoreCase(connection))) { return false; } // HTTP/1.1默认打开Keep-Alive return true; }
@Override public void respondRaw(FuseRequestMessage message, HttpResponseStatus status, ByteBuffer data, Map<String, String> headers) { if (!message.flushed()) { boolean keepAlive = isKeepAlive(message.getRequest()); FullHttpResponse response = new DefaultFullHttpResponse( HTTP_1_1, status, Unpooled.wrappedBuffer(data) ); response.headers().set(CONTENT_LENGTH , response.content().readableBytes()); for (Map.Entry<String, String> entry : headers.entrySet()) { response.headers().set(entry.getKey(), entry.getValue()); } if (!keepAlive) { message.getChannelContext() .write(response) .addListener(ChannelFutureListener.CLOSE); } else { response.headers() .set( CONNECTION, Values.KEEP_ALIVE ); message.getChannelContext() .channel() .write(response); } message.flush(); } }
protected void doGet(ChannelHandlerContext ctx, HttpRequest httpReq) { ByteBuf contentBuf = Unpooled.wrappedBuffer(REPLY_MESSAGE.getBytes()) ; FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, contentBuf); response.headers().set(CONTENT_TYPE, "text/plain"); response.headers().set(CONTENT_LENGTH, response.content().readableBytes()); boolean keepAlive = isKeepAlive(httpReq); if (!keepAlive) { ctx.write(response).addListener(ChannelFutureListener.CLOSE); } else { response.headers().set(CONNECTION, Values.KEEP_ALIVE); ctx.write(response); } ctx.flush() ; }
protected FullHttpResponse createResponse(HttpRequest req, ByteBuf content, String mimeType) { FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, OK, content); response.headers().set(CONTENT_TYPE, mimeType); response.headers().set(CONTENT_LENGTH, response.content().readableBytes()); response.headers().set(HttpHeaders.Names.ACCEPT_ENCODING, HttpHeaders.Values.GZIP); return response ; }
protected void write(ChannelHandlerContext ctx, HttpRequest request, FullHttpResponse response) { boolean keepAlive = isKeepAlive(request); if (!keepAlive) { ctx.write(response).addListener(ChannelFutureListener.CLOSE); } else { response.headers().set(CONNECTION, Values.KEEP_ALIVE); ctx.write(response) ; } ctx.flush() ; }
@Override public OutputStream writeResponseStatusAndHeaders(long contentLength, ContainerResponse jerseyResponse) throws ContainerException { int status = jerseyResponse.getStatus(); LOGGER.debug("{}: [{}] write status and headers st:{} cl:{}", Channels.getHexText(ctx), requestId, status, contentLength); meterStatus(status); // create the netty response HttpResponse nettyResponse = new DefaultHttpResponse(httpVersion, HttpResponseStatus.valueOf(status)); copyHeaders(jerseyResponse, nettyResponse); // add the request id to the header nettyResponse.headers().add(Headers.REQUEST_TRACING_HEADER, requestId); // add a Connection: Close header if required if (!keepAlive) { nettyResponse.headers().add(Names.CONNECTION, Values.CLOSE); } // create the content buffer if necessary if (contentLength < 0) { LOGGER.trace("{}: [{}] chunked", Channels.getHexText(ctx), requestId); nettyResponse.headers().add(Names.TRANSFER_ENCODING, Values.CHUNKED); ctx.writeAndFlush(nettyResponse); entityOutputStream = new EntityOutputStream(ctx, CONTENT_LENGTH_HISTOGRAM); } else if (contentLength == 0) { LOGGER.trace("{}: [{}] no content", Channels.getHexText(ctx), requestId); nettyResponse.headers().add(Names.CONTENT_LENGTH, 0); ctx.write(nettyResponse); entityOutputStream = new EmptyEntityOutputStream(ctx); } else { LOGGER.trace("{}: [{}] non-empty body", Channels.getHexText(ctx), requestId); nettyResponse.headers().add(Names.CONTENT_LENGTH, contentLength); ctx.write(nettyResponse); // don't flush now - only do so when all the content is written entityOutputStream = new EntityOutputStream(ctx, CONTENT_LENGTH_HISTOGRAM); } return entityOutputStream; }
@Override protected void decode(ChannelHandlerContext ctx, HttpRequest msg, List<Object> out) throws Exception { CharSequence acceptedEncoding = msg.headers().get(HttpHeaders.Names.ACCEPT_ENCODING); if (acceptedEncoding == null) { acceptedEncoding = HttpHeaders.Values.IDENTITY; } acceptEncodingQueue.add(acceptedEncoding); out.add(ReferenceCountUtil.retain(msg)); }
/** * <p> * Process server response: * </p> * * <pre> * HTTP/1.1 101 WebSocket Protocol Handshake * Upgrade: WebSocket * Connection: Upgrade * Sec-WebSocket-Origin: http://example.com * Sec-WebSocket-Location: ws://example.com/demo * Sec-WebSocket-Protocol: sample * * 8jKS'y:G*Co,Wxa- * </pre> * * @param response * HTTP response returned from the server for the request sent by beginOpeningHandshake00(). * @throws WebSocketHandshakeException */ @Override protected void verify(FullHttpResponse response) { final HttpResponseStatus status = new HttpResponseStatus(101, "WebSocket Protocol Handshake"); if (!response.getStatus().equals(status)) { throw new WebSocketHandshakeException("Invalid handshake response getStatus: " + response.getStatus()); } HttpHeaders headers = response.headers(); String upgrade = headers.get(Names.UPGRADE); if (!HttpHeaders.equalsIgnoreCase(Values.WEBSOCKET, upgrade)) { throw new WebSocketHandshakeException("Invalid handshake response upgrade: " + upgrade); } String connection = headers.get(Names.CONNECTION); if (!HttpHeaders.equalsIgnoreCase(Values.UPGRADE, connection)) { throw new WebSocketHandshakeException("Invalid handshake response connection: " + connection); } ByteBuf challenge = response.content(); if (!challenge.equals(expectedChallengeResponseBytes)) { throw new WebSocketHandshakeException("Invalid challenge"); } }
public void writeStart(Channel ch, int contentLength) { // Build the response object. HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, this.status); response.headers().set(Names.CONTENT_TYPE, "text/plain; charset=UTF-8"); if (this.keepAlive) { // Add 'Content-Length' header only for a keep-alive connection. if (contentLength > 0) response.headers().set(Names.CONTENT_LENGTH, contentLength); // Add keep alive header as per: // - http://www.w3.org/Protocols/HTTP/1.1/draft-ietf-http-v11-spec-01.html#Connection response.headers().set(Names.CONNECTION, HttpHeaders.Values.KEEP_ALIVE); } if (contentLength == 0) response.headers().set(Names.TRANSFER_ENCODING, HttpHeaders.Values.CHUNKED); // Encode the cookies for (Cookie c : this.cookies.values()) response.headers().add(Names.SET_COOKIE, ServerCookieEncoder.STRICT.encode(c)); for (Entry<CharSequence, String> h : this.headers.entrySet()) response.headers().set(h.getKey(), h.getValue()); Hub.instance.getSecurityPolicy().hardenHttpResponse(response); if (Logger.isDebug()) { Logger.debug("Web server responding to " + ch.remoteAddress()); for (Entry<String, String> ent : response.headers().entries()) { Logger.debug("Response header: " + ent.getKey() + ": " + ent.getValue()); } } // Write the response. ch.write(response); }
public void writeChunked(Channel ch) { // Build the response object. HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, this.status); response.headers().set(Names.CONTENT_TYPE, "text/plain; charset=UTF-8"); if (this.keepAlive) { // Add keep alive header as per: // - http://www.w3.org/Protocols/HTTP/1.1/draft-ietf-http-v11-spec-01.html#Connection response.headers().set(Names.CONNECTION, HttpHeaders.Values.KEEP_ALIVE); } // TODO add a customer header telling how many messages are in the session adaptor's queue - if > 0 // Encode the cookies for (Cookie c : this.cookies.values()) response.headers().add(Names.SET_COOKIE, ServerCookieEncoder.STRICT.encode(c)); for (Entry<CharSequence, String> h : this.headers.entrySet()) response.headers().set(h.getKey(), h.getValue()); response.headers().set(Names.TRANSFER_ENCODING, Values.CHUNKED); // Write the response. ChannelFuture future = ch.writeAndFlush(response); // Close the non-keep-alive connection after the write operation is done. if (!this.keepAlive) future.addListener(ChannelFutureListener.CLOSE); /* we do not need to sync - HTTP is one request, one response. we would not pile messages on this channel try { future.sync(); } catch (InterruptedException x) { // TODO should we close channel? } */ }
private HttpResponse evalProceedStatus(FullHttpRequest request, EventMetadata metadata) { HttpResponseStatus httpStatus = null; switch (metadata.getExecutionStatus()) { case EXECUTING: case EXECUTED: if (Context.requestScope().isPlaying()) { httpStatus = HttpResponseStatus.OK; break; } else { return null; } case DENIED: httpStatus = HttpResponseStatus.FORBIDDEN; break; case FIRST_POSTPONED: case POSTPONED: case SCHEDULED: httpStatus = HttpResponseStatus.ACCEPTED; break; case ERROR: httpStatus = (HttpResponseStatus) Context.requestScope().getProperty(InternalRequestScope.HTTPRESPONSESTATUS); if (httpStatus == null) { httpStatus = HttpResponseStatus.BAD_REQUEST; } break; default: String err = "Execution status " + metadata.getExecutionStatus() + " should not be possible in CibetProxy.requestPre"; log.error(err); throw new RuntimeException(err); } log.info(metadata.getResource().getTarget() + ": --> " + httpStatus); HttpResponse response = new DefaultHttpResponse(request.getProtocolVersion(), httpStatus); response.headers().set(Names.CONNECTION, Values.CLOSE); return response; }
/** * /** * <p> * Sends the opening request to the server: * </p> * * <pre> * GET /chat HTTP/1.1 * Host: server.example.com * Upgrade: websocket * Connection: Upgrade * Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== * Sec-WebSocket-Origin: http://example.com * Sec-WebSocket-Protocol: chat, superchat * Sec-WebSocket-Version: 7 * </pre> * */ @Override protected FullHttpRequest newHandshakeRequest() { // Get path URI wsURL = uri(); String path = wsURL.getPath(); if (wsURL.getQuery() != null && !wsURL.getQuery().isEmpty()) { path = wsURL.getPath() + '?' + wsURL.getQuery(); } if (path == null || path.isEmpty()) { path = "/"; } // Get 16 bit nonce and base 64 encode it byte[] nonce = WebSocketUtil.randomBytes(16); String key = WebSocketUtil.base64(nonce); String acceptSeed = key + MAGIC_GUID; byte[] sha1 = WebSocketUtil.sha1(acceptSeed.getBytes(CharsetUtil.US_ASCII)); expectedChallengeResponseString = WebSocketUtil.base64(sha1); if (logger.isDebugEnabled()) { logger.debug( "WebSocket version 07 client handshake key: {}, expected response: {}", key, expectedChallengeResponseString); } // Format request FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, path); HttpHeaders headers = request.headers(); headers.add(Names.UPGRADE, Values.WEBSOCKET.toLowerCase()) .add(Names.CONNECTION, Values.UPGRADE) .add(Names.SEC_WEBSOCKET_KEY, key) .add(Names.HOST, wsURL.getHost()); int wsPort = wsURL.getPort(); String originValue = "http://" + wsURL.getHost(); if (wsPort != 80 && wsPort != 443) { // if the port is not standard (80/443) its needed to add the port to the header. // See http://tools.ietf.org/html/rfc6454#section-6.2 originValue = originValue + ':' + wsPort; } headers.add(Names.SEC_WEBSOCKET_ORIGIN, originValue); String expectedSubprotocol = expectedSubprotocol(); if (expectedSubprotocol != null && !expectedSubprotocol.isEmpty()) { headers.add(Names.SEC_WEBSOCKET_PROTOCOL, expectedSubprotocol); } headers.add(Names.SEC_WEBSOCKET_VERSION, "7"); if (customHeaders != null) { headers.add(customHeaders); } return request; }