Decode gzip body if not handled by okhttp (#21187)

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: https://github.com/facebook/react-native/pull/21187

Differential Revision: D9978889

Pulled By: hramos

fbshipit-source-id: b86791fb7d3157f325a0904225d2f63d166080d5
This commit is contained in:
Janic Duplessis 2018-09-20 14:55:08 -07:00 committed by Facebook Github Bot
parent 5068dfcad3
commit a6f47d46ca
1 changed files with 21 additions and 1 deletions

View File

@ -47,6 +47,8 @@ import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.ByteString;
import okio.GzipSource;
import okio.Okio;
/**
* Implements the XMLHttpRequest JavaScript interface.
@ -454,8 +456,26 @@ public final class NetworkingModule extends ReactContextBaseJavaModule {
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)) {