@Test public void clientRequestStreamDependencyInHttpMessageFlow() throws Exception { setServerLatch(2); final String text = "hello world big time data!"; final ByteBuf content = Unpooled.copiedBuffer(text.getBytes()); final String text2 = "hello world big time data...number 2!!"; final ByteBuf content2 = Unpooled.copiedBuffer(text2.getBytes()); final FullHttpRequest request = new DefaultFullHttpRequest( HttpVersion.HTTP_1_1, HttpMethod.PUT, "/some/path/resource", content, true); final FullHttpMessage request2 = new DefaultFullHttpRequest( HttpVersion.HTTP_1_1, HttpMethod.PUT, "/some/path/resource2", content2, true); try { HttpHeaders httpHeaders = request.headers(); httpHeaders.set(HttpUtil.ExtensionHeaderNames.STREAM_ID.text(), 3); httpHeaders.set(HttpHeaders.Names.CONTENT_LENGTH, text.length()); HttpHeaders httpHeaders2 = request2.headers(); httpHeaders2.set(HttpUtil.ExtensionHeaderNames.STREAM_ID.text(), 5); httpHeaders2.set(HttpUtil.ExtensionHeaderNames.STREAM_DEPENDENCY_ID.text(), 3); httpHeaders2.set(HttpUtil.ExtensionHeaderNames.STREAM_WEIGHT.text(), 123); httpHeaders2.set(HttpHeaders.Names.CONTENT_LENGTH, text2.length()); final Http2Headers http2Headers = new DefaultHttp2Headers().method(as("PUT")).path(as("/some/path/resource")); final Http2Headers http2Headers2 = new DefaultHttp2Headers().method(as("PUT")).path(as("/some/path/resource2")); runInChannel( clientChannel, new Http2Runnable() { @Override public void run() { frameWriter.writeHeaders(ctxClient(), 3, http2Headers, 0, false, newPromiseClient()); frameWriter.writeHeaders(ctxClient(), 5, http2Headers2, 0, false, newPromiseClient()); frameWriter.writePriority(ctxClient(), 5, 3, (short) 123, true, newPromiseClient()); frameWriter.writeData(ctxClient(), 3, content.retain(), 0, true, newPromiseClient()); frameWriter.writeData(ctxClient(), 5, content2.retain(), 0, true, newPromiseClient()); ctxClient().flush(); } }); awaitRequests(); ArgumentCaptor<FullHttpMessage> httpObjectCaptor = ArgumentCaptor.forClass(FullHttpMessage.class); verify(serverListener, times(2)).messageReceived(httpObjectCaptor.capture()); capturedRequests = httpObjectCaptor.getAllValues(); assertEquals(request, capturedRequests.get(0)); assertEquals(request2, capturedRequests.get(1)); } finally { request.release(); request2.release(); } }
@Test public void clientRequestMultipleEmptyDataFrames() throws Exception { final String text = ""; final ByteBuf content = Unpooled.copiedBuffer(text.getBytes()); final FullHttpRequest request = new DefaultFullHttpRequest( HttpVersion.HTTP_1_1, HttpMethod.GET, "/some/path/resource2", content, true); try { HttpHeaders httpHeaders = request.headers(); httpHeaders.set(HttpUtil.ExtensionHeaderNames.STREAM_ID.text(), 3); httpHeaders.set(HttpHeaders.Names.CONTENT_LENGTH, text.length()); final Http2Headers http2Headers = new DefaultHttp2Headers().method(as("GET")).path(as("/some/path/resource2")); runInChannel( clientChannel, new Http2Runnable() { @Override public void run() { frameWriter.writeHeaders(ctxClient(), 3, http2Headers, 0, false, newPromiseClient()); frameWriter.writeData(ctxClient(), 3, content.retain(), 0, false, newPromiseClient()); frameWriter.writeData(ctxClient(), 3, content.retain(), 0, false, newPromiseClient()); frameWriter.writeData(ctxClient(), 3, content.retain(), 0, true, newPromiseClient()); ctxClient().flush(); } }); awaitRequests(); ArgumentCaptor<FullHttpMessage> requestCaptor = ArgumentCaptor.forClass(FullHttpMessage.class); verify(serverListener).messageReceived(requestCaptor.capture()); capturedRequests = requestCaptor.getAllValues(); assertEquals(request, capturedRequests.get(0)); } finally { request.release(); } }
@Test public void clientRequestMultipleHeaders() throws Exception { // writeHeaders will implicitly add an END_HEADERS tag each time and so this test does not // follow the HTTP // message flow. We currently accept this message flow and just add the second headers to the // trailing headers. final String text = ""; final ByteBuf content = Unpooled.copiedBuffer(text.getBytes()); final FullHttpRequest request = new DefaultFullHttpRequest( HttpVersion.HTTP_1_1, HttpMethod.GET, "/some/path/resource2", content, true); try { HttpHeaders httpHeaders = request.headers(); httpHeaders.set(HttpUtil.ExtensionHeaderNames.STREAM_ID.text(), 3); httpHeaders.set(HttpHeaders.Names.CONTENT_LENGTH, text.length()); HttpHeaders trailingHeaders = request.trailingHeaders(); trailingHeaders.set("FoO", "goo"); trailingHeaders.set("foO2", "goo2"); trailingHeaders.add("fOo2", "goo3"); final Http2Headers http2Headers = new DefaultHttp2Headers().method(as("GET")).path(as("/some/path/resource2")); final Http2Headers http2Headers2 = new DefaultHttp2Headers() .set(as("foo"), as("goo")) .set(as("foo2"), as("goo2")) .add(as("foo2"), as("goo3")); runInChannel( clientChannel, new Http2Runnable() { @Override public void run() { frameWriter.writeHeaders(ctxClient(), 3, http2Headers, 0, false, newPromiseClient()); frameWriter.writeHeaders(ctxClient(), 3, http2Headers2, 0, false, newPromiseClient()); frameWriter.writeData(ctxClient(), 3, content.retain(), 0, true, newPromiseClient()); ctxClient().flush(); } }); awaitRequests(); ArgumentCaptor<FullHttpMessage> requestCaptor = ArgumentCaptor.forClass(FullHttpMessage.class); verify(serverListener).messageReceived(requestCaptor.capture()); capturedRequests = requestCaptor.getAllValues(); assertEquals(request, capturedRequests.get(0)); } finally { request.release(); } }
@Test public void clientRequestSingleHeaderNoDataFrames() throws Exception { final FullHttpRequest request = new DefaultFullHttpRequest( HttpVersion.HTTP_1_1, HttpMethod.GET, "/some/path/resource2", true); try { HttpHeaders httpHeaders = request.headers(); httpHeaders.set(HttpUtil.ExtensionHeaderNames.SCHEME.text(), "https"); httpHeaders.set(HttpUtil.ExtensionHeaderNames.AUTHORITY.text(), "example.org"); httpHeaders.set(HttpUtil.ExtensionHeaderNames.STREAM_ID.text(), 3); httpHeaders.set(HttpHeaders.Names.CONTENT_LENGTH, 0); final Http2Headers http2Headers = new DefaultHttp2Headers() .method(as("GET")) .scheme(as("https")) .authority(as("example.org")) .path(as("/some/path/resource2")); runInChannel( clientChannel, new Http2Runnable() { @Override public void run() { frameWriter.writeHeaders(ctxClient(), 3, http2Headers, 0, true, newPromiseClient()); ctxClient().flush(); } }); awaitRequests(); ArgumentCaptor<FullHttpMessage> requestCaptor = ArgumentCaptor.forClass(FullHttpMessage.class); verify(serverListener).messageReceived(requestCaptor.capture()); capturedRequests = requestCaptor.getAllValues(); assertEquals(request, capturedRequests.get(0)); } finally { request.release(); } }
@Test public void serverResponseHeaderInformational() throws Exception { final FullHttpMessage request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.PUT, "/info/test", true); HttpHeaders httpHeaders = request.headers(); httpHeaders.set(HttpUtil.ExtensionHeaderNames.STREAM_ID.text(), 3); httpHeaders.set(HttpHeaders.Names.EXPECT, HttpHeaders.Values.CONTINUE); httpHeaders.set(HttpHeaders.Names.CONTENT_LENGTH, 0); final Http2Headers http2Headers = new DefaultHttp2Headers() .method(as("PUT")) .path(as("/info/test")) .set( as(HttpHeaders.Names.EXPECT.toString()), as(HttpHeaders.Values.CONTINUE.toString())); final FullHttpMessage response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.CONTINUE); final String text = "a big payload"; final ByteBuf payload = Unpooled.copiedBuffer(text.getBytes()); final FullHttpMessage request2 = request.copy(payload); final FullHttpMessage response2 = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); try { runInChannel( clientChannel, new Http2Runnable() { @Override public void run() { frameWriter.writeHeaders(ctxClient(), 3, http2Headers, 0, false, newPromiseClient()); ctxClient().flush(); } }); awaitRequests(); ArgumentCaptor<FullHttpMessage> requestCaptor = ArgumentCaptor.forClass(FullHttpMessage.class); verify(serverListener).messageReceived(requestCaptor.capture()); capturedRequests = requestCaptor.getAllValues(); assertEquals(request, capturedRequests.get(0)); cleanupCapturedRequests(); reset(serverListener); httpHeaders = response.headers(); httpHeaders.set(HttpUtil.ExtensionHeaderNames.STREAM_ID.text(), 3); httpHeaders.set(HttpHeaders.Names.CONTENT_LENGTH, 0); final Http2Headers http2HeadersResponse = new DefaultHttp2Headers().status(as("100")); runInChannel( serverConnectedChannel, new Http2Runnable() { @Override public void run() { frameWriter.writeHeaders( ctxServer(), 3, http2HeadersResponse, 0, false, newPromiseServer()); ctxServer().flush(); } }); awaitResponses(); ArgumentCaptor<FullHttpMessage> responseCaptor = ArgumentCaptor.forClass(FullHttpMessage.class); verify(clientListener).messageReceived(responseCaptor.capture()); capturedResponses = responseCaptor.getAllValues(); assertEquals(response, capturedResponses.get(0)); cleanupCapturedResponses(); reset(clientListener); setServerLatch(1); httpHeaders = request2.headers(); httpHeaders.set(HttpHeaders.Names.CONTENT_LENGTH, text.length()); httpHeaders.remove(HttpHeaders.Names.EXPECT); runInChannel( clientChannel, new Http2Runnable() { @Override public void run() { frameWriter.writeData(ctxClient(), 3, payload.retain(), 0, true, newPromiseClient()); ctxClient().flush(); } }); awaitRequests(); requestCaptor = ArgumentCaptor.forClass(FullHttpMessage.class); verify(serverListener).messageReceived(requestCaptor.capture()); capturedRequests = requestCaptor.getAllValues(); assertEquals(request2, capturedRequests.get(0)); setClientLatch(1); httpHeaders = response2.headers(); httpHeaders.set(HttpUtil.ExtensionHeaderNames.STREAM_ID.text(), 3); httpHeaders.set(HttpHeaders.Names.CONTENT_LENGTH, 0); final Http2Headers http2HeadersResponse2 = new DefaultHttp2Headers().status(as("200")); runInChannel( serverConnectedChannel, new Http2Runnable() { @Override public void run() { frameWriter.writeHeaders( ctxServer(), 3, http2HeadersResponse2, 0, true, newPromiseServer()); ctxServer().flush(); } }); awaitResponses(); responseCaptor = ArgumentCaptor.forClass(FullHttpMessage.class); verify(clientListener).messageReceived(responseCaptor.capture()); capturedResponses = responseCaptor.getAllValues(); assertEquals(response2, capturedResponses.get(0)); } finally { request.release(); request2.release(); response.release(); response2.release(); } }
@Test public void serverRequestPushPromise() throws Exception { setClientLatch(2); final String text = "hello world big time data!"; final ByteBuf content = Unpooled.copiedBuffer(text.getBytes()); final String text2 = "hello world smaller data?"; final ByteBuf content2 = Unpooled.copiedBuffer(text2.getBytes()); final FullHttpMessage response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, content, true); final FullHttpMessage response2 = new DefaultFullHttpResponse( HttpVersion.HTTP_1_1, HttpResponseStatus.CREATED, content2, true); final FullHttpMessage request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/push/test", true); try { HttpHeaders httpHeaders = response.headers(); httpHeaders.set(HttpUtil.ExtensionHeaderNames.STREAM_ID.text(), 3); httpHeaders.set(HttpHeaders.Names.CONTENT_LENGTH, text.length()); HttpHeaders httpHeaders2 = response2.headers(); httpHeaders2.set(HttpUtil.ExtensionHeaderNames.SCHEME.text(), "https"); httpHeaders2.set(HttpUtil.ExtensionHeaderNames.AUTHORITY.text(), "example.org"); httpHeaders2.set(HttpUtil.ExtensionHeaderNames.STREAM_ID.text(), 5); httpHeaders2.set(HttpUtil.ExtensionHeaderNames.STREAM_PROMISE_ID.text(), 3); httpHeaders2.set(HttpHeaders.Names.CONTENT_LENGTH, text2.length()); httpHeaders = request.headers(); httpHeaders.set(HttpUtil.ExtensionHeaderNames.STREAM_ID.text(), 3); httpHeaders.set(HttpHeaders.Names.CONTENT_LENGTH, 0); final Http2Headers http2Headers3 = new DefaultHttp2Headers().method(as("GET")).path(as("/push/test")); runInChannel( clientChannel, new Http2Runnable() { @Override public void run() { frameWriter.writeHeaders(ctxClient(), 3, http2Headers3, 0, true, newPromiseClient()); ctxClient().flush(); } }); awaitRequests(); ArgumentCaptor<FullHttpMessage> requestCaptor = ArgumentCaptor.forClass(FullHttpMessage.class); verify(serverListener).messageReceived(requestCaptor.capture()); capturedRequests = requestCaptor.getAllValues(); assertEquals(request, capturedRequests.get(0)); final Http2Headers http2Headers = new DefaultHttp2Headers().status(as("200")); final Http2Headers http2Headers2 = new DefaultHttp2Headers() .status(as("201")) .scheme(as("https")) .authority(as("example.org")); runInChannel( serverConnectedChannel, new Http2Runnable() { @Override public void run() { frameWriter.writeHeaders(ctxServer(), 3, http2Headers, 0, false, newPromiseServer()); frameWriter.writePushPromise(ctxServer(), 3, 5, http2Headers2, 0, newPromiseServer()); frameWriter.writeData(ctxServer(), 3, content.retain(), 0, true, newPromiseServer()); frameWriter.writeData(ctxServer(), 5, content2.retain(), 0, true, newPromiseServer()); ctxServer().flush(); } }); awaitResponses(); ArgumentCaptor<FullHttpMessage> responseCaptor = ArgumentCaptor.forClass(FullHttpMessage.class); verify(clientListener, times(2)).messageReceived(responseCaptor.capture()); capturedResponses = responseCaptor.getAllValues(); assertEquals(response, capturedResponses.get(0)); assertEquals(response2, capturedResponses.get(1)); } finally { request.release(); response.release(); response2.release(); } }