private void handleChunk( HttpContent chunk, // final Channel channel, // final NettyResponseFuture<?> future, // AsyncHandler<?> handler) throws IOException, Exception { boolean interrupt = false; boolean last = chunk instanceof LastHttpContent; // Netty 4: the last chunk is not empty if (last) { LastHttpContent lastChunk = (LastHttpContent) chunk; HttpHeaders trailingHeaders = lastChunk.trailingHeaders(); if (!trailingHeaders.isEmpty()) { interrupt = handler.onHeadersReceived(new HttpResponseHeaders(trailingHeaders, true)) != State.CONTINUE; } } ByteBuf buf = chunk.content(); if (!interrupt && !(handler instanceof StreamedAsyncHandler) && (buf.readableBytes() > 0 || last)) { HttpResponseBodyPart part = config.getResponseBodyPartFactory().newResponseBodyPart(buf, last); interrupt = updateBodyAndInterrupt(future, handler, part); } if (interrupt || last) finishUpdate(future, channel, !last); }
private static void testPerformOpeningHandshake0(boolean subProtocol) { EmbeddedChannel ch = new EmbeddedChannel( new HttpObjectAggregator(42), new HttpRequestDecoder(), new HttpResponseEncoder()); FullHttpRequest req = ReferenceCountUtil.releaseLater( new DefaultFullHttpRequest( HTTP_1_1, HttpMethod.GET, "/chat", Unpooled.copiedBuffer("^n:ds[4U", CharsetUtil.US_ASCII))); req.headers().set(HttpHeaderNames.HOST, "server.example.com"); req.headers().set(HttpHeaderNames.UPGRADE, HttpHeaderValues.WEBSOCKET); req.headers().set(HttpHeaderNames.CONNECTION, "Upgrade"); req.headers().set(HttpHeaderNames.ORIGIN, "http://example.com"); req.headers().set(HttpHeaderNames.SEC_WEBSOCKET_KEY1, "4 @1 46546xW%0l 1 5"); req.headers().set(HttpHeaderNames.SEC_WEBSOCKET_KEY2, "12998 5 Y3 1 .P00"); req.headers().set(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL, "chat, superchat"); if (subProtocol) { new WebSocketServerHandshaker00("ws://example.com/chat", "chat", Integer.MAX_VALUE) .handshake(ch, req); } else { new WebSocketServerHandshaker00("ws://example.com/chat", null, Integer.MAX_VALUE) .handshake(ch, req); } EmbeddedChannel ch2 = new EmbeddedChannel(new HttpResponseDecoder()); ch2.writeInbound(ch.readOutbound()); HttpResponse res = ch2.readInbound(); Assert.assertEquals( "ws://example.com/chat", res.headers().get(HttpHeaderNames.SEC_WEBSOCKET_LOCATION)); if (subProtocol) { Assert.assertEquals("chat", res.headers().get(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL)); } else { Assert.assertNull(res.headers().get(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL)); } LastHttpContent content = ch2.readInbound(); Assert.assertEquals("8jKS'y:G*Co,Wxa-", content.content().toString(CharsetUtil.US_ASCII)); content.release(); }
@Override protected Object safeObject(Object msg) throws Exception { if (msg instanceof HttpContent) { HttpContent content = (HttpContent) msg; ByteBuf buf = content.content(); if (buf != Unpooled.EMPTY_BUFFER && buf.isDirect()) { ByteBuf newBuf = safeBuffer(content); if (msg instanceof LastHttpContent) { LastHttpContent last = (LastHttpContent) msg; return new AssembledLastHttpContent(newBuf, last.trailingHeaders()); } else { return new DefaultHttpContent(newBuf); } } } else if (msg instanceof WebSocketFrame) { ByteBuf payload = safeBuffer((WebSocketFrame) msg); if (msg instanceof BinaryWebSocketFrame) { return new DefaultWebSocketFrame( org.vertx.java.core.http.impl.ws.WebSocketFrame.FrameType.BINARY, payload); } else if (msg instanceof CloseWebSocketFrame) { return new DefaultWebSocketFrame( org.vertx.java.core.http.impl.ws.WebSocketFrame.FrameType.CLOSE, payload); } else if (msg instanceof PingWebSocketFrame) { return new DefaultWebSocketFrame( org.vertx.java.core.http.impl.ws.WebSocketFrame.FrameType.PING, payload); } else if (msg instanceof PongWebSocketFrame) { return new DefaultWebSocketFrame( org.vertx.java.core.http.impl.ws.WebSocketFrame.FrameType.PONG, payload); } else if (msg instanceof TextWebSocketFrame) { return new DefaultWebSocketFrame( org.vertx.java.core.http.impl.ws.WebSocketFrame.FrameType.TEXT, payload); } else if (msg instanceof ContinuationWebSocketFrame) { return new DefaultWebSocketFrame( org.vertx.java.core.http.impl.ws.WebSocketFrame.FrameType.CONTINUATION, payload); } else { throw new IllegalStateException("Unsupported websocket msg " + msg); } } return msg; }
@Override public List<String> cookies() { synchronized (conn) { if (cookies == null) { cookies = new ArrayList<>(); cookies.addAll(response.headers().getAll(HttpHeaders.SET_COOKIE)); if (trailer != null) { cookies.addAll(trailer.trailingHeaders().getAll(HttpHeaders.SET_COOKIE)); } } return cookies; } }
@Override protected Object safeObject(Object msg, ByteBufAllocator allocator) throws Exception { if (msg instanceof HttpContent) { HttpContent content = (HttpContent) msg; ByteBuf buf = content.content(); if (buf != Unpooled.EMPTY_BUFFER && buf.isDirect()) { ByteBuf newBuf = safeBuffer(content, allocator); if (msg instanceof LastHttpContent) { LastHttpContent last = (LastHttpContent) msg; return new AssembledLastHttpContent( newBuf, last.trailingHeaders(), last.getDecoderResult()); } else { return new DefaultHttpContent(newBuf); } } } else if (msg instanceof WebSocketFrame) { ByteBuf payload = safeBuffer((WebSocketFrame) msg, allocator); boolean isFinal = ((WebSocketFrame) msg).isFinalFragment(); FrameType frameType; if (msg instanceof BinaryWebSocketFrame) { frameType = FrameType.BINARY; } else if (msg instanceof CloseWebSocketFrame) { frameType = FrameType.CLOSE; } else if (msg instanceof PingWebSocketFrame) { frameType = FrameType.PING; } else if (msg instanceof PongWebSocketFrame) { frameType = FrameType.PONG; } else if (msg instanceof TextWebSocketFrame) { frameType = FrameType.TEXT; } else if (msg instanceof ContinuationWebSocketFrame) { frameType = FrameType.CONTINUATION; } else { throw new IllegalStateException("Unsupported websocket msg " + msg); } return new WebSocketFrameImpl(frameType, payload, isFinal); } return msg; }
public void messageReceived(ChannelHandlerContext ctx, Object o) throws Exception { if (o instanceof HttpRequest) { // DefaultHttpRequest ) { queue.add((HttpRequest) o); } else if (o instanceof LastHttpContent) { HttpRequest req = queue.remove(); req.getMethod(); req.getUri(); req.headers(); LastHttpContent content = (LastHttpContent) o; ByteBuf buf = content.content(); if (buf.readableBytes() > 0) { Gson gson = GsonFactory.createBuilder().create(); Reader in = new InputStreamReader(new ByteBufInputStream(buf), "utf-8"); Object v = gson.fromJson(in, Class.forName("com.logbook.logbook.resources.logs.LogEntryDTO")); System.out.println("v = " + v); } System.out.println( req.getMethod() + " " + req.getUri() + " -- " + buf.readableBytes() + " bytes"); HttpResponse r = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); r.headers().add("Content-Length", "0"); ctx.write(r); } else { System.out.println("o = " + o + " : " + o.getClass()); } }
void handleEnd(LastHttpContent trailer) { synchronized (conn) { conn.reportBytesRead(bytesRead); bytesRead = 0; request.reportResponseEnd(this); if (paused) { hasPausedEnd = true; pausedTrailer = trailer; } else { this.trailer = trailer; trailers = new HeadersAdaptor(trailer.trailingHeaders()); if (endHandler != null) { try { endHandler.handle(null); } catch (Throwable t) { handleException(t); } } } } }
@Override public void handle(final Channel channel, final NettyResponseFuture<?> future, final Object e) throws Exception { future.touch(); // The connect timeout occurred. if (future.isCancelled() || future.isDone()) { channels.finishChannel(channel); return; } NettyRequest nettyRequest = future.getNettyRequest(); AsyncHandler<?> handler = future.getAsyncHandler(); ProxyServer proxyServer = future.getProxyServer(); try { if (e instanceof HttpResponse) { HttpResponse response = (HttpResponse) e; LOGGER.debug("\n\nRequest {}\n\nResponse {}\n", nettyRequest.getHttpRequest(), response); future.setPendingResponse(response); return; } if (e instanceof HttpContent) { HttpResponse response = future.getPendingResponse(); future.setPendingResponse(null); if (handler != null) { if (response != null && handleResponseAndExit( channel, future, handler, nettyRequest.getHttpRequest(), proxyServer, response)) { return; } HttpContent chunk = (HttpContent) e; boolean interrupt = false; boolean last = chunk instanceof LastHttpContent; if (last) { LastHttpContent lastChunk = (LastHttpContent) chunk; HttpHeaders trailingHeaders = lastChunk.trailingHeaders(); if (!trailingHeaders.isEmpty()) { interrupt = handler.onHeadersReceived( new ResponseHeaders( future.getURI(), future.getHttpHeaders(), trailingHeaders)) != STATE.CONTINUE; } } ByteBuf buf = chunk.content(); try { if (!interrupt && (buf.readableBytes() > 0 || last)) { interrupt = updateBodyAndInterrupt( future, handler, nettyConfig.getBodyPartFactory().newResponseBodyPart(buf, last)); } } finally { // FIXME we shouldn't need this, should we? But a leak was reported there without it?! buf.release(); } if (interrupt || last) { finishUpdate(future, channel, !last); } } } } catch (Exception t) { if (hasIOExceptionFilters && t instanceof IOException && requestSender.applyIoExceptionFiltersAndReplayRequest( future, IOException.class.cast(t), channel)) { return; } try { channels.abort(future, t); } finally { finishUpdate(future, channel, false); throw t; } } }
@Override protected void encode(ChannelHandlerContext ctx, HttpObject msg, List<Object> out) throws Exception { boolean valid = false; boolean last = false; if (msg instanceof HttpRequest) { HttpRequest httpRequest = (HttpRequest) msg; SpdySynStreamFrame spdySynStreamFrame = createSynStreamFrame(httpRequest); out.add(spdySynStreamFrame); last = spdySynStreamFrame.isLast(); valid = true; } if (msg instanceof HttpResponse) { HttpResponse httpResponse = (HttpResponse) msg; if (httpResponse.headers().contains(SpdyHttpHeaders.Names.ASSOCIATED_TO_STREAM_ID)) { SpdySynStreamFrame spdySynStreamFrame = createSynStreamFrame(httpResponse); last = spdySynStreamFrame.isLast(); out.add(spdySynStreamFrame); } else { SpdySynReplyFrame spdySynReplyFrame = createSynReplyFrame(httpResponse); last = spdySynReplyFrame.isLast(); out.add(spdySynReplyFrame); } valid = true; } if (msg instanceof HttpContent && !last) { HttpContent chunk = (HttpContent) msg; chunk.content().retain(); SpdyDataFrame spdyDataFrame = new DefaultSpdyDataFrame(currentStreamId, chunk.content()); spdyDataFrame.setLast(chunk instanceof LastHttpContent); if (chunk instanceof LastHttpContent) { LastHttpContent trailer = (LastHttpContent) chunk; HttpHeaders trailers = trailer.trailingHeaders(); if (trailers.isEmpty()) { out.add(spdyDataFrame); } else { // Create SPDY HEADERS frame out of trailers SpdyHeadersFrame spdyHeadersFrame = new DefaultSpdyHeadersFrame(currentStreamId); for (Map.Entry<String, String> entry : trailers) { spdyHeadersFrame.headers().add(entry.getKey(), entry.getValue()); } // Write HEADERS frame and append Data Frame out.add(spdyHeadersFrame); out.add(spdyDataFrame); } } else { out.add(spdyDataFrame); } valid = true; } if (!valid) { throw new UnsupportedMessageTypeException(msg); } }