0

I'm trying to write a function to download a file stored in a persistent bucket and I'm having some problems decoding the result.

I'm following the guide here to try and download the object shown here:

(int) 3 => object(stdClass) {
        bucketKey => 'my-persistent-bucket'
        objectKey => '11--test.dwg'
        objectId => 'urn:adsk.objects:os.object:my-persistent-bucket/11--test.dwg'
        sha1 => '477085439a60779064d91fd1971d53c77c7a163a'
        size => (int) 188600
        location => 'https://developer.api.autodesk.com/oss/v2/buckets/my-persistent-bucket/objects/11--test.dwg'
    }

Using the following cURL function

    $ch = curl_init();
    $headers = [
        "Authorization: Bearer " . $token->token,
        "Accept: application/octet-stream"
    ];

    $url = 'https://developer.api.autodesk.com/oss/v2/buckets/'.$this->persistent.'/objects/'.rawurlencode($file->object_key);

    curl_setopt_array($ch, [
        CURLOPT_HTTPHEADER => $headers,
        CURLOPT_RETURNTRANSFER => 1,
        CURLOPT_URL => $url
    ]);

    $response = curl_exec($ch) ;
    $http_header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE) ;
    $http_header = substr($response, 0, $http_header_size) ;
    $http_body = substr($response, $http_header_size) ;
    $response_info = curl_getinfo($ch) ;
    curl_close($ch) ;

curl_getinfo($ch); looks like everything has gone fine:

'url' => 'https://developer.api.autodesk.com/oss/v2/buckets/my-persistent-bucket/objects/11--test.dwg',
'content_type' => 'application/x-www-form-urlencoded',
'http_code' => (int) 200,
'header_size' => (int) 474,
'request_size' => (int) 199,
'filetime' => (int) -1,
'ssl_verify_result' => (int) 0,
'redirect_count' => (int) 0,
'total_time' => (float) 1.261261,
'namelookup_time' => (float) 0.029048,
'connect_time' => (float) 0.057444,
'pretransfer_time' => (float) 0.119675,
'size_upload' => (float) 0,
'size_download' => (float) 188600,
'speed_download' => (float) 149532,
'speed_upload' => (float) 0,
'download_content_length' => (float) 188600,
'upload_content_length' => (float) 0,
'starttransfer_time' => (float) 0.902231,
'redirect_time' => (float) 0,
'redirect_url' => '',
'primary_ip' => '52.210.137.76',
'certinfo' => [],
'primary_port' => (int) 443,
'local_ip' => '10.0.2.15',
'local_port' => (int) 50564

$http_body = '%C8B%BB%8B%A6%12%03Z%7D%29%E7%27%1F%5D%D4%CB%FC%DA%15G%3B%13%0D%89%0A%1C%DB%AE2%2C%9AP%EE%60x6%FD%92I2%F6%DE%7DI%DC%A0O%14%F2%84%9Ed%D0k%C40%B7%3E%3B%A1%22%...

The response is always what looks like a url encoded string but no matter how I try to decode it, I can't manage to get a working file, so far I've tried:

curl_unescape() urldecode() rawurldecode()

and none of these give me a useable file. It's worth noting that I can download a file from A360 no problem, but I've not managed to get one out of a Forge bucket.

Any ideas on what I'm doing wrong would be great.

Thanks

Kev Wilson
  • 470
  • 6
  • 19

1 Answers1

0

The bucketKey should match this regular expression '^[-_.a-z0-9]{3,128}$', and the objectKey should be URL encoded. However, the keys used to upload the file/object must match the ones used to download. Which means that if you choose to encode characters one way, they should be encoded the same way later.

I also noticed you did not specify how to encode the download. If you do not specify to download as octet, HTTP will use the default which is UTF8 text characters vs binary. You did specify CURLOPT_RETURNTRANSFER which will convert to binary, but you are missing the header for the server part.

The code below works fine for me, assuming bucketKey and objectKey were URL encoded with rawurlencode(); as well as when the file/object was uploaded with PUT.

```
$ch =curl_init () ;
$headers =[
    "Authorization: Bearer {$token->token}",
    "Accept: application/octet-stream",
    "Content-Type: application/json"
] ;
$url ="https://developer.api.autodesk.com/oss/v2/buckets/{$bucket_key}/objects/{$object_key}" ;
curl_setopt_array($ch, [
    CURLOPT_HTTPHEADER => $headers,
    CURLOPT_RETURNTRANSFER => 1,
    CURLOPT_URL => $url
]) ;

$response =curl_exec ($ch) ;
$http_header_size =curl_getinfo ($curl, CURLINFO_HEADER_SIZE) ;
$http_header =substr ($response, 0, $http_header_size) ;
$http_body =substr ($response, $http_header_size) ;
$response_info =curl_getinfo ($ch) ;
curl_close ($ch) ;

file_put_contents ('11--test.dwg', $http_body) ;

```

As you can see I split the response into 2 parts. The headers and the octet-stream. The file download is in the 2nd part and is the HTTP body response. The response contains both headers and body, hence you need to split this on your end.

Hope that helps,

cyrille
  • 2,616
  • 1
  • 10
  • 18
  • Thanks for your help @cyrille but I'm still not having much luck. I notice you didn't decode your `$http_body` I assume that is because you used an `octet-stream`. I have set `"Accept: application/octet-stream"` in my headers but `curl_getinfo($ch)` shows that `'content_type' => 'application/x-www-form-urlencoded',` was sent. Could this be the reason behind my inability to decode the response into something usefull? I'm going to edit my question to include your suggestions. Thanks – Kev Wilson Sep 26 '16 at 13:58