Skip to content

Commit

Permalink
Replace HTTP client option tryUseCompression with decompressionSuppor…
Browse files Browse the repository at this point in the history
…ted (eclipse-vertx#4931)

See eclipse-vertx#4022

Signed-off-by: Thomas Segismont <[email protected]>
  • Loading branch information
tsegismont authored Nov 8, 2023
1 parent e3c7095 commit f5e7003
Show file tree
Hide file tree
Showing 10 changed files with 62 additions and 144 deletions.
2 changes: 1 addition & 1 deletion src/main/asciidoc/http.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -1439,7 +1439,7 @@ If the body of the response was compressed via gzip it will include for example

Content-Encoding: gzip

To enable compression set {@link io.vertx.core.http.HttpClientOptions#setTryUseCompression(boolean)} on the options
To enable compression set {@link io.vertx.core.http.HttpClientOptions#setDecompressionSupported(boolean)} on the options
used when creating the client.

By default compression is disabled.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ static void fromJson(Iterable<java.util.Map.Entry<String, Object>> json, HttpCli
obj.setVerifyHost((Boolean)member.getValue());
}
break;
case "tryUseCompression":
case "decompressionSupported":
if (member.getValue() instanceof Boolean) {
obj.setTryUseCompression((Boolean)member.getValue());
obj.setDecompressionSupported((Boolean)member.getValue());
}
break;
case "defaultHost":
Expand Down Expand Up @@ -167,7 +167,7 @@ static void toJson(HttpClientOptions obj, java.util.Map<String, Object> json) {
json.put("pipelining", obj.isPipelining());
json.put("pipeliningLimit", obj.getPipeliningLimit());
json.put("verifyHost", obj.isVerifyHost());
json.put("tryUseCompression", obj.isTryUseCompression());
json.put("decompressionSupported", obj.isDecompressionSupported());
if (obj.getDefaultHost() != null) {
json.put("defaultHost", obj.getDefaultHost());
}
Expand Down
34 changes: 14 additions & 20 deletions src/main/java/io/vertx/core/http/HttpClientOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,15 @@

package io.vertx.core.http;

import io.netty.handler.logging.ByteBufFormat;
import io.vertx.codegen.annotations.DataObject;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.impl.Arguments;
import io.vertx.core.json.JsonObject;
import io.vertx.core.net.*;
import io.vertx.core.tracing.TracingPolicy;
import io.netty.handler.logging.ByteBufFormat;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
Expand Down Expand Up @@ -70,9 +66,9 @@ public class HttpClientOptions extends ClientOptionsBase {
public static final int DEFAULT_KEEP_ALIVE_TIMEOUT = 60;

/**
* Default value of whether the client will attempt to use compression = {@code false}
* Whether the client should send requests with an {@code accepting-encoding} header set to a compression algorithm by default = {@code false}
*/
public static final boolean DEFAULT_TRY_USE_COMPRESSION = false;
public static final boolean DEFAULT_DECOMPRESSION_SUPPORTED = false;

/**
* Default value of whether hostname verification (for SSL/TLS) is enabled = {@code true}
Expand Down Expand Up @@ -163,7 +159,7 @@ public class HttpClientOptions extends ClientOptionsBase {
private int http2ConnectionWindowSize;
private int http2KeepAliveTimeout;

private boolean tryUseCompression;
private boolean decompressionSupported;
private String defaultHost;
private int defaultPort;
private HttpVersion protocolVersion;
Expand Down Expand Up @@ -216,7 +212,7 @@ public HttpClientOptions(HttpClientOptions other) {
this.http2MultiplexingLimit = other.http2MultiplexingLimit;
this.http2ConnectionWindowSize = other.http2ConnectionWindowSize;
this.http2KeepAliveTimeout = other.getHttp2KeepAliveTimeout();
this.tryUseCompression = other.isTryUseCompression();
this.decompressionSupported = other.decompressionSupported;
this.defaultHost = other.defaultHost;
this.defaultPort = other.defaultPort;
this.protocolVersion = other.protocolVersion;
Expand Down Expand Up @@ -266,7 +262,7 @@ private void init() {
http2MultiplexingLimit = DEFAULT_HTTP2_MULTIPLEXING_LIMIT;
http2ConnectionWindowSize = DEFAULT_HTTP2_CONNECTION_WINDOW_SIZE;
http2KeepAliveTimeout = DEFAULT_HTTP2_KEEP_ALIVE_TIMEOUT;
tryUseCompression = DEFAULT_TRY_USE_COMPRESSION;
decompressionSupported = DEFAULT_DECOMPRESSION_SUPPORTED;
defaultHost = DEFAULT_DEFAULT_HOST;
defaultPort = DEFAULT_DEFAULT_PORT;
protocolVersion = DEFAULT_PROTOCOL_VERSION;
Expand Down Expand Up @@ -671,22 +667,20 @@ public HttpClientOptions setVerifyHost(boolean verifyHost) {
}

/**
* Is compression enabled on the client?
*
* @return {@code true} if enabled
* @return {@code true} if the client should send requests with an {@code accepting-encoding} header set to a compression algorithm, {@code false} otherwise
*/
public boolean isTryUseCompression() {
return tryUseCompression;
public boolean isDecompressionSupported() {
return decompressionSupported;
}

/**
* Set whether compression is enabled
* Whether the client should send requests with an {@code accepting-encoding} header set to a compression algorithm.
*
* @param tryUseCompression {@code true} if enabled
* @param decompressionSupported {@code true} if the client should send a request with an {@code accepting-encoding} header set to a compression algorithm, {@code false} otherwise
* @return a reference to this, so the API can be used fluently
*/
public HttpClientOptions setTryUseCompression(boolean tryUseCompression) {
this.tryUseCompression = tryUseCompression;
public HttpClientOptions setDecompressionSupported(boolean decompressionSupported) {
this.decompressionSupported = decompressionSupported;
return this;
}

Expand Down
52 changes: 12 additions & 40 deletions src/main/java/io/vertx/core/http/impl/Http1xClientConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,38 +13,17 @@

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoop;
import io.netty.handler.codec.DecoderResult;
import io.netty.handler.codec.compression.Brotli;
import io.netty.handler.codec.compression.ZlibCodecFactory;
import io.netty.handler.codec.http.DefaultHttpContent;
import io.netty.handler.codec.http.DefaultHttpHeaders;
import io.netty.handler.codec.http.DefaultHttpRequest;
import io.netty.handler.codec.http.DefaultLastHttpContent;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpContent;
import io.netty.handler.codec.http.HttpContentDecompressor;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpHeaderValues;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpObject;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpUtil;
import io.netty.handler.codec.http.LastHttpContent;
import io.netty.handler.codec.http.websocketx.WebSocket07FrameDecoder;
import io.netty.handler.codec.http.websocketx.WebSocket08FrameDecoder;
import io.netty.handler.codec.http.websocketx.WebSocket13FrameDecoder;
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker;
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker00;
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker07;
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker08;
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker13;
import io.netty.handler.codec.http.websocketx.WebSocketDecoderConfig;
import io.netty.handler.codec.http.*;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketFrameDecoder;
import io.netty.handler.codec.http.websocketx.WebSocketHandshakeException;
import io.netty.handler.codec.http.websocketx.WebSocketVersion;
import io.netty.handler.codec.http.websocketx.*;
import io.netty.handler.codec.http.websocketx.extensions.WebSocketClientExtensionHandler;
import io.netty.handler.codec.http.websocketx.extensions.WebSocketClientExtensionHandshaker;
import io.netty.handler.codec.http.websocketx.extensions.compression.DeflateFrameClientExtensionHandshaker;
Expand All @@ -54,22 +33,20 @@
import io.netty.util.ReferenceCountUtil;
import io.netty.util.concurrent.FutureListener;
import io.netty.util.concurrent.GenericFutureListener;
import io.vertx.core.Future;
import io.vertx.core.Handler;
import io.vertx.core.MultiMap;
import io.vertx.core.Promise;
import io.vertx.core.VertxException;
import io.vertx.core.*;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.buffer.impl.BufferInternal;
import io.vertx.core.http.HttpMethod;
import io.vertx.core.http.HttpVersion;
import io.vertx.core.http.*;
import io.vertx.core.http.impl.headers.HeadersAdaptor;
import io.vertx.core.impl.ContextInternal;
import io.vertx.core.impl.future.PromiseInternal;
import io.vertx.core.impl.logging.Logger;
import io.vertx.core.impl.logging.LoggerFactory;
import io.vertx.core.net.HostAndPort;
import io.vertx.core.net.impl.*;
import io.vertx.core.net.SocketAddress;
import io.vertx.core.net.impl.*;
import io.vertx.core.spi.metrics.ClientMetrics;
import io.vertx.core.spi.metrics.HttpClientMetrics;
import io.vertx.core.spi.tracing.SpanKind;
Expand All @@ -79,12 +56,7 @@
import io.vertx.core.streams.impl.InboundBuffer;

import java.net.URI;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.function.BiConsumer;

import static io.netty.handler.codec.http.websocketx.WebSocketVersion.*;
Expand Down Expand Up @@ -229,7 +201,7 @@ private HttpRequest createRequest(
if (chunked) {
HttpUtil.setTransferEncodingChunked(request, true);
}
if (options.isTryUseCompression() && request.headers().get(ACCEPT_ENCODING) == null) {
if (options.isDecompressionSupported() && request.headers().get(ACCEPT_ENCODING) == null) {
// if compression should be used but nothing is specified by the user support deflate and gzip.
CharSequence acceptEncoding = determineCompressionAcceptEncoding();
request.headers().set(ACCEPT_ENCODING, acceptEncoding);
Expand Down
10 changes: 3 additions & 7 deletions src/main/java/io/vertx/core/http/impl/Http2ClientConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,7 @@
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http2.DefaultHttp2Headers;
import io.netty.handler.codec.http2.Http2Error;
import io.netty.handler.codec.http2.Http2Exception;
import io.netty.handler.codec.http2.Http2Headers;
import io.netty.handler.codec.http2.Http2Stream;
import io.netty.handler.codec.http2.*;
import io.netty.handler.timeout.IdleStateEvent;
import io.vertx.core.*;
import io.vertx.core.buffer.Buffer;
Expand Down Expand Up @@ -572,7 +568,7 @@ private void writeHeaders(HttpRequestHead request, ByteBuf buf, boolean end, Str
headers.add(HttpUtils.toLowerCase(header.getKey()), header.getValue());
}
}
if (conn.client.options().isTryUseCompression() && headers.get(HttpHeaderNames.ACCEPT_ENCODING) == null) {
if (conn.client.options().isDecompressionSupported() && headers.get(HttpHeaderNames.ACCEPT_ENCODING) == null) {
headers.set(HttpHeaderNames.ACCEPT_ENCODING, Http1xClientConnection.determineCompressionAcceptEncoding());
}
try {
Expand Down Expand Up @@ -683,7 +679,7 @@ public static VertxHttp2ConnectionHandler<Http2ClientConnection> createHttp2Conn
HttpClientMetrics met = client.metrics();
VertxHttp2ConnectionHandler<Http2ClientConnection> handler = new VertxHttp2ConnectionHandlerBuilder<Http2ClientConnection>()
.server(false)
.useDecompression(client.options().isTryUseCompression())
.useDecompression(client.options().isDecompressionSupported())
.gracefulShutdownTimeoutMillis(0) // So client close tests don't hang 30 seconds - make this configurable later but requires HTTP/1 impl
.initialSettings(client.options().getInitialSettings())
.connectionFactory(connHandler -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.http.*;
import io.netty.handler.codec.http.HttpClientCodec;
import io.netty.handler.codec.http.HttpContentDecompressor;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.ssl.SslHandler;
import io.netty.handler.timeout.IdleStateHandler;
Expand Down Expand Up @@ -190,7 +191,7 @@ private void applyHttp1xConnectionOptions(ChannelPipeline pipeline) {
false,
!HttpHeaders.DISABLE_HTTP_HEADERS_VALIDATION,
options.getDecoderInitialBufferSize()));
if (options.isTryUseCompression()) {
if (options.isDecompressionSupported()) {
pipeline.addLast("inflater", new HttpContentDecompressor(false));
}
}
Expand Down
31 changes: 13 additions & 18 deletions src/test/java/io/vertx/core/http/Http1xTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,10 @@
import io.netty.handler.codec.TooLongFrameException;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.TooLongHttpHeaderException;
import io.vertx.core.*;
import io.vertx.core.Future;
import io.vertx.core.*;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.impl.Http1xOrH2CHandler;
import io.vertx.core.http.impl.Http1xServerConnection;
import io.vertx.core.http.impl.Http1xUpgradeToH2CHandler;
import io.vertx.core.http.impl.HttpServerImpl;
import io.vertx.core.http.impl.HttpServerRequestInternal;
import io.vertx.core.http.impl.HttpUtils;
import io.vertx.core.http.impl.*;
import io.vertx.core.impl.ContextInternal;
import io.vertx.core.impl.Utils;
import io.vertx.core.impl.VertxInternal;
Expand All @@ -34,11 +29,11 @@
import io.vertx.core.net.*;
import io.vertx.core.parsetools.RecordParser;
import io.vertx.core.streams.WriteStream;
import io.vertx.test.core.Repeat;
import io.vertx.test.core.CheckingSender;
import io.vertx.test.core.Repeat;
import io.vertx.test.core.TestUtils;
import io.vertx.test.tls.Cert;
import io.vertx.test.verticles.SimpleServer;
import io.vertx.test.core.TestUtils;
import org.junit.Assume;
import org.junit.Ignore;
import org.junit.Test;
Expand Down Expand Up @@ -190,9 +185,9 @@ public void testClientOptions() {
assertEquals(rand, options.getConnectTimeout());
assertIllegalArgumentException(() -> options.setConnectTimeout(-2));

assertFalse(options.isTryUseCompression());
assertEquals(options, options.setTryUseCompression(true));
assertEquals(true, options.isTryUseCompression());
assertFalse(options.isDecompressionSupported());
assertEquals(options, options.setDecompressionSupported(true));
assertEquals(true, options.isDecompressionSupported());

assertTrue(options.getEnabledCipherSuites().isEmpty());
assertEquals(options, options.addEnabledCipherSuite("foo"));
Expand Down Expand Up @@ -432,7 +427,7 @@ public void testCopyClientOptions() {
int http2MaxPoolSize = TestUtils.randomPositiveInt();
int http2MultiplexingLimit = TestUtils.randomPositiveInt();
int http2ConnectionWindowSize = TestUtils.randomPositiveInt();
boolean tryUseCompression = rand.nextBoolean();
boolean decompressionSupported = rand.nextBoolean();
HttpVersion protocolVersion = HttpVersion.HTTP_1_0;
int maxChunkSize = TestUtils.randomPositiveInt();
int maxInitialLineLength = TestUtils.randomPositiveInt();
Expand Down Expand Up @@ -470,7 +465,7 @@ public void testCopyClientOptions() {
options.setPipeliningLimit(pipeliningLimit);
options.setHttp2MultiplexingLimit(http2MultiplexingLimit);
options.setHttp2ConnectionWindowSize(http2ConnectionWindowSize);
options.setTryUseCompression(tryUseCompression);
options.setDecompressionSupported(decompressionSupported);
options.setProtocolVersion(protocolVersion);
options.setMaxChunkSize(maxChunkSize);
options.setMaxInitialLineLength(maxInitialLineLength);
Expand Down Expand Up @@ -521,7 +516,7 @@ public void testDefaultClientOptionsJson() {
assertEquals(def.getHttp2MultiplexingLimit(), json.getHttp2MultiplexingLimit());
assertEquals(def.getHttp2ConnectionWindowSize(), json.getHttp2ConnectionWindowSize());
assertEquals(def.isVerifyHost(), json.isVerifyHost());
assertEquals(def.isTryUseCompression(), json.isTryUseCompression());
assertEquals(def.isDecompressionSupported(), json.isDecompressionSupported());
assertEquals(def.isTrustAll(), json.isTrustAll());
assertEquals(def.getCrlPaths(), json.getCrlPaths());
assertEquals(def.getCrlValues(), json.getCrlValues());
Expand Down Expand Up @@ -579,7 +574,7 @@ public void testClientOptionsJson() {
int http2MaxPoolSize = TestUtils.randomPositiveInt();
int http2MultiplexingLimit = TestUtils.randomPositiveInt();
int http2ConnectionWindowSize = TestUtils.randomPositiveInt();
boolean tryUseCompression = rand.nextBoolean();
boolean decompressionSupported = rand.nextBoolean();
HttpVersion protocolVersion = HttpVersion.HTTP_1_1;
int maxChunkSize = TestUtils.randomPositiveInt();
int maxInitialLineLength = TestUtils.randomPositiveInt();
Expand Down Expand Up @@ -620,7 +615,7 @@ public void testClientOptionsJson() {
.put("http2MaxPoolSize", http2MaxPoolSize)
.put("http2MultiplexingLimit", http2MultiplexingLimit)
.put("http2ConnectionWindowSize", http2ConnectionWindowSize)
.put("tryUseCompression", tryUseCompression)
.put("decompressionSupported", decompressionSupported)
.put("protocolVersion", protocolVersion.name())
.put("maxChunkSize", maxChunkSize)
.put("maxInitialLineLength", maxInitialLineLength)
Expand Down Expand Up @@ -671,7 +666,7 @@ public void testClientOptionsJson() {
assertEquals(pipeliningLimit, options.getPipeliningLimit());
assertEquals(http2MultiplexingLimit, options.getHttp2MultiplexingLimit());
assertEquals(http2ConnectionWindowSize, options.getHttp2ConnectionWindowSize());
assertEquals(tryUseCompression, options.isTryUseCompression());
assertEquals(decompressionSupported, options.isDecompressionSupported());
assertEquals(protocolVersion, options.getProtocolVersion());
assertEquals(maxChunkSize, options.getMaxChunkSize());
assertEquals(maxInitialLineLength, options.getMaxInitialLineLength());
Expand Down
Loading

0 comments on commit f5e7003

Please sign in to comment.