I work with a rest API with token authentication, where some users have permissions to download the file, and some do not.
The problem is that some users without permission to download the file try to download (say a 1GB file), I get an error response only after all 1GB has been downloaded.
If I copy the request as a curl from the Chrome developer tools and send it through the terminal, it will work immediately.
I checked the curl command with a token from a user who has download permissions, it works as expected.
So, how is curl different from XHR?
Curl is synchronous, and XHR is not the default. I tried to make XHR synchronous, but it still needs to download the whole file before it gets a response.
function upload(file, url) {
var xhr = new XMLHttpRequest();
xhr.upload.key = xhr.key = file.key
xhr.upload.addEventListener("progress", updateProgress);
xhr.addEventListener("error", transferFailed);
xhr.addEventListener("abort", transferCanceled);
xhr.open("PUT", url);
xhr.setRequestHeader("Content-Type", "application/octet-stream");
xhr.setRequestHeader("X-Auth-Token", service.token.token);
xhr.addEventListener("readystatechange", function (e) {
if (this.readyState === 4 && this.status >= 200 && this.status < 300) {
transferComplete(e)
}
if (this.readyState === 4 && this.status === 0) {
transferFailed(e)
}
if (this.status >= 400) {
transferFailed(e)
}
});
xhr.send(file);
}
Here is the exact curl command, formatted for readability:
curl 'https://my-website.com/54321/my-filename.jpg'
-X PUT
-H 'Pragma: no-cache'
-H 'Origin: https://my-website.com'
-H 'Accept-Encoding: gzip, deflate, sdch, br'
-H 'Accept-Language: en-US,en;q=0.8'
-H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36'
-H 'Content-Type: application/octet-stream'
-H 'Accept: */*'
-H 'Cache-Control: no-cache'
-H 'X-Auth-Token: fsadgsdgs'
-H 'Referer: https://some-allowed-origin-referrer.com/'
-H 'Connection: keep-alive'
-H 'Content-Length: 86815'
-F "data=@/Users/satish/abc.jpg" --compressed --insecure
// Headers are split except for the token
curl 'https://my-website.com/54321/my-filename.jpg'
-X PUT
-H 'X-Auth-Token: fsadsdsdaf'
-F "data=@/Users/satish/abc.jpg"
--compressed --insecure
--- Update 02/21/2017 ---
To rule out any behavior on a particular API endpoint, I wrote a crude PHP script to test this observation, and this is still the case. Below is the PHP script I was trying to download.
<?php
$putdata = fopen( "php://input", "r" );
$file = fopen( "/Users/satish/Work/Development/htdocs/put-test/wow.jpg", "w" );
while ( $data = fread( $putdata, 1024 ) ) {
fwrite( $file, $data );
}
fclose( $file );
fclose( $putdata );
?>