I've a HTTP communication to a webserver requesting JSON data. I'd like compress this data stream with Content-Encoding: gzip
. Is there a way I can set Accept-Encoding: gzip
in my HttpClient? The search for gzip
in the Android References doesn't show up anything related to HTTP, as you can see here.
Asked
Active
Viewed 6.1k times
110

znq
- 44,613
- 41
- 116
- 144
-
1[Android-WebRequest](https://github.com/delight-im/Android-WebRequest) supports GZIP and uncompressed responses automatically, e.g. with `new WebRequest().get().to("http://www.example.com/").askForGzip(true).executeSync()`. Specifically, the method [parseResponse(...)](https://github.com/delight-im/Android-WebRequest/blob/master/src/im/delight/android/webrequest/WebRequest.java) should be what you're looking for. – caw Jun 30 '14 at 16:47
5 Answers
175
You should use http headers to indicate a connection can accept gzip encoded data, e.g:
HttpUriRequest request = new HttpGet(url);
request.addHeader("Accept-Encoding", "gzip");
// ...
httpClient.execute(request);
Check response for content encoding:
InputStream instream = response.getEntity().getContent();
Header contentEncoding = response.getFirstHeader("Content-Encoding");
if (contentEncoding != null && contentEncoding.getValue().equalsIgnoreCase("gzip")) {
instream = new GZIPInputStream(instream);
}

Bakhtiyor
- 4,356
- 2
- 23
- 15
-
7That is a great and very helpful answer with all the details I needed. Thanks a lot. One comment: instead of addHeader I used setHeader. From what I understand this overwrites the existing "Accept-Encoding" if there is one. Not sure which approach is the right/better one. To overwrite an existing header to make sure it has the right value, or to add it in case that there can be other Accept-Encoding headers in parallel. – znq Oct 16 '09 at 08:04
-
-
7this does not gzip the request, it only tells the server that you can accept a gzip'd response. – Jeffrey Blattman May 04 '11 at 17:47
-
1For anyone also having trouble to get this up and running for google services here are two issues which took me quite some time to find out: (1) some google services require the user agent string provided by the client to contain the string `gzip` to _really_ enable gzip compression. (2) keep in mind that the server may not gzip the response if it is too small... – sven Jun 17 '11 at 07:30
-
My problem is that the gzip header is nowhere to be seen. I am using Wireshark to sniff the network on the server side, and I see no trace of the "gzip" header that I added in android... – Ted Feb 16 '14 at 14:21
-
@znq Android itself uses `addHeader(...)` in `AndroidHttpClient`'s method `modifyRequestToAcceptGzipResponse(...)` so you should probably use that. – caw Jun 30 '14 at 15:30
33
If you're using API level 8 or above there's AndroidHttpClient.
It has helper methods like:
public static InputStream getUngzippedContent (HttpEntity entity)
and
public static void modifyRequestToAcceptGzipResponse (HttpRequest request)
leading to much more succinct code:
AndroidHttpClient.modifyRequestToAcceptGzipResponse( request );
HttpResponse response = client.execute( request );
InputStream inputStream = AndroidHttpClient.getUngzippedContent( response.getEntity() );

Volker Neumann
- 476
- 5
- 6
-
Nice tip the modifyRequest & getUngzipped, also, I needed to copy EntityUtils.toString(HttpEntity) to parse the ungzipeed stream as String – Marcos Vasconcelos Jul 25 '13 at 23:17
-
1
13
I think the sample of code at this link is more interesting: ClientGZipContentCompression.java
They are using HttpRequestInterceptor and HttpResponseInterceptor
Sample for request:
httpclient.addRequestInterceptor(new HttpRequestInterceptor() {
public void process(
final HttpRequest request,
final HttpContext context) throws HttpException, IOException {
if (!request.containsHeader("Accept-Encoding")) {
request.addHeader("Accept-Encoding", "gzip");
}
}
});
Sample for answer:
httpclient.addResponseInterceptor(new HttpResponseInterceptor() {
public void process(
final HttpResponse response,
final HttpContext context) throws HttpException, IOException {
HttpEntity entity = response.getEntity();
Header ceheader = entity.getContentEncoding();
if (ceheader != null) {
HeaderElement[] codecs = ceheader.getElements();
for (int i = 0; i < codecs.length; i++) {
if (codecs[i].getName().equalsIgnoreCase("gzip")) {
response.setEntity(
new GzipDecompressingEntity(response.getEntity()));
return;
}
}
}
}
});

Niqo
- 1,072
- 10
- 20
-
1
-
3@codingcrow Here's what you're looking for : _In this particular case HTTP client is made capable of transparent content GZIP compression by adding two protocol interceptors: a request interceptor that adds 'Accept-Encoding: gzip' header to all outgoing requests and a response interceptor that automatically expands compressed response entities by wrapping them with a uncompressing decorator class. The use of protocol interceptors makes content compression completely transparent to the consumer of the HttpClient interface._ – clauziere Dec 03 '12 at 21:16
-
[Source](http://hc.apache.org/httpcomponents-client-ga/httpclient/examples/org/apache/http/examples/client/ClientGZipContentCompression.java) – clauziere Dec 03 '12 at 21:16
-
1
I haven't used GZip, but I would assume that you should use the input stream from your HttpURLConnection
or HttpResponse
as GZIPInputStream
, and not some specific other class.

Dimitar Dimitrov
- 16,032
- 5
- 53
- 55
-
HTTPURLConnection has gzip turned on by default. You just need to make sure your web server can return gzip pages. http://developer.android.com/reference/java/net/HttpURLConnection.html I was able to return gzip pages from php by using ob_start("ob_gzhandler"); – metric152 Aug 13 '12 at 18:35
-
0
In my case it was like this:
URLConnection conn = ...;
InputStream instream = conn.getInputStream();
String encodingHeader = conn.getHeaderField("Content-Encoding");
if (encodingHeader != null && encodingHeader.toLowerCase().contains("gzip"))
{
instream = new GZIPInputStream(instream);
}

kospol
- 377
- 3
- 9