2

This question was asked for Apache Commons HttpClient, however I'm using the async client HttpAsyncClient.

Content decompression (gzip) does not work out of the box.

I tried to configure it with:

httpClientAsync = HttpAsyncClients.custom()
            .setMaxConnPerRoute(100)
            .setMaxConnTotal(200)
            // Enable response content encoding (gzip)
            //
            // NOTE: Does not work for some reason
            .addInterceptorLast(ResponseContentEncoding())

Which I copied from HttpClientBuilder, but it doesn't work.

Any ideas?

ok2c
  • 26,450
  • 5
  • 63
  • 71
Nikola Mihajlović
  • 2,286
  • 2
  • 19
  • 23

1 Answers1

2

The use of addInterceptorLast and addInterceptorFirst has no effect.
asyncHttpClient.execute() will create a BasicAsyncResponseConsumer by default.
This BasicAsyncResponseConsumer will copy the original ContentDecoder into the buffer, resulting in DecompressingEntity.getContent() is never called.

org.apache.http.impl.nio.client.CloseableHttpAsyncClient#execute()

    public Future<HttpResponse> execute(
            final HttpHost target, final HttpRequest request, final HttpContext context,
            final FutureCallback<HttpResponse> callback) {
        return execute(
                HttpAsyncMethods.create(target, request),
                HttpAsyncMethods.createConsumer(), // BasicAsyncResponseConsumer
                context, callback);
    }

org.apache.http.nio.protocol.BasicAsyncResponseConsumer#onContentReceived

    protected void onContentReceived(
            final ContentDecoder decoder, final IOControl ioControl) throws IOException {
        Asserts.notNull(this.buf, "Content buffer");
        this.buf.consumeContent(decoder);
    }

My solution is to manually call ResponseContentEncoding.process(resp, context) in the callback to reset the HttpEntity.

private static final ResponseContentEncoding responseContentEncoding = new ResponseContentEncoding();

HttpClientContext hcc = HttpClientContext.create();
asyncHttpClient.execute(bidreq, hcc, new FutureCallback<HttpResponse>() {
    @Override
    public void completed(HttpResponse result) {
        HttpEntity entity = null;
        String content = null;
        try {
            responseContentEncoding.process(result, hcc);
            entity = result.getEntity();
            if (entity != null) {
                content = EntityUtils.toString(entity, UTF_8);
                log.info(content);
            }
        } catch (Exception e) {
            log.error("error", e);
        } finally {
            EntityUtils.consumeQuietly(entity);
        }
    }

    @Override
    public void failed(Exception ex) {
        log.error("failed", ex);
    }

    @Override
    public void cancelled() { }
});
Wayne
  • 31
  • 4