Jonathan Rainville Jonathan Rainville - 4 months ago 21
Node.js Question

Using Autodesk's Forge OSS, I can upload to a bucket, but the body of the download is empty

I'm using Autodesk's Forge Object Storage Service and while I can upload my file to my bucket, when I try to download it, the body comes out empty. However, when using

Head
, the Data-Size is correct.

Here is my upload (note that I'm using the signed url upload API):

var url = uploadOptions.url;

var fileReader = new FileReader();
// UploadOptions.Body contains a Blob
fileReader.readAsBinaryString(uploadOptions.Body);
fileReader.onloadend = function (e) {
var xhr = new XMLHttpRequest();
var lastLoadedValue = 0;
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && (xhr.status === 200 || xhr.status === 201)) {
console.log('UPLOAD FINISHED:', xhr.responseText);
callback();
}
};
xhr.open("PUT", url, true);
xhr.withCredentials = true;
// uploadOptions.ContentType = 'application/octet-stream'
xhr.setRequestHeader('Content-Type', uploadOptions.ContentType);
xhr.send(e.target.result);


Here is my download:


superagent
.get(_autodesk_api_baseurl
+ baseUrl
+ downloadOptions.bucket
+ '/objects/'
+ encodeURIComponent(downloadOptions.key))
.set('Authorization', 'Bearer '
+ token.access_token)
.query({'response-content-type': 'application/octet-stream'})
.end(function (err, resp) {
if (typeof callback === 'function') {
// All works fine
callback(undefined, resp);
}
});


And then, in the callback, I print my response and the body is empty.
I even wrote the JSON encoded response to a file to get this:

{
"req": {
"method": "GET",
"url": "https://developer.api.autodesk.com/oss/v2/buckets/storage.vcs.prod.mevsg.autodesk.com/objects/assets%2FNT5NR9KJU2PH%2Fea02ec77505f2ea2defac93fe231764f2916e4d1aeaac7d92945a08a0086c60667369431361d5aa426d4cccca49b9e4c7cb70bc6ebf700258a3cb37617eacfa0"
},
"header": {
"access-control-allow-credentials": "true",
"access-control-allow-headers": "Authorization, Accept-Encoding, Range, Content-Type",
"access-control-allow-methods": "GET",
"access-control-allow-origin": "*",
"content-disposition": "attachment; filename=\"ea02ec77505f2ea2defac93fe231764f2916e4d1aeaac7d92945a08a0086c60667369431361d5aa426d4cccca49b9e4c7cb70bc6ebf700258a3cb37617eacfa0\"",
"content-encoding": "gzip",
"content-type": "application/octet-stream",
"date": "Thu, 30 Jun 2016 18:03:10 GMT",
"etag": "\"8ad9c59b256cef48798a94c0295023088016d43a\"",
"server": "Apigee Router",
"vary": "Accept-Encoding",
"transfer-encoding": "chunked",
"connection": "Close"
},
"status": 200


}

As you can see, there is no body. But when I use
Head
on the object, I get the right number of bytes.

Can someone tell me what I'm doing wrong?
I tried hard-coding Content-Type to
application/x-www-form-urlencoded
and then I could download the file (there were bytes in the body), but the bytes were changed a little. For example, 208 (11010000) became 80 (1010000). As you can see, the first bit was reversed. With that content-type, I could not open the file. Which way should I use?




UPDATE:
With the help of Augusto, I found the problem.


  1. Superagent doesn't seem to work, but Request does.

  2. Not sure if it had an real impact, but I set the encoding for the downloaded buffer to base64

  3. I needed to upload the Blob directly. I didn't have to use a FileReader to read the bytes.


Answer

Don't believe you need content-type to download a file, see more here. Can you request the details of the file?

This the curl to download it that should work:

curl -v "https://developer.api.autodesk.com/oss/v2/buckets/storage.vcs.prod.mevsg.autodesk.com/objects/assets%2FNT5NR9KJU2PH%2Fea02ec77505f2ea2defac93fe231764f2916e4d1aeaac7d92945a08a0086c60667369431361d5aa426d4cccca49b9e4c7cb70bc6ebf700258a3cb37617eacfa0"
  -X GET
  -H "Authorization: Bearer AbCdEfGhIjKlMnOpQrStUvXwYz"

And here is a code I used with NodeJS/Request module. It's in fact quite generic, but if I pass the /oss/ URL resource, it works fine. I'm not sure which library you're using, sorry.

function download(resource, token, onsuccess) {
    console.log('Downloading ' + config.baseURL + resource); // debug
    request({
        url: config.baseURL + resource,
        method: "GET",
        headers: {
            'Authorization': 'Bearer ' + token,
        },
        encoding: null
    }, function (error, response, body) {
        onsuccess(new Buffer(body, 'base64'));
    });
}