35

The REST service I want to consume answers as a gzipped encoded JSON. It provides the Content-Encoding: gzip, but my OkHttp does not encode it to readable text, so the JSON converter throws an exception.

---> HTTP GET https://rapla.dhbw-karlsruhe.de/rapla/events?resources=%5B%27rc85dbd6-7d98-4eb7-a7f6-b867213c73d8%27%5D&start=2015-09-01&end=2015-12-31
Accept-Encoding: gzip, deflate
Accept: application/json
Authorization: *not posted*
Content-Type: application/json;charset=utf-8
---> END HTTP (no body)
<--- HTTP 200 https://rapla.dhbw-karlsruhe.de/rapla/events?resources=%5B%27rc85dbd6-7d98-4eb7-a7f6-b867213c73d8%27%5D&start=2015-09-01&end=2015-12-31 (13ms)
Date: Tue, 24 Nov 2015 09:09:10 GMT
Server: Jetty(9.2.2.v20140723)
Expires: Tue, 01 Jan 1980 00:00:00 GMT
Pragma: no-cache
Cache-Control: no-cache, must-revalidate
Content-Encoding: gzip
Content-Type: application/json; charset=utf-8
Content-Disposition: attachment
Content-Length: 9684
Via: 1.1 rapla.dhbw-karlsruhe.de
Keep-Alive: timeout=5, max=99
Connection: Keep-Alive
OkHttp-Selected-Protocol: http/1.1
OkHttp-Sent-Millis: 1448356149978
OkHttp-Received-Millis: 1448356149991

����WK�{��J�`k�_��Z����E�p�>3m�WMa�ג�ҵ�p�0��<��
... skipped rest of the body
E��>���S���n 
<--- END HTTP (9684-byte body)

According to Jake Whartons comment the Content-Encoding: gzip Header should tell OkHttp to decode the body.

The code for creating the RestAdapter is:

final RestAdapter adapter = new RestAdapter.Builder()
    .setEndpoint(baseUrl)
    .setClient(new OkClient(new OkHttpClient()))
    .setConverter(new GsonConverter(gson))
    .setLogLevel(RestAdapter.LogLevel.FULL)
    .build();
service = adapter.create(RaplaService.class);

The gradle dependencies are:

compile 'com.squareup.retrofit:retrofit:1.9.0'
compile 'com.squareup.okhttp:okhttp:2.6.0'

The method in my ServiceInterface:

@Headers({
        "Accept-Encoding: gzip, deflate",
        "Content-Type: application/json;charset=utf-8",
        "Accept: application/json"
})
@GET("/events")
List<Event> getEvents(@Header("Authorization") String token, @Query("resources") String resources, @Query("start") String start, @Query("end") String end);
Community
  • 1
  • 1
Simon Tenbeitel
  • 835
  • 1
  • 8
  • 20

2 Answers2

66

Replace this:

@Headers({
    "Accept-Encoding: gzip, deflate",
    "Content-Type: application/json;charset=utf-8",
    "Accept: application/json"
})

With this:

@Headers({
    "Content-Type: application/json;charset=utf-8",
    "Accept: application/json"
})

When you provide your own Accept-Encoding header you’re instructing OkHttp that you want to do your own decompression. By omitting it, OkHttp will take care of both adding the header and the decompression.

Jesse Wilson
  • 39,078
  • 8
  • 121
  • 128
  • 2
    But will i be getting compressed response if i omitted `"Accept-Encoding: gzip, deflate",` ? – Hakim Apr 20 '16 at 15:16
  • 5
    Yes. If you omit the Accept-Encoding header, OkHttp will automatically add its own and decompress on your behalf. – Jesse Wilson Apr 21 '16 at 07:37
  • 2
    I just encounter a similar problem on Retrofit 2 as well. But in my case I added `.header("Accept-Encoding", "gzip, deflate")` to the request builder. – chubao Jun 22 '16 at 09:36
  • 5
    Only add an Accept-Encoding header if you want to disable OkHttp’s automatic gzip feature. – Jesse Wilson Jun 22 '16 at 11:33
  • 2
    @DavidCheung I didn't have to add this. As per Jesse Wilson, it looks like OkHttp adds this header automatically and if the server returns a gzip data stream, it's smart enough to know that and decompress it. If the server doesn't response to the gzip request in the header, it doesn't try to decompress it. Clever. – Joshua Pinter Feb 20 '18 at 04:29
  • @JesseWilson I am facing problem using Gzip with retorfit. https://stackoverflow.com/questions/52661900/unable-to-parse-gzip-response-from-server-using-retrofit-android?noredirect=1#comment92254234_52661900 Please tell me where I am doing wrong? – Aman Srivastava Oct 08 '18 at 06:55
  • Removing Accept-Encoding from @Headers doesn't actually remove it - OkHttp still adds it, with "gzip, deflate, br". I'm not sure how to remove it completely. – alekop Dec 03 '20 at 18:27
  • Either add `Accept-Encoding: identity` or use a network interceptor to remove the header on the outbound request. – Jesse Wilson Dec 04 '20 at 21:06
  • in my case, the server only send me gzip if i send Accept-Encoding from the request.. – Erlang Parasu Jan 05 '21 at 02:25
-2

In My case I commented client(OkHttpClient client) following is the snippet code

Retrofit.Builder()
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .addConverterFactory(GsonConverterFactory.create())
            .baseUrl(BuildConfig.END_POINT)
            //.client(client)
            .build()

Because I am using LoggingInterceptor i think he will not take care everything related to gzip

Mohd Qasim
  • 896
  • 9
  • 20