diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/HttpUtil.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/HttpUtil.java index 304ef8f779..1c912b2aa1 100644 --- a/codec-http2/src/main/java/io/netty/handler/codec/http2/HttpUtil.java +++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/HttpUtil.java @@ -39,7 +39,6 @@ import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import java.util.Set; -import java.util.regex.Pattern; import static io.netty.handler.codec.http.HttpScheme.HTTP; import static io.netty.handler.codec.http.HttpScheme.HTTPS; @@ -289,24 +288,15 @@ public final class HttpUtil { URI requestTargetUri = URI.create(request.uri()); out.path(toHttp2Path(requestTargetUri)); out.method(request.method().asciiName()); + setHttp2Scheme(inHeaders, requestTargetUri, out); - // Attempt to take from HOST header before taking from the request-line - String host = inHeaders.getAsString(HttpHeaderNames.HOST); - boolean shouldSetAuthroity = !isOriginForm(requestTargetUri) && !isAsteriskForm(requestTargetUri); - if (host == null) { - if (shouldSetAuthroity) { - setHttp2Authority(inHeaders, requestTargetUri, out); - } - setHttp2Scheme(inHeaders, requestTargetUri, true, out); - } else { - URI hostUri = URI.create(host); - if (shouldSetAuthroity) { - setHttp2Authority(inHeaders, hostUri, out); - } - if (!setHttp2Scheme(inHeaders, hostUri, false, out)) { - /** :scheme must be present as defined by - rfc7540, 8.1.2.3. */ - setHttp2Scheme(inHeaders, requestTargetUri, true, out); + if (!isOriginForm(requestTargetUri) && !isAsteriskForm(requestTargetUri)) { + // Attempt to take from HOST header before taking from the request-line + String host = inHeaders.getAsString(HttpHeaderNames.HOST); + if (host == null || host.isEmpty()) { + setHttp2Authority(inHeaders, requestTargetUri.getAuthority(), out); + } else { + setHttp2Authority(inHeaders, host, out); } } } else if (in instanceof HttpResponse) { @@ -364,15 +354,16 @@ public final class HttpUtil { return path.isEmpty() ? EMPTY_REQUEST_PATH : new AsciiString(path); } - private static void setHttp2Authority(HttpHeaders in, URI uri, Http2Headers out) { + private static void setHttp2Authority(HttpHeaders in, String autority, Http2Headers out) { // The authority MUST NOT include the deprecated "userinfo" subcomponent - String value = uri.getAuthority(); - if (value != null) { - int endOfUserInfo = value.indexOf('@'); + if (autority != null) { + int endOfUserInfo = autority.indexOf('@'); if (endOfUserInfo < 0) { - out.authority(new AsciiString(value)); - } else if (endOfUserInfo + 1 < value.length()) { - out.authority(new AsciiString(value.substring(endOfUserInfo + 1))); + out.authority(new AsciiString(autority)); + } else if (endOfUserInfo + 1 < autority.length()) { + out.authority(new AsciiString(autority.substring(endOfUserInfo + 1))); + } else { + throw new IllegalArgumentException("autority: " + autority); } } else { // Consume the Authority extension header if present @@ -384,23 +375,28 @@ public final class HttpUtil { } } - private static boolean setHttp2Scheme(HttpHeaders in, URI uri, boolean mustSet, Http2Headers out) { + private static void setHttp2Scheme(HttpHeaders in, URI uri, Http2Headers out) { String value = uri.getScheme(); if (value != null) { out.scheme(new AsciiString(value)); - return true; + return; } + // Consume the Scheme extension header if present CharSequence cValue = in.get(ExtensionHeaderNames.SCHEME.text()); if (cValue != null) { out.scheme(AsciiString.of(cValue)); - return true; + return; } - if (uri.getPort() >= 0 || mustSet) { - out.scheme(uri.getPort() == HTTPS.port() ? HTTPS.name() : HTTP.name()); - return true; + + if (uri.getPort() == HTTPS.port()) { + out.scheme(HTTPS.name()); + } else if (uri.getPort() == HTTP.port()) { + out.scheme(HTTP.name()); + } else { + throw new IllegalArgumentException(":scheme must be specified. " + + "see https://tools.ietf.org/html/rfc7540#section-8.1.2.3"); } - return false; } /** diff --git a/codec-http2/src/test/java/io/netty/handler/codec/http2/HttpToHttp2ConnectionHandlerTest.java b/codec-http2/src/test/java/io/netty/handler/codec/http2/HttpToHttp2ConnectionHandlerTest.java index 82fd3c0398..88e8b3a8d3 100644 --- a/codec-http2/src/test/java/io/netty/handler/codec/http2/HttpToHttp2ConnectionHandlerTest.java +++ b/codec-http2/src/test/java/io/netty/handler/codec/http2/HttpToHttp2ConnectionHandlerTest.java @@ -118,13 +118,14 @@ public class HttpToHttp2ConnectionHandlerTest { } @Test - public void testJustHeadersRequest() throws Exception { + public void testHeadersOnlyRequest() throws Exception { bootstrapEnv(2, 1, 0); - final FullHttpRequest request = new DefaultFullHttpRequest(HTTP_1_1, GET, "/example"); + final FullHttpRequest request = new DefaultFullHttpRequest(HTTP_1_1, GET, + "http://my-user_name@www.example.org:5555/example"); final HttpHeaders httpHeaders = request.headers(); httpHeaders.setInt(HttpUtil.ExtensionHeaderNames.STREAM_ID.text(), 5); httpHeaders.set(HttpHeaderNames.HOST, - "http://my-user_name@www.example.org:5555/example"); + "my-user_name@www.example.org:5555"); httpHeaders.set(HttpUtil.ExtensionHeaderNames.AUTHORITY.text(), "www.example.org:5555"); httpHeaders.set(HttpUtil.ExtensionHeaderNames.SCHEME.text(), "http"); httpHeaders.add("foo", "goo"); @@ -136,18 +137,9 @@ public class HttpToHttp2ConnectionHandlerTest { .add(new AsciiString("foo"), new AsciiString("goo")) .add(new AsciiString("foo"), new AsciiString("goo2")) .add(new AsciiString("foo2"), new AsciiString("goo2")); - ChannelPromise writePromise = newPromise(); - ChannelFuture writeFuture = clientChannel.writeAndFlush(request, writePromise); - assertTrue(writePromise.awaitUninterruptibly(WAIT_TIME_SECONDS, SECONDS)); - assertTrue(writePromise.isSuccess()); - assertTrue(writeFuture.awaitUninterruptibly(WAIT_TIME_SECONDS, SECONDS)); - assertTrue(writeFuture.isSuccess()); - awaitRequests(); - verify(serverListener).onHeadersRead(any(ChannelHandlerContext.class), eq(5), - eq(http2Headers), eq(0), anyShort(), anyBoolean(), eq(0), eq(true)); - verify(serverListener, never()).onDataRead(any(ChannelHandlerContext.class), anyInt(), - any(ByteBuf.class), anyInt(), anyBoolean()); + ChannelPromise writePromise = newPromise(); + verifyHeadersOnly(http2Headers, writePromise, clientChannel.writeAndFlush(request, writePromise)); } @Test @@ -156,22 +148,14 @@ public class HttpToHttp2ConnectionHandlerTest { final FullHttpRequest request = new DefaultFullHttpRequest(HTTP_1_1, GET, "/where?q=now&f=then#section1"); final HttpHeaders httpHeaders = request.headers(); httpHeaders.setInt(HttpUtil.ExtensionHeaderNames.STREAM_ID.text(), 5); + httpHeaders.set(HttpUtil.ExtensionHeaderNames.SCHEME.text(), "http"); final Http2Headers http2Headers = new DefaultHttp2Headers().method(new AsciiString("GET")) .path(new AsciiString("/where?q=now&f=then#section1")) .scheme(new AsciiString("http")); - ChannelPromise writePromise = newPromise(); - ChannelFuture writeFuture = clientChannel.writeAndFlush(request, writePromise); - assertTrue(writePromise.awaitUninterruptibly(WAIT_TIME_SECONDS, SECONDS)); - assertTrue(writePromise.isSuccess()); - assertTrue(writeFuture.awaitUninterruptibly(WAIT_TIME_SECONDS, SECONDS)); - assertTrue(writeFuture.isSuccess()); - awaitRequests(); - verify(serverListener).onHeadersRead(any(ChannelHandlerContext.class), eq(5), - eq(http2Headers), eq(0), anyShort(), anyBoolean(), eq(0), eq(true)); - verify(serverListener, never()).onDataRead(any(ChannelHandlerContext.class), anyInt(), - any(ByteBuf.class), anyInt(), anyBoolean()); + ChannelPromise writePromise = newPromise(); + verifyHeadersOnly(http2Headers, writePromise, clientChannel.writeAndFlush(request, writePromise)); } @Test @@ -181,26 +165,17 @@ public class HttpToHttp2ConnectionHandlerTest { final HttpHeaders httpHeaders = request.headers(); httpHeaders.setInt(HttpUtil.ExtensionHeaderNames.STREAM_ID.text(), 5); httpHeaders.set(HttpHeaderNames.HOST, - "https://foouser@www.example.org:5555/ignored_host"); + "foouser@www.example.org:5555"); httpHeaders.set(HttpUtil.ExtensionHeaderNames.PATH.text(), "ignored_path"); httpHeaders.set(HttpUtil.ExtensionHeaderNames.AUTHORITY.text(), "ignored_authority"); - httpHeaders.set(HttpUtil.ExtensionHeaderNames.SCHEME.text(), "ignored_scheme"); + httpHeaders.set(HttpUtil.ExtensionHeaderNames.SCHEME.text(), "https"); final Http2Headers http2Headers = new DefaultHttp2Headers().method(new AsciiString("GET")) .path(new AsciiString("/pub/WWW/TheProject.html")) .authority(new AsciiString("www.example.org:5555")).scheme(new AsciiString("https")); - ChannelPromise writePromise = newPromise(); - ChannelFuture writeFuture = clientChannel.writeAndFlush(request, writePromise); - assertTrue(writePromise.awaitUninterruptibly(WAIT_TIME_SECONDS, SECONDS)); - assertTrue(writePromise.isSuccess()); - assertTrue(writeFuture.awaitUninterruptibly(WAIT_TIME_SECONDS, SECONDS)); - assertTrue(writeFuture.isSuccess()); - awaitRequests(); - verify(serverListener).onHeadersRead(any(ChannelHandlerContext.class), eq(5), - eq(http2Headers), eq(0), anyShort(), anyBoolean(), eq(0), eq(true)); - verify(serverListener, never()).onDataRead(any(ChannelHandlerContext.class), anyInt(), - any(ByteBuf.class), anyInt(), anyBoolean()); + ChannelPromise writePromise = newPromise(); + verifyHeadersOnly(http2Headers, writePromise, clientChannel.writeAndFlush(request, writePromise)); } @Test @@ -216,18 +191,9 @@ public class HttpToHttp2ConnectionHandlerTest { new DefaultHttp2Headers().method(new AsciiString("GET")) .path(new AsciiString("/pub/WWW/TheProject.html")) .authority(new AsciiString("www.example.org:5555")).scheme(new AsciiString("https")); - ChannelPromise writePromise = newPromise(); - ChannelFuture writeFuture = clientChannel.writeAndFlush(request, writePromise); - assertTrue(writePromise.awaitUninterruptibly(WAIT_TIME_SECONDS, SECONDS)); - assertTrue(writePromise.isSuccess()); - assertTrue(writeFuture.awaitUninterruptibly(WAIT_TIME_SECONDS, SECONDS)); - assertTrue(writeFuture.isSuccess()); - awaitRequests(); - verify(serverListener).onHeadersRead(any(ChannelHandlerContext.class), eq(5), - eq(http2Headers), eq(0), anyShort(), anyBoolean(), eq(0), eq(true)); - verify(serverListener, never()).onDataRead(any(ChannelHandlerContext.class), anyInt(), - any(ByteBuf.class), anyInt(), anyBoolean()); + ChannelPromise writePromise = newPromise(); + verifyHeadersOnly(http2Headers, writePromise, clientChannel.writeAndFlush(request, writePromise)); } @Test @@ -241,18 +207,9 @@ public class HttpToHttp2ConnectionHandlerTest { new DefaultHttp2Headers().method(new AsciiString("GET")) .path(new AsciiString("/pub/WWW/TheProject.html")) .authority(new AsciiString("www.example.org:5555")).scheme(new AsciiString("http")); - ChannelPromise writePromise = newPromise(); - ChannelFuture writeFuture = clientChannel.writeAndFlush(request, writePromise); - assertTrue(writePromise.awaitUninterruptibly(WAIT_TIME_SECONDS, SECONDS)); - assertTrue(writePromise.isSuccess()); - assertTrue(writeFuture.awaitUninterruptibly(WAIT_TIME_SECONDS, SECONDS)); - assertTrue(writeFuture.isSuccess()); - awaitRequests(); - verify(serverListener).onHeadersRead(any(ChannelHandlerContext.class), eq(5), - eq(http2Headers), eq(0), anyShort(), anyBoolean(), eq(0), eq(true)); - verify(serverListener, never()).onDataRead(any(ChannelHandlerContext.class), anyInt(), - any(ByteBuf.class), anyInt(), anyBoolean()); + ChannelPromise writePromise = newPromise(); + verifyHeadersOnly(http2Headers, writePromise, clientChannel.writeAndFlush(request, writePromise)); } @Test @@ -264,18 +221,9 @@ public class HttpToHttp2ConnectionHandlerTest { final Http2Headers http2Headers = new DefaultHttp2Headers().method(new AsciiString("CONNECT")).path(new AsciiString("/")) .scheme(new AsciiString("http")).authority(new AsciiString("www.example.com:80")); - ChannelPromise writePromise = newPromise(); - ChannelFuture writeFuture = clientChannel.writeAndFlush(request, writePromise); - assertTrue(writePromise.awaitUninterruptibly(WAIT_TIME_SECONDS, SECONDS)); - assertTrue(writePromise.isSuccess()); - assertTrue(writeFuture.awaitUninterruptibly(WAIT_TIME_SECONDS, SECONDS)); - assertTrue(writeFuture.isSuccess()); - awaitRequests(); - verify(serverListener).onHeadersRead(any(ChannelHandlerContext.class), eq(5), - eq(http2Headers), eq(0), anyShort(), anyBoolean(), eq(0), eq(true)); - verify(serverListener, never()).onDataRead(any(ChannelHandlerContext.class), anyInt(), - any(ByteBuf.class), anyInt(), anyBoolean()); + ChannelPromise writePromise = newPromise(); + verifyHeadersOnly(http2Headers, writePromise, clientChannel.writeAndFlush(request, writePromise)); } @Test @@ -284,22 +232,14 @@ public class HttpToHttp2ConnectionHandlerTest { final FullHttpRequest request = new DefaultFullHttpRequest(HTTP_1_1, OPTIONS, "*"); final HttpHeaders httpHeaders = request.headers(); httpHeaders.setInt(HttpUtil.ExtensionHeaderNames.STREAM_ID.text(), 5); - httpHeaders.set(HttpHeaderNames.HOST, "http://www.example.com:80"); + httpHeaders.set(HttpHeaderNames.HOST, "www.example.com:80"); + httpHeaders.set(HttpUtil.ExtensionHeaderNames.SCHEME.text(), "http"); final Http2Headers http2Headers = new DefaultHttp2Headers().method(new AsciiString("OPTIONS")).path(new AsciiString("*")) .scheme(new AsciiString("http")).authority(new AsciiString("www.example.com:80")); - ChannelPromise writePromise = newPromise(); - ChannelFuture writeFuture = clientChannel.writeAndFlush(request, writePromise); - assertTrue(writePromise.awaitUninterruptibly(WAIT_TIME_SECONDS, SECONDS)); - assertTrue(writePromise.isSuccess()); - assertTrue(writeFuture.awaitUninterruptibly(WAIT_TIME_SECONDS, SECONDS)); - assertTrue(writeFuture.isSuccess()); - awaitRequests(); - verify(serverListener).onHeadersRead(any(ChannelHandlerContext.class), eq(5), - eq(http2Headers), eq(0), anyShort(), anyBoolean(), eq(0), eq(true)); - verify(serverListener, never()).onDataRead(any(ChannelHandlerContext.class), anyInt(), - any(ByteBuf.class), anyInt(), anyBoolean()); + ChannelPromise writePromise = newPromise(); + verifyHeadersOnly(http2Headers, writePromise, clientChannel.writeAndFlush(request, writePromise)); } @Test @@ -310,77 +250,55 @@ public class HttpToHttp2ConnectionHandlerTest { final FullHttpRequest request = new DefaultFullHttpRequest(HTTP_1_1, GET, "/"); final HttpHeaders httpHeaders = request.headers(); httpHeaders.setInt(HttpUtil.ExtensionHeaderNames.STREAM_ID.text(), 5); - httpHeaders.set(HttpHeaderNames.HOST, "http://[::1]:80"); + httpHeaders.set(HttpHeaderNames.HOST, "[::1]:80"); + httpHeaders.set(HttpUtil.ExtensionHeaderNames.SCHEME.text(), "http"); final Http2Headers http2Headers = new DefaultHttp2Headers().method(new AsciiString("GET")).path(new AsciiString("/")) .scheme(new AsciiString("http")).authority(new AsciiString("[::1]:80")); - ChannelPromise writePromise = newPromise(); - ChannelFuture writeFuture = clientChannel.writeAndFlush(request, writePromise); - assertTrue(writePromise.awaitUninterruptibly(WAIT_TIME_SECONDS, SECONDS)); - assertTrue(writePromise.isSuccess()); - assertTrue(writeFuture.awaitUninterruptibly(WAIT_TIME_SECONDS, SECONDS)); - assertTrue(writeFuture.isSuccess()); - awaitRequests(); - verify(serverListener).onHeadersRead(any(ChannelHandlerContext.class), eq(5), - eq(http2Headers), eq(0), anyShort(), anyBoolean(), eq(0), eq(true)); - verify(serverListener, never()).onDataRead(any(ChannelHandlerContext.class), anyInt(), - any(ByteBuf.class), anyInt(), anyBoolean()); + ChannelPromise writePromise = newPromise(); + verifyHeadersOnly(http2Headers, writePromise, clientChannel.writeAndFlush(request, writePromise)); } @Test - public void testHostNoSchemeFormRequestTargetHandled() throws Exception { + public void testHostFormRequestTargetHandled() throws Exception { bootstrapEnv(2, 1, 0); final FullHttpRequest request = new DefaultFullHttpRequest(HTTP_1_1, GET, "/"); final HttpHeaders httpHeaders = request.headers(); httpHeaders.setInt(HttpUtil.ExtensionHeaderNames.STREAM_ID.text(), 5); - // This is an "irregular" host in that the scheme is "localhost" httpHeaders.set(HttpHeaderNames.HOST, "localhost:80"); + httpHeaders.set(HttpUtil.ExtensionHeaderNames.SCHEME.text(), "http"); final Http2Headers http2Headers = new DefaultHttp2Headers().method(new AsciiString("GET")).path(new AsciiString("/")) - .scheme(new AsciiString("localhost")); - ChannelPromise writePromise = newPromise(); - ChannelFuture writeFuture = clientChannel.writeAndFlush(request, writePromise); + .scheme(new AsciiString("http")).authority(new AsciiString("localhost:80")); - assertTrue(writePromise.awaitUninterruptibly(WAIT_TIME_SECONDS, SECONDS)); - assertTrue(writePromise.isSuccess()); - assertTrue(writeFuture.awaitUninterruptibly(WAIT_TIME_SECONDS, SECONDS)); - assertTrue(writeFuture.isSuccess()); - awaitRequests(); - verify(serverListener).onHeadersRead(any(ChannelHandlerContext.class), eq(5), - eq(http2Headers), eq(0), anyShort(), anyBoolean(), eq(0), eq(true)); - verify(serverListener, never()).onDataRead(any(ChannelHandlerContext.class), anyInt(), - any(ByteBuf.class), anyInt(), anyBoolean()); + ChannelPromise writePromise = newPromise(); + verifyHeadersOnly(http2Headers, writePromise, clientChannel.writeAndFlush(request, writePromise)); } @Test - public void testBadHostIPv4FormRequestTargetHandled() throws Exception { - // Invalid according to - // https://tools.ietf.org/html/rfc7230#section-2.7.1 -> https://tools.ietf.org/html/rfc3986#section-3 + public void testHostIPv4FormRequestTargetHandled() throws Exception { bootstrapEnv(2, 1, 0); final FullHttpRequest request = new DefaultFullHttpRequest(HTTP_1_1, GET, "/"); final HttpHeaders httpHeaders = request.headers(); httpHeaders.setInt(HttpUtil.ExtensionHeaderNames.STREAM_ID.text(), 5); httpHeaders.set(HttpHeaderNames.HOST, "1.2.3.4:80"); - ChannelPromise writePromise = newPromise(); - ChannelFuture writeFuture = clientChannel.writeAndFlush(request, writePromise); + httpHeaders.set(HttpUtil.ExtensionHeaderNames.SCHEME.text(), "http"); + final Http2Headers http2Headers = + new DefaultHttp2Headers().method(new AsciiString("GET")).path(new AsciiString("/")) + .scheme(new AsciiString("http")).authority(new AsciiString("1.2.3.4:80")); - assertTrue(writePromise.awaitUninterruptibly(WAIT_TIME_SECONDS, SECONDS)); - assertTrue(writePromise.isDone()); - assertFalse(writePromise.isSuccess()); - assertTrue(writeFuture.isDone()); - assertFalse(writeFuture.isSuccess()); + ChannelPromise writePromise = newPromise(); + verifyHeadersOnly(http2Headers, writePromise, clientChannel.writeAndFlush(request, writePromise)); } @Test - public void testBadHostIPv6FormRequestTargetHandled() throws Exception { - // Invalid according to - // https://tools.ietf.org/html/rfc7230#section-2.7.1 -> https://tools.ietf.org/html/rfc3986#section-3 + public void testNoSchemeRequestTargetHandled() throws Exception { bootstrapEnv(2, 1, 0); final FullHttpRequest request = new DefaultFullHttpRequest(HTTP_1_1, GET, "/"); final HttpHeaders httpHeaders = request.headers(); httpHeaders.setInt(HttpUtil.ExtensionHeaderNames.STREAM_ID.text(), 5); - httpHeaders.set(HttpHeaderNames.HOST, "[::1]:80"); + httpHeaders.set(HttpHeaderNames.HOST, "localhost"); ChannelPromise writePromise = newPromise(); ChannelFuture writeFuture = clientChannel.writeAndFlush(request, writePromise); @@ -404,16 +322,17 @@ public class HttpToHttp2ConnectionHandlerTest { }).when(serverListener).onDataRead(any(ChannelHandlerContext.class), eq(3), any(ByteBuf.class), eq(0), eq(true)); bootstrapEnv(3, 1, 0); - final FullHttpRequest request = new DefaultFullHttpRequest(HTTP_1_1, POST, "/example", + final FullHttpRequest request = new DefaultFullHttpRequest(HTTP_1_1, POST, + "http://your_user-name123@www.example.org:5555/example", Unpooled.copiedBuffer(text, UTF_8)); final HttpHeaders httpHeaders = request.headers(); - httpHeaders.set(HttpHeaderNames.HOST, "http://your_user-name123@www.example.org:5555/example"); + httpHeaders.set(HttpHeaderNames.HOST, "www.example-origin.org:5555"); httpHeaders.add("foo", "goo"); httpHeaders.add("foo", "goo2"); httpHeaders.add("foo2", "goo2"); final Http2Headers http2Headers = new DefaultHttp2Headers().method(new AsciiString("POST")).path(new AsciiString("/example")) - .authority(new AsciiString("www.example.org:5555")).scheme(new AsciiString("http")) + .authority(new AsciiString("www.example-origin.org:5555")).scheme(new AsciiString("http")) .add(new AsciiString("foo"), new AsciiString("goo")) .add(new AsciiString("foo"), new AsciiString("goo2")) .add(new AsciiString("foo2"), new AsciiString("goo2")); @@ -446,10 +365,11 @@ public class HttpToHttp2ConnectionHandlerTest { }).when(serverListener).onDataRead(any(ChannelHandlerContext.class), eq(3), any(ByteBuf.class), eq(0), eq(false)); bootstrapEnv(4, 1, 1); - final FullHttpRequest request = new DefaultFullHttpRequest(HTTP_1_1, POST, "/example", + final FullHttpRequest request = new DefaultFullHttpRequest(HTTP_1_1, POST, + "http://your_user-name123@www.example.org:5555/example", Unpooled.copiedBuffer(text, UTF_8)); final HttpHeaders httpHeaders = request.headers(); - httpHeaders.set(HttpHeaderNames.HOST, "http://your_user-name123@www.example.org:5555/example"); + httpHeaders.set(HttpHeaderNames.HOST, "www.example.org:5555"); httpHeaders.add("foo", "goo"); httpHeaders.add("foo", "goo2"); httpHeaders.add("foo2", "goo2"); @@ -497,9 +417,10 @@ public class HttpToHttp2ConnectionHandlerTest { }).when(serverListener).onDataRead(any(ChannelHandlerContext.class), eq(3), any(ByteBuf.class), eq(0), eq(false)); bootstrapEnv(4, 1, 1); - final HttpRequest request = new DefaultHttpRequest(HTTP_1_1, POST, "/example"); + final HttpRequest request = new DefaultHttpRequest(HTTP_1_1, POST, + "http://your_user-name123@www.example.org:5555/example"); final HttpHeaders httpHeaders = request.headers(); - httpHeaders.set(HttpHeaderNames.HOST, "http://your_user-name123@www.example.org:5555/example"); + httpHeaders.set(HttpHeaderNames.HOST, "www.example.org:5555"); httpHeaders.add(HttpHeaderNames.TRANSFER_ENCODING, "chunked"); httpHeaders.add("foo", "goo"); httpHeaders.add("foo", "goo2"); @@ -593,6 +514,19 @@ public class HttpToHttp2ConnectionHandlerTest { clientChannel = ccf.channel(); } + private void verifyHeadersOnly(Http2Headers expected, ChannelPromise writePromise, ChannelFuture writeFuture) + throws Exception { + assertTrue(writePromise.awaitUninterruptibly(WAIT_TIME_SECONDS, SECONDS)); + assertTrue(writePromise.isSuccess()); + assertTrue(writeFuture.awaitUninterruptibly(WAIT_TIME_SECONDS, SECONDS)); + assertTrue(writeFuture.isSuccess()); + awaitRequests(); + verify(serverListener).onHeadersRead(any(ChannelHandlerContext.class), eq(5), + eq(expected), eq(0), anyShort(), anyBoolean(), eq(0), eq(true)); + verify(serverListener, never()).onDataRead(any(ChannelHandlerContext.class), anyInt(), + any(ByteBuf.class), anyInt(), anyBoolean()); + } + private void awaitRequests() throws Exception { assertTrue(requestLatch.await(WAIT_TIME_SECONDS, SECONDS)); if (trailersLatch != null) {