Skip to content

Commit

Permalink
Decode gzip body if not handled by okhttp (#21187)
Browse files Browse the repository at this point in the history
Summary:
When looking at enabling gzip content encoding on Android I stumbled on this old issue where the body content is not decoded. It happens because okhttp only handles gzip decoding if the user does NOT provide an accept-encoding header. This is pretty confusing because on iOS we need to pass the header manually if we want to receive a gzipped response. I think it makes sense to handle the decoding no matter what.

See the comment in code for more details.

Fixed #5297
Pull Request resolved: #21187

Differential Revision: D9978889

Pulled By: hramos

fbshipit-source-id: b86791fb7d3157f325a0904225d2f63d166080d5
  • Loading branch information
janicduplessis authored and facebook-github-bot committed Sep 20, 2018
1 parent 5068dfc commit a6f47d4
Showing 1 changed file with 21 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.ByteString;
import okio.GzipSource;
import okio.Okio;

/**
* Implements the XMLHttpRequest JavaScript interface.
Expand Down Expand Up @@ -454,8 +456,26 @@ public void onResponse(Call call, Response response) throws IOException {
translateHeaders(response.headers()),
response.request().url().toString());

ResponseBody responseBody = response.body();
try {
// OkHttp implements something called transparent gzip, which mean that it will
// automatically add the Accept-Encoding gzip header and handle decoding internally.
// The issue is that it won't handle decoding if the user provides a Accept-Encoding
// header. This is also undesirable considering that iOS does handle the decoding even
// when the header is provided. To make sure this works in all cases, handle gzip body
// here also. This works fine since OKHttp will remove the Content-Encoding header if
// it used transparent gzip.
// See https://github.com/square/okhttp/blob/5b37cda9e00626f43acf354df145fd452c3031f1/okhttp/src/main/java/okhttp3/internal/http/BridgeInterceptor.java#L76-L111
ResponseBody responseBody = response.body();
if ("gzip".equalsIgnoreCase(response.header("Content-Encoding")) &&
responseBody != null) {
GzipSource gzipSource = new GzipSource(responseBody.source());
String contentType = response.header("Content-Type");
responseBody = ResponseBody.create(
contentType != null ? MediaType.parse(contentType) : null,
-1L,
Okio.buffer(gzipSource));
}

// Check if a handler is registered
for (ResponseHandler handler : mResponseHandlers) {
if (handler.supports(responseType)) {
Expand Down

0 comments on commit a6f47d4

Please sign in to comment.