Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

getting error during file downloading #17

Closed
arindam2ghosh opened this issue Apr 6, 2018 · 5 comments
Closed

getting error during file downloading #17

arindam2ghosh opened this issue Apr 6, 2018 · 5 comments

Comments

@arindam2ghosh
Copy link

Getting error "java.io.IOException: The current offset on block-info isn't update correct, 1048577 != 8010121 on 2"

Download URL: http://43.229.84.125:1337/parse/files/QzxAOPDw8p3VmLecPW5b8oyKLYhIr1btsqRzw4fd/d575e21c9fc7558841da949ccec740e7_V07-NetballSG-13Mar-31Mar.mp4

Can you please rectify the issue

@arindam2ghosh arindam2ghosh changed the title getting error during download file getting error during file downloading Apr 6, 2018
@Jacksgong
Copy link
Collaborator

Jacksgong commented Apr 7, 2018

REASON

This URL response header can't meet HTTP 1.1 RFC 2616 and HTTP 1.1 RFC 7233 define, and violate it very far.

I debug okdownload on the sample project SingleActivity with replacing with your provide URL, and get the following log:

image

As you can see, the request and response to the trial connection before split several blocks to downloading:

  • Request header: {range=[bytes=0-0]}
  • Response header: code[206]{accept-ranges=[bytes], access-control-allow-headers=[X-Parse-Master-Key, X-Parse-REST-API-Key, X-Parse-Javascript-Key, X-Parse-Application-Id, X-Parse-Client-Version, X-Parse-Session-Token, X-Requested-With, X-Parse-Revocable-Session, Content-Type], access-control-allow-methods=[GET,PUT,POST,DELETE,OPTIONS], access-control-allow-origin=[*], connection=[keep-alive], content-length=[1048577], content-range=[bytes 0-1048576/24030363], content-type=[video/mp4], date=[Sat, 07 Apr 2018 01:41:54 GMT], x-powered-by=[Express]}

So as page 5 of RFC 7233 said:

The first and last bytes only (bytes 0 and 9999):

        bytes=0-0,-1

So, when the request with {range=[bytes=0-0]}, the response would with content-length=[1] what is only the first-byte length, so in here we can't get the instance length from content-length because on the define with the request it is not the instance length, But on the response of your provide URL the response header is content-length=[1048577] what is very wrong, and we can't use it, as define it is not the instance length. Then as the RFC 2616 defined, the content-range would tell us the right instance length with content-range=[unit range/instant-length], and with your URL we got the instance length from content-range=[bytes 0-1048576/24030363] is 24030363, and then we use this instance length to split into several blocks to download this resources, but on the block two the input-stream from response body only provide 1048577 bytes data, so you occur such problem.

So I guess, the right response to your URL would contain content-length=[1], content-range=[bytes 0-0/1048576], but your response is content-length=[1048577], content-range=[bytes 0-1048576/24030363] , as you can see: none of them are correct, and why don't we use content-length of it directly? because as the RFC define, it is not the instance length, even if you don't provide content-range field we also need use HEAD method request to get the certain content-length as the instance length.

Appendix

Why need to download with split several blocks?

Because of the most resource, one connection doesn't provide enough speed input-stream for it, so we split several blocks of it and use each independent connection to touch each block input-stream simultaneously to enhance the download speed.

Why there is a trial connection before split several blocks to downloading?

Because of before split-block, we need to know how many blocks do we need to split, then we need to know whether the resource support split block or not and the instance length of resource, and use GET method request with {range=0-0} or HEAD method request for the trial connection is just for avoiding cache useless data on TCP receive window.

@arindam2ghosh
Copy link
Author

Thanks for your response.
URL is not in my control. Which API should I use from your library?

@Jacksgong Jacksgong added this to the 1.0.1 milestone Apr 7, 2018
@Jacksgong
Copy link
Collaborator

I think this resource has something special, it is like chunked resource but it response content-length and content-range without transfer-encoding=[chunked].

I tried the Url without {range=0-0} and just raise an HTTP HEAD request( without any addition request header), the response is: content-length=[24030363]. So the instance-length is 24030363.

REAL PROBLEM

As the Request-Range define on the RFC 7233:

   Additional examples, assuming a representation of length 10000:

   o  The final 500 bytes (byte offsets 9500-9999, inclusive):

        bytes=-500

   Or:

        bytes=9500-

We think such as 9500- is just means from 9500 to end, but for the URL you provide it means 9500-1058075 (9500+1048576-1), so I tried using especially range even for the last block the download is correct.

So consider this case we will add exactly range even for the last block to fix such problem on 1.0.1.

@Jacksgong
Copy link
Collaborator

Now, You can use v1.0.1-SNAPSHOT which handled this issue, and final release would be on v1.0.1.

@arindam2ghosh
Copy link
Author

Thank you very much. Its working perfectly now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants