HttpUrlConnection setting Range in Android is ignored

Binoy Babu :

I'm trying get a 206 response from my server using Android.

Here's the code.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_splash);
    new AsyncTask<Void, Void, Void>() {
        @Override
        protected Void doInBackground(Void... params) {
            try {
                URL url = new URL("http://aviddapp.com/10mb.file");
                HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
                urlConnection.setRequestProperty("Range", "bytes=1-2");
                urlConnection.connect();

                System.out.println("Response Code: " + urlConnection.getResponseCode());
                System.out.println("Content-Length: " + urlConnection.getContentLength());
                Map<String, List<String>> map = urlConnection.getHeaderFields();
                for (Map.Entry<String, List<String>> entry : map.entrySet()) {
                    System.out.println("Key : " + entry.getKey() +
                            " ,Value : " + entry.getValue());
                }
                InputStream inputStream = urlConnection.getInputStream();
                long size = 0;

                while(inputStream.read() != -1 )
                    size++;

                System.out.println("Downloaded Size: " + size);

            }catch(MalformedURLException mue) {
                mue.printStackTrace();
            }catch(IOException ioe) {
                ioe.printStackTrace();
            }
            return null;
        }
    }.execute();
}

Here's the output:

I/System.out: Respnse Code: 200
I/System.out: Content-Length: -1
I/System.out: Key : null ,Value : [HTTP/1.1 200 OK]
I/System.out: Key : Accept-Ranges ,Value : [bytes]
I/System.out: Key : Cache-Control ,Value : [max-age=604800, public]
I/System.out: Key : Connection ,Value : [Keep-Alive]
I/System.out: Key : Date ,Value : [Tue, 04 Oct 2016 07:45:22 GMT]
I/System.out: Key : ETag ,Value : ["a00000-53e051f279680-gzip"]
I/System.out: Key : Expires ,Value : [Tue, 11 Oct 2016 07:45:22 GMT]
I/System.out: Key : Keep-Alive ,Value : [timeout=5, max=100]
I/System.out: Key : Last-Modified ,Value : [Tue, 04 Oct 2016 07:36:42 GMT]
I/System.out: Key : Server ,Value : [Apache/2.4.12 (Unix) OpenSSL/1.0.1e-fips mod_bwlimited/1.4]
I/System.out: Key : Transfer-Encoding ,Value : [chunked]
I/System.out: Key : Vary ,Value : [Accept-Encoding,User-Agent]
I/System.out: Key : X-Android-Received-Millis ,Value : [1475567127403]
I/System.out: Key : X-Android-Response-Source ,Value : [NETWORK 200]
I/System.out: Key : X-Android-Sent-Millis ,Value : [1475567127183]
I/System.out: Downloaded Size: 10485760

Now I'm doing the same thing is pure java.

public static void main(String... args) {
    try {
        URL url = new URL("http://aviddapp.com/10mb.file");
        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
        urlConnection.setRequestProperty("Range", "bytes=1-2");
        urlConnection.connect();

        System.out.println("Respnse Code: " + urlConnection.getResponseCode());
        System.out.println("Content-Length: " + urlConnection.getContentLength());
        Map<String, List<String>> map = urlConnection.getHeaderFields();
        for (Map.Entry<String, List<String>> entry : map.entrySet()) {
            System.out.println("Key : " + entry.getKey() +
                    " ,Value : " + entry.getValue());
        }
        InputStream inputStream = urlConnection.getInputStream();
        long size = 0;

        while(inputStream.read() != -1 )
            size++;

        System.out.println("Downloaded Size: " + size);

    }catch(MalformedURLException mue) {
        mue.printStackTrace();
    }catch(IOException ioe) {
        ioe.printStackTrace();
    }
}

Here's the output

Respnse Code: 206
Content-Length: 2
Key : Keep-Alive ,Value : [timeout=5, max=100]
Key : null ,Value : [HTTP/1.1 206 Partial Content]
Key : Server ,Value : [Apache/2.4.12 (Unix) OpenSSL/1.0.1e-fips mod_bwlimited/1.4]
Key : Content-Range ,Value : [bytes 1-2/10485760]
Key : Connection ,Value : [Keep-Alive]
Key : Last-Modified ,Value : [Tue, 04 Oct 2016 07:36:42 GMT]
Key : Date ,Value : [Tue, 04 Oct 2016 07:42:17 GMT]
Key : Accept-Ranges ,Value : [bytes]
Key : Cache-Control ,Value : [max-age=604800, public]
Key : ETag ,Value : ["a00000-53e051f279680"]
Key : Vary ,Value : [Accept-Encoding,User-Agent]
Key : Expires ,Value : [Tue, 11 Oct 2016 07:42:17 GMT]
Key : Content-Length ,Value : [2]
Downloaded Size: 2

As you can see I'm getting diffrent response codes in both cases. It seems like Android is not passing Range to the server maybe? What's happening here?

PS: I'm getting a 206 if the file size is 1mb.

Knossos :

I am relatively certain the error is not in the Android code.

It looks like the server might be delivering spurious results.

You can check with a third party tool (such as Postman) to determine the headers that web service is delivering.

My results using Postman. As you can see, it is delivering HTTP 200 (not 206). It is also not wending a capped Content-Length. If the server is yours, perhaps check that it is configured correctly. Also check your code with other servers.

Postman results

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=447943&siteId=1