Question

I'm doing a download in an android app and I need to get the content_length in order to display the percent downloaded.

The files reside on a server that my client has set up. On this server, the call to getContentLength() returns -1. Here are the headers:

THIS SERVERS HEADER DOESN'T WORK WITH urlConnection.getContentLength()


    $ curl --head "http://www.server0.com/ango/thefile.m4v"
    HTTP/1.1 200 OK
    Set-Cookie: JSESSIONID=A17762C6B65FD8D35840110F8628DE4B.V5; Path=/; HttpOnly
    X-ServedBy: web114
    Set-Cookie: SS_MID=7315b0cb-054c-4dd8-a013-c7163793becehfjcndg8; Domain=.tangoberretin.com; Expires=Thu, 13-Apr-2023 07:57:07 GMT; Path=/
    Pragma: cache
    Cache-Control: private,max-age=86400
    Last-Modified: Thu, 21 Feb 2013 06:28:24 GMT
    Content-Disposition: attachment; filename="thefile.m4v";
    Accept-Ranges: bytes
    Content-Range: bytes 0-6716578/6716579
    Content-Type: application/octet-stream;charset=UTF-8
    Content-Length: 6716579
    Date: Mon, 15 Apr 2013 07:57:07 GMT
    Server: SSWS
    Set-Cookie: WebPersCookie=Gn5lN9r2EIK+3eKz0tv/bEs4IJpcBzYg22jKvv/JD1eAA1N3D0pevaz3zuXOD3uTT950AQdstGRJgdE=; path=/

So I did a test and put the file on my own server (apache) and everything works fine. Here are those headers:

THIS SERVERS HEADER WORKS WITH urlConnection.getContentLength()


    $ curl --head "http://server1.net/wp-content/video/thefile.m4v"
    HTTP/1.1 200 OK
    Date: Mon, 15 Apr 2013 07:57:42 GMT
    Server: Apache
    Last-Modified: Sun, 14 Apr 2013 23:49:00 GMT
    Accept-Ranges: bytes
    Content-Length: 502365
    Content-Type: text/plain

So my question is what about the first case is causing the failure, and what can I do about it. Ideally I'd leave the files where they are.

*UPDATE**

I've printed out the headers from the android app, and apparently the server doesn't send the Content-Length for the android agent. I don't understand... :(

HTTP/1.1 200 OK
Accept-Ranges : 
bytes
Cache-Control : 
private,max-age=86400
Content-Disposition : 
attachment; filename="04Left_Turning_Check_Step.m4v";
Content-Range : 
bytes 0-7019776/7019777
Content-Type : 
application/octet-stream;charset=UTF-8
Date : 
Mon, 15 Apr 2013 08:39:06 GMT
Last-Modified : 
Wed, 02 Jan 2013 18:40:09 GMT
Pragma : 
cache
Server : 
SSWS
Set-Cookie : 
JSESSIONID=0B1D0CFFD975ED2736BFF7BBC23ACD96.V5; Path=/; HttpOnly
SS_MID=5a7bd305-4ac1-4d4d-98a3-67fa26c0db56hfje5d3d; Domain=.tangoberretin.com; Expires=Thu, 13-Apr-2023 08:39:06 GMT; Path=/
WebPersCookie=WIo8mRMTANAAke3GEsDOsONkGZoRcVvqpC4Am/pl/3WFB9hSEGH5DfGiDSKJDLc2nbZBpWFy3/Yfb3s=; path=/
Transfer-Encoding : 
chunked
Vary : 
Accept-Encoding
X-Android-Received-Millis : 
1366015147201
X-Android-Sent-Millis : 
1366015146842
X-ServedBy : 
web115
Was it helpful?

Solution

The key thing here is the following:

Transfer-Encoding : 
chunked

Chunked transfer encoding is described here.

In a nutshell chunked transfer encoding allows the server to send large content in a sequence of chunks without first having to determine the size of the content before sending. This allows the server to be much more efficient about how it loads the content from storage in order to send it the client.

I think that you need to speak with your client and tell him that if the server provides a valid, accurate Content-Length in the response headers then you can provide a progress report, but otherwise you cannot. Alternatively are you able to make an initial request to get information about the content (including the content size) and then make a second request for the content itself? If so, then you are able to provide a progress report.

OTHER TIPS

Old post, but the explanation by Mark helped point me to my solution.


Make a call to the url using the following call. This allows the content length to be returned without the server going into "Chunked" mode.

DefaultHttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
HttpResponse execute = client.execute(httpGet);
int contentLength = (int)execute.getEntity().getContentLength();

You can then remake the the request using URLConnection and use the already returned content length for calculations

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top