private static Http1MessageSession setDefaultMessageSession(ChannelHandlerContext ctx) { Http1MessageSession session = ctx.channel().attr(CHANNEL_MESSAGE_SESSION_KEY).get(); if (session == null) { session = new Http1MessageSession(); ctx.channel().attr(CHANNEL_MESSAGE_SESSION_KEY).set(session); } return session; }
/** Wrap the HttpObject with the appropriate type and fire read on the next handler. */ private void wrapRequest(ChannelHandlerContext ctx, HttpObject msg) { Http1MessageSession session = setDefaultMessageSession(ctx); try { Request request; if (msg instanceof FullHttpRequest) { request = new FullHttp1Request((FullHttpRequest) msg); session.onRequest(request); } else if (msg instanceof HttpRequest) { request = new SegmentedHttp1Request((HttpRequest) msg); session.onRequest(request); } else if (msg instanceof HttpContent) { SegmentedData data = new Http1SegmentedData((HttpContent) msg); session.onRequestData(data); Request sessionRequest = session.currentRequest(); if (sessionRequest == null) { // We don't have a sessionRequest so we can't construct a SegmentedRequestData. // Don't log as session.onRequestData should have logged. return; } request = new SegmentedRequestData(sessionRequest, data); } else { log.error("Dropping unsupported http object: {}", msg); return; } ctx.fireChannelRead(request); } finally { session.flush(); } }
public Http1MessageSession() { reset(); }
@Test public void testFlush() { Request request = DefaultFullRequest.builder() .body(Unpooled.EMPTY_BUFFER) .headers(new DefaultHeaders()) .method(GET) .path("/") .build(); session.onRequest(request); assertTrue(session.initialRequest().requestFinished); assertFalse(session.initialRequest().responseFinished); session.flush(); assertNotNull(session.currentRequest()); Response response = DefaultFullResponse.builder() .body(Unpooled.EMPTY_BUFFER) .status(OK) .headers(new DefaultHeaders()) .build(); session.onResponse(response); assertTrue(session.initialRequest().requestFinished); assertTrue(session.initialRequest().responseFinished); session.flush(); assertNull(session.currentRequest()); } }
Http1MessageSession session = setDefaultMessageSession(ctx); try { session.onResponse(response); Request request = session.currentRequest(); boolean closeConnection = session.closeConnection() && (response instanceof FullResponse); if (session.closeConnection()) { response.headers().set(HttpHeaderNames.CONNECTION, "close"); session.flush();
@Test public void testOnRequestData() { Request request = DefaultSegmentedRequest.builder() .headers(new DefaultHeaders()) .method(GET) .path("/") .build(); session.onRequest(request); assertFalse(session.initialRequest().requestFinished); assertFalse(session.initialRequest().responseFinished); assertFalse(session.closeConnection()); SegmentedData data = DefaultSegmentedData.builder() .content(Unpooled.EMPTY_BUFFER) .endOfMessage(true) .trailingHeaders(new DefaultHeaders()) .build(); session.onRequestData(data); assertTrue(session.initialRequest().requestFinished); }
@Test public void testOnResponseData() { Request request = DefaultFullRequest.builder() .body(Unpooled.EMPTY_BUFFER) .headers(new DefaultHeaders()) .method(GET) .path("/") .build(); session.onRequest(request); assertTrue(session.initialRequest().requestFinished); assertFalse(session.initialRequest().responseFinished); Response response = DefaultSegmentedResponse.builder().status(OK).headers(new DefaultHeaders()).build(); session.onResponse(response); assertTrue(session.initialRequest().requestFinished); assertFalse(session.initialRequest().responseFinished); SegmentedData data = DefaultSegmentedData.builder() .content(Unpooled.EMPTY_BUFFER) .endOfMessage(true) .trailingHeaders(new DefaultHeaders()) .build(); session.onResponseData(data); assertTrue(session.initialRequest().requestFinished); assertTrue(session.initialRequest().responseFinished); }
/** * Translate the SegmentedData object into a netty HttpContent and fire write on the next handler. */ private void buildContent(ChannelHandlerContext ctx, SegmentedData data, ChannelPromise promise) { Http1MessageSession session = setDefaultMessageSession(ctx); try { session.onResponseData(data); HttpObject obj; if (data.endOfMessage()) { LastHttpContent last = new DefaultLastHttpContent(data.content()); if (data.trailingHeaders() != null) { last.trailingHeaders().add(data.trailingHeaders().http1Headers(true, false)); } obj = last; } else { obj = new DefaultHttpContent(data.content()); } ChannelFuture future = ctx.write(obj, promise); if (session.closeConnection() && data.endOfMessage()) { future.addListener(ChannelFutureListener.CLOSE); } } finally { session.flush(); } }
@Test public void testOnResponseStreaming() { Request request = DefaultFullRequest.builder() .body(Unpooled.EMPTY_BUFFER) .headers(new DefaultHeaders()) .method(GET) .path("/") .build(); session.onRequest(request); assertTrue(session.initialRequest().requestFinished); assertFalse(session.initialRequest().responseFinished); Response response = DefaultSegmentedResponse.builder().status(OK).headers(new DefaultHeaders()).build(); session.onResponse(response); assertTrue(session.initialRequest().requestFinished); assertFalse(session.initialRequest().responseFinished); }
@Test public void testOnRequestPipeline() { Request request = DefaultFullRequest.builder() .body(Unpooled.EMPTY_BUFFER) .headers(new DefaultHeaders()) .method(GET) .path("/") .build(); session.onRequest(request); assertTrue(session.initialRequest().requestFinished); assertFalse(session.initialRequest().responseFinished); assertFalse(session.closeConnection()); session.onRequest(request); assertTrue(session.closeConnection()); }
@Test public void testOnRequestStreaming() { Request request = DefaultSegmentedRequest.builder() .headers(new DefaultHeaders()) .method(GET) .path("/") .build(); session.onRequest(request); assertFalse(session.initialRequest().requestFinished); assertFalse(session.initialRequest().responseFinished); }
@Test public void testOnResponseFull() { Request request = DefaultFullRequest.builder() .body(Unpooled.EMPTY_BUFFER) .headers(new DefaultHeaders()) .method(GET) .path("/") .build(); session.onRequest(request); assertTrue(session.initialRequest().requestFinished); assertFalse(session.initialRequest().responseFinished); Response response = DefaultFullResponse.builder() .body(Unpooled.EMPTY_BUFFER) .status(OK) .headers(new DefaultHeaders()) .build(); session.onResponse(response); assertTrue(session.initialRequest().requestFinished); assertTrue(session.initialRequest().responseFinished); }
@Test public void testOnRequestFull() { Request request = DefaultFullRequest.builder() .body(Unpooled.EMPTY_BUFFER) .headers(new DefaultHeaders()) .method(GET) .path("/") .build(); session.onRequest(request); assertTrue(session.initialRequest().requestFinished); assertFalse(session.initialRequest().responseFinished); }
@Before public void setUp() { session = new Http1MessageSession(); }
/** * Check if the message session has completed, if so remove state and prepare for the next * session. */ public void flush() { // If we have a current request and we've seen all of the request data and all of the response // data we can reset. if (initialRequest != null && initialRequest.requestFinished && initialRequest.responseFinished) { reset(); } } }