DigitalOcean Spaces - File Upload Using Curl

Posted August 9, 2019 2.1k views


I’m trying to upload some files to DigitalOcean’s Spaces with PHP and cURL but for some reason I cannot do it. I don’t want to use some libraries like Amazon’s SDK because they are too big. I want something more simple. Here is where I am at now.

 $file = '/home/development/www/source.png';

    $contents = file_get_contents($file);
    $filesize = filesize($file);

    $accessKeyId = '###';
    $secretKey = '###';

    $longDate = gmdate('Ymd\THis\Z');
    $shortDate = gmdate('Ymd');

    $newfile = urlencode('/new-dir/new-file.png');

    $cannonical = 'PUT'.PHP_EOL.''.$newfile.''.PHP_EOL.''.PHP_EOL.'content-length:'.$filesize.''.PHP_EOL.''.PHP_EOL.'x-amz-date:'.$longDate.''.PHP_EOL.'x-amz-acl:public-read'.PHP_EOL.'content-length;host;x-amz-date;x-amz-acl;'.PHP_EOL.''.hash_file('sha256', $file).''.PHP_EOL.'';

    $cannonical = hash('sha256', $cannonical);

    $string = 'AWS4-HMAC-SHA256'.PHP_EOL.''.$longDate.''.PHP_EOL.''.$shortDate.'/fra1/s3/aws4_request'.PHP_EOL.''.$cannonical.''.PHP_EOL.'';

    $signingKey = hash_hmac('sha256', $shortDate, 'AWS4'.$secretKey, true);
    $signingKey = hash_hmac('sha256', 'fra1', $signingKey, true);
    $signingKey = hash_hmac('sha256', 's3', $signingKey, true);
    $signingKey = hash_hmac('sha256', 'aws4_request', $signingKey, true);
    $signature  = hash_hmac('sha256', $signingKey.$string, $signingKey);

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_HEADER, true);
    curl_setopt($ch, CURLOPT_URL, ''.$newfile);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Length: '.$filesize,
            'x-amz-date: '.$longDate,
            'x-amz-acl: public-read',
            'Authorization: AWS4-HMAC-SHA256 Credential='.$accessKeyId.'/'.$longDate.'/fra1/s3/aws4_request, SignedHeaders=host;x-amz-date;x-amz-acl;content-length, Signature='.$signature

    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
    curl_setopt($ch, CURLOPT_POSTFIELDS, $contents);
    echo curl_error($ch);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    echo $http_code;

Every time I try to upload something it says 403 Forbidden. What am I doing wrong in the signature calculation?

Thank you.

1 comment

These answers are provided by our Community. If you find them useful, show some love by clicking the heart. If you run into issues leave a comment, or add your own answer to help others.

1 answer


I’m not sure what’s missing in your code here. We do have similar case discussed earlier in community link below which might help you to upload files using PHP:

If you are still getting an error then I would highly recommend you to open a support ticket along with the error message so that our support team looks into it.


Submit an Answer