Upgrade: how to parse a GZIP'd answer without Content-Encoding: gzip header

I am trying to process a server response that is gzip'd. The answer comes with a title.

Content-Type: application/x-gzip 

but has no title

 Content-Encoding: gzip 

If I add this header using a proxy, the answer will be parsed just fine. I have no control over the server, so I cannot add a header.

Can I get Retrofit to treat it as gzip content? Is there a better way? Server URL: http://crowdtorch.cms.s3.amazonaws.com/4474/Updates/update-1.xml

+5
source share
2 answers

There is a better way than reinventing the wheel. Just add the Content-Encoding header.

 .addNetworkInterceptor((Interceptor.Chain chain) -> { Request req = chain.request(); Headers.Builder headersBuilder = req.headers().newBuilder(); String credential = Credentials.basic(...); headersBuilder.set("Authorization", credential); Response res = chain.proceed(req.newBuilder().headers(headersBuilder.build()).build()); return res.newBuilder() .header("Content-Encoding", "gzip") .header("Content-Type", ""application/json") .build(); }) 

In fact, your code is a classic example of flaws in the use of internal code (for example, com.sun packages from JDK). RealResponseBody no longer has this constructor.

+1
source

I get it. The idea is to add a custom interceptor that will accept the unpacked response and unzip it β€œmanually” - to do the same thing that OkHttp will do automatically based on the Content-Encoding header, but without requiring this header.

similar to dis:

  OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder() .addInterceptor(new UnzippingInterceptor()); OkHttpClient client = clientBuilder.build(); 

And the interceptor is like dis:

 private class UnzippingInterceptor implements Interceptor { @Override public Response intercept(Chain chain) throws IOException { Response response = chain.proceed(chain.request()); return unzip(response); } } 

And the unzip function is like dis:

  // copied from okhttp3.internal.http.HttpEngine (because is private) private Response unzip(final Response response) throws IOException { if (response.body() == null) { return response; } GzipSource responseBody = new GzipSource(response.body().source()); Headers strippedHeaders = response.headers().newBuilder() .removeAll("Content-Encoding") .removeAll("Content-Length") .build(); return response.newBuilder() .headers(strippedHeaders) .body(new RealResponseBody(strippedHeaders, Okio.buffer(responseBody))) .build(); } 
+6
source

All Articles