Skip to content

Incompatibility with Apache Http Client 5.6Β #1134

@wilkinsona

Description

@wilkinsona

Java API client version

9.2.3

Java version

17

Elasticsearch Version

N/A

Problem description

Apache Http Client 5.6 has changed how it handles the Content-Encoding header. It now leaves it in place on the HTTP response. This leads to a double decoding attempt which fails:

Caused by: java.lang.RuntimeException: node: http://localhost:49627/, status: 200, [es/indices.create] Failed to decode response
	at org.springframework.data.elasticsearch.client.elc.ElasticsearchExceptionTranslator.translateException(ElasticsearchExceptionTranslator.java:69)
	... 39 common frames omitted
Caused by: co.elastic.clients.transport.TransportException: node: http://localhost:49627/, status: 200, [es/indices.create] Failed to decode response
	at co.elastic.clients.transport.ElasticsearchTransportBase.decodeTransportResponse(ElasticsearchTransportBase.java:435)
	at co.elastic.clients.transport.ElasticsearchTransportBase.getApiResponse(ElasticsearchTransportBase.java:391)
	at co.elastic.clients.transport.ElasticsearchTransportBase.lambda$performRequestAsync$0(ElasticsearchTransportBase.java:219)
	... 30 common frames omitted
Caused by: jakarta.json.JsonException: Jackson exception
	at co.elastic.clients.json.jackson.Jackson3Utils.convertException(Jackson3Utils.java:27)
	at co.elastic.clients.json.jackson.Jackson3JsonProvider$ParserFactory.createParser(Jackson3JsonProvider.java:118)
	at co.elastic.clients.json.jackson.Jackson3JsonProvider.createParser(Jackson3JsonProvider.java:93)
	at co.elastic.clients.transport.ElasticsearchTransportBase.decodeTransportResponse(ElasticsearchTransportBase.java:428)
	... 32 common frames omitted
Caused by: tools.jackson.core.exc.JacksonIOException: Not in GZIP format
 at [No location information]
	at tools.jackson.core.exc.JacksonIOException.construct(JacksonIOException.java:39)
	at tools.jackson.core.json.ByteSourceJsonBootstrapper._wrapIOFailure(ByteSourceJsonBootstrapper.java:460)
	at tools.jackson.core.json.ByteSourceJsonBootstrapper.ensureLoaded(ByteSourceJsonBootstrapper.java:434)
	at tools.jackson.core.json.ByteSourceJsonBootstrapper.detectEncoding(ByteSourceJsonBootstrapper.java:143)
	at tools.jackson.core.json.ByteSourceJsonBootstrapper.constructParser(ByteSourceJsonBootstrapper.java:291)
	at tools.jackson.core.json.JsonFactory._createParser(JsonFactory.java:391)
	at tools.jackson.core.base.TextualTSFactory.createParser(TextualTSFactory.java:116)
	at tools.jackson.databind.ObjectMapper.createParser(ObjectMapper.java:624)
	at co.elastic.clients.json.jackson.Jackson3JsonProvider$ParserFactory.createParser(Jackson3JsonProvider.java:116)
	... 34 common frames omitted
Caused by: java.util.zip.ZipException: Not in GZIP format
	at java.base/java.util.zip.GZIPInputStream.readHeader(GZIPInputStream.java:165)
	at java.base/java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:79)
	at java.base/java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:91)
	at org.apache.hc.client5.http.entity.GZIPInputStreamFactory.create(GZIPInputStreamFactory.java:72)
	at org.apache.hc.client5.http.entity.LazyDecompressingInputStream.initWrapper(LazyDecompressingInputStream.java:56)
	at org.apache.hc.client5.http.entity.LazyDecompressingInputStream.read(LazyDecompressingInputStream.java:73)
	at tools.jackson.core.json.ByteSourceJsonBootstrapper.ensureLoaded(ByteSourceJsonBootstrapper.java:432)
	... 40 common frames omitted

The problem can be worked around with an HTTP client config callback that disables (de)compression support on the HTTP client but it would be nice if it worked out of the box.

Rather than looking at the headers of the response (which now match what the server sent), I believe the intent is that client-side code should look at the HTTP entity instead. In terms of Rest5Client, that would look something like this:

         HttpEntity entity = httpResponse.getEntity();
         if (entity != null) {
-            Header encoding = null;
-            try {
-                encoding = httpResponse.getHeader(CONTENT_ENCODING);
-            } catch (ProtocolException e) {
-                throw new IOException("Couldn't retrieve content encoding: " + e);
-            }
-            if (encoding != null && "gzip".equals(encoding.getValue())) {
+            if ("gzip".equals(entity.getContentEncoding())) {
                 // Decompress and cleanup response headers
                 httpResponse.setEntity(new GzipDecompressingEntity(entity));

I believe a change along these lines will allow things to work out of the box with 5.6, while also remaining compatible with earlier 5.x releases. @ok2c, if you have a minute, please correct me if I've got this wrong.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions