Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java HttpURLConnection VS Android HttpURLConnection

I have this simple code that run on a Windows VM:

URL url = new URL("http:xxx.xxx.xxx.xxx/api/cities.json");
HttpURLConnection connexion = (HttpURLConnection) url.openConnection();
connexion.setRequestMethod("GET");

System.out.println("response " + connexion.getResponseCode());
connexion.connect();

InputStream is = connexion.getInputStream();

for (String header : connexion.getHeaderFields().keySet()) {
    System.out.println(header + ":" + connexion.getHeaderField(header));
}

Giving these headers

response 200
null:HTTP/1.1 200 OK
X-Frame-Options:SAMEORIGIN
Access-Control-Allow-Origin:*
Vary:Accept-Encoding
Date:Sun, 23 Mar 2014 03:00:06 GMT
Content-Length:1894
Connection:keep-alive
Content-Type:application/json
Server:nginx

And the exact same code on Android giving theses headers

03-22 23:10:35.405: I/System.out(23707): null:HTTP/1.1 200 OK
03-22 23:10:35.405: I/System.out(23707): Access-Control-Allow-Origin:*
03-22 23:10:35.405: I/System.out(23707): Connection:keep-alive
03-22 23:10:35.405: I/System.out(23707): Content-Type:application/json
03-22 23:10:35.405: I/System.out(23707): Date:Sun, 23 Mar 2014 03:10:35 GMT
03-22 23:10:35.405: I/System.out(23707): Server:nginx
03-22 23:10:35.405: I/System.out(23707): Vary:Accept-Encoding
03-22 23:10:35.405: I/System.out(23707): X-Android-Received-Millis:1395544235409
03-22 23:10:35.405: I/System.out(23707): X-Android-Response-Source:NETWORK 200
03-22 23:10:35.405: I/System.out(23707): X-Android-Selected-Transport:http/1.1
03-22 23:10:35.405: I/System.out(23707): X-Android-Sent-Millis:1395544235363
03-22 23:10:35.405: I/System.out(23707): X-Frame-Options:SAMEORIGIN

I just cant find the content-length header anymore. Im I missing something ?

like image 410
geh Avatar asked Mar 23 '14 03:03

geh


1 Answers

Android HttpURLConnection is doing some magic transparently for you like caching and gzip-handling.

So if you don't set Accept-Encoding: identity, HUC sets Accept-Encoding: gzip,deflate. And since nginx is an intelligent nice thing, it might deliver your response gzip encoded. You didn't tell HUC to give the response as gzipped back to you, but it decompresses that response for you and drops the header since this was misleading.

You can see this as a powerful feature to save bandwidth and radio power consumption without Android programmers having to deal with gzip or deflate encoding.

If you just stream the response to your JSON-parser, you will get the uncompressed data in the correct size, though without knowing size in advance.

You could verify what I said by running wireshark or tcpdump server-side, or if you have a rooted Android device, there are ways to do this client-side as well.

like image 189
hgoebl Avatar answered Oct 23 '22 14:10

hgoebl