diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkingModule.java b/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkingModule.java index 249fc18b3..9b335a4d0 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkingModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkingModule.java @@ -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)) {