HttpURLConnection not decompressing Gzip

2019-06-22 13:12发布

I'm trying to use HttpURLConnection on Gingerbread+ Android devices and am having trouble with the gzip encoding. According to the documentation

"In Gingerbread, we added transparent response compression. HttpURLConnection will automatically add this header to outgoing requests, and handle the corresponding response:

Accept-Encoding: gzip"

The problem is that this is not actually happening. The Accept-Encoding: gzip header is not getting added at all. If I add it manually, I would then expect the decompressing part of it to work by connection.openInputStream() to automatically return a GZipInputStream but it just returns a plain InputStream.

Has anyone experienced this? I havent seen any posts of this happening so its very odd. The project is compiled against API 17 so that shouldnt be a problem and the device is running 4.3.

Thanks.

4条回答
男人必须洒脱
2楼-- · 2019-06-22 13:43

I had the same problem and it was related to HTTPS. If you call:

URL url = new URL("https://www.example.com");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();

you actually get an instance of HttpsURLConnection (a subclass of HttpURLConnection) that does NOT handle gzip automatically. In those cases you can:

conn.setRequestProperty("Accept-Encoding", "gzip");
...
InputStream inStream = new GZIPInputStream(conn.getInputStream());
查看更多
ゆ 、 Hurt°
3楼-- · 2019-06-22 13:57

Since Android Gingerbread (http) and ICS (http + https), when you use Http(s)URLConnection, Android adds the Accept-Encoding: gzip header automatically, but only if you didn't add it yourself first.

In that case, if the server returns gzip-encoded content, you will automatically get a GZIPInputStream and the Content-Encoding: gzip header will be removed from the response. That's why it's called transparent: so the client cannot tell the difference between compressed or uncompressed responses by looking at the stream content or the headers.

If you add the Accept-Encoding: gzip header manually yourself however, then transparent gzip handling is disabled for that request and if the server returns gzip-compressed content, then you need to look for the Content-Encoding: gzip header and create the GZIPInputStream yourself to decompress content.

查看更多
放荡不羁爱自由
4楼-- · 2019-06-22 14:05

I tested with a few of my devices and HttpURLConnection is adding Accept-Encoding: gzip to the headers.

Have you tried configuring Fiddler for your Android devices to verify http headers? Perhaps your server does not support compression.

查看更多
Emotional °昔
5楼-- · 2019-06-22 14:07

I've experienced this myself and also found that it worked if I added the header and used GZIPInputStream manually. However, we were setting our headers manually (had a custom header we had to add).

The Android documentation says "By default, this implementation of HttpURLConnection requests that servers use gzip compression." So I'm guessing that the default only applies if you don't manually set the headers.

查看更多
登录 后发表回答