From 8ea333ec5a85a9c6925bbce85e9ea6f3eb6ef1d5 Mon Sep 17 00:00:00 2001 From: Kowalczyk Date: Mon, 14 Oct 2019 22:00:32 +0200 Subject: [PATCH] 2934 make compressed http2 request possible Signed-off-by: Kowalczyk --- .../http/impl/Http1xUpgradeToH2CHandler.java | 14 ++++++-- .../impl/HttpServerChannelInitializer.java | 2 +- .../vertx/core/http/Http2CompressionTest.java | 33 ++++++++++++++++--- 3 files changed, 42 insertions(+), 7 deletions(-) diff --git a/src/main/java/io/vertx/core/http/impl/Http1xUpgradeToH2CHandler.java b/src/main/java/io/vertx/core/http/impl/Http1xUpgradeToH2CHandler.java index 4f152952d..df1809dd9 100644 --- a/src/main/java/io/vertx/core/http/impl/Http1xUpgradeToH2CHandler.java +++ b/src/main/java/io/vertx/core/http/impl/Http1xUpgradeToH2CHandler.java @@ -8,6 +8,7 @@ import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.ChannelPipeline; import io.netty.handler.codec.http.*; import io.netty.handler.codec.http2.*; +import io.vertx.core.http.HttpServerOptions; import io.netty.handler.timeout.IdleState; import io.netty.handler.timeout.IdleStateEvent; import io.vertx.core.Handler; @@ -26,10 +27,14 @@ class Http1xUpgradeToH2CHandler extends ChannelInboundHandlerAdapter { private final HttpServerChannelInitializer initializer; private final HandlerHolder> holder; private VertxHttp2ConnectionHandler handler; + private final boolean isCompressionSupported; + private final boolean isDecompressionSupported; - Http1xUpgradeToH2CHandler(HttpServerChannelInitializer initializer, HandlerHolder> holder) { + Http1xUpgradeToH2CHandler(HttpServerChannelInitializer initializer, HandlerHolder> holder, boolean isCompressionSupported, boolean isDecompressionSupported) { this.initializer = initializer; this.holder = holder; + this.isCompressionSupported = isCompressionSupported; + this.isDecompressionSupported = isDecompressionSupported; } @Override @@ -68,9 +73,14 @@ class Http1xUpgradeToH2CHandler extends ChannelInboundHandlerAdapter { DefaultFullHttpResponse res = new DefaultFullHttpResponse(HTTP_1_1, SWITCHING_PROTOCOLS, Unpooled.EMPTY_BUFFER, false); res.headers().add(HttpHeaderNames.CONNECTION, HttpHeaderValues.UPGRADE); res.headers().add(HttpHeaderNames.UPGRADE, Http2CodecUtil.HTTP_UPGRADE_PROTOCOL_NAME); - res.headers().add(HttpHeaderNames.CONTENT_LENGTH, HttpHeaderValues.ZERO); ctx.writeAndFlush(res); pipeline.remove("httpEncoder"); + if(isCompressionSupported) { + pipeline.remove("deflater"); + } + if(isDecompressionSupported) { + pipeline.remove("inflater"); + } handler = initializer.buildHttp2ConnectionHandler(holder.context, holder.handler); pipeline.addLast("handler", handler); handler.serverUpgrade(ctx, settings, request); diff --git a/src/main/java/io/vertx/core/http/impl/HttpServerChannelInitializer.java b/src/main/java/io/vertx/core/http/impl/HttpServerChannelInitializer.java index 14cffde3a..4796c95b5 100644 --- a/src/main/java/io/vertx/core/http/impl/HttpServerChannelInitializer.java +++ b/src/main/java/io/vertx/core/http/impl/HttpServerChannelInitializer.java @@ -237,7 +237,7 @@ public class HttpServerChannelInitializer extends ChannelInitializer { if (disableH2C) { configureHttp1(pipeline, holder); } else { - pipeline.addLast("h2c", new Http1xUpgradeToH2CHandler(this, holder)); + pipeline.addLast("h2c", new Http1xUpgradeToH2CHandler(this, holder, options.isCompressionSupported(), options.isDecompressionSupported())); } } diff --git a/src/test/java/io/vertx/core/http/Http2CompressionTest.java b/src/test/java/io/vertx/core/http/Http2CompressionTest.java index 66a81a829..c82e49199 100644 --- a/src/test/java/io/vertx/core/http/Http2CompressionTest.java +++ b/src/test/java/io/vertx/core/http/Http2CompressionTest.java @@ -38,15 +38,16 @@ public class Http2CompressionTest extends Http2TestBase { + " * You may elect to redistribute this code under either of these licenses.\n" + " */"; - HttpServer serverWithMinCompressionLevel, serverWithMaxCompressionLevel = null; + HttpServer serverWithMinCompressionLevel, serverWithMaxCompressionLevel, serverWithCompressionWithoutTls = null; - HttpClient clientraw = null; + HttpClient clientraw = null, clearTextClient = null; public void setUp() throws Exception { super.setUp(); client = vertx.createHttpClient(createHttp2ClientOptions().setTryUseCompression(true)); clientraw = vertx.createHttpClient(createHttp2ClientOptions().setTryUseCompression(false)); + clearTextClient = vertx.createHttpClient(new HttpClientOptions().setTryUseCompression(true).setProtocolVersion(HttpVersion.HTTP_2).setHttp2ClearTextUpgrade(true)); // server = vertx.createHttpServer(); serverWithMinCompressionLevel = vertx.createHttpServer( @@ -57,6 +58,12 @@ public class Http2CompressionTest extends Http2TestBase { createHttp2ServerOptions(DEFAULT_HTTP_PORT + 1, DEFAULT_HTTP_HOST) .setCompressionSupported(true) .setCompressionLevel(9)); + //regression part of test for https://github.com/eclipse-vertx/vert.x/issues/2934 + serverWithCompressionWithoutTls = vertx.createHttpServer( + new HttpServerOptions() + .setCompressionSupported(true) + .setPort(DEFAULT_HTTP_PORT + 2) + .setHost(DEFAULT_HTTP_HOST)); } @Test @@ -71,7 +78,7 @@ public class Http2CompressionTest extends Http2TestBase { serverWithMinCompressionLevel.requestHandler(requestHandler); serverWithMaxCompressionLevel.requestHandler(requestHandler); - + serverWithCompressionWithoutTls.requestHandler(requestHandler); serverWithMinCompressionLevel.listen(onSuccess(serverReady -> { testMinCompression(); testRawMinCompression(); @@ -82,6 +89,10 @@ public class Http2CompressionTest extends Http2TestBase { testRawMaxCompression(); })); + serverWithCompressionWithoutTls.listen(onSuccess(serverReady -> { + testCompressionWithHttp2Upgrade(); + })); + await(); } @@ -99,6 +110,20 @@ public class Http2CompressionTest extends Http2TestBase { }).end(); } + public static boolean compressionWithoutTlsPassed = false; + + public void testCompressionWithHttp2Upgrade() { + clearTextClient.request(HttpMethod.GET, DEFAULT_HTTP_PORT + 2, DEFAULT_HTTP_HOST, "some-uri", + resp -> { + resp.bodyHandler(responseBuffer -> { + String responseBody = responseBuffer.toString(CharsetUtil.UTF_8); + assertEquals(COMPRESS_TEST_STRING, responseBody); + compressionWithoutTlsPassed = true; + terminateTestWhenAllPassed(); + }); + }).end(); + } + public static boolean maxCompressionTestPassed = false; public void testMaxCompression() { @@ -146,7 +171,7 @@ public class Http2CompressionTest extends Http2TestBase { } public void terminateTestWhenAllPassed() { - if (maxCompressionTestPassed && minCompressionTestPassed + if (maxCompressionTestPassed && minCompressionTestPassed && compressionWithoutTlsPassed && rawMinCompressionResponseByteCount != null && rawMaxCompressionResponseByteCount != null) { assertTrue("Checking compression byte size difference", rawMaxCompressionResponseByteCount > 0 && rawMinCompressionResponseByteCount > rawMaxCompressionResponseByteCount);