So I’m building this platform that will allow file uploads and I will be using Digital Oceans Spaces because it’s more affordable for my project. I encountered 2 problems so far when uploading files with presigned url. One is independent from the other. Here’s the code that generates the url:
$spaces = \Storage::disk('spaces');
$client = $spaces->getDriver()->getAdapter()->getClient();
$expiry = "+60 minutes";
$filename = time() .'.jpeg';
$command = $client->getCommand('PutObject', [
'Bucket' => 'jgb',
'Key' => "images/$filename",
'ACL' => 'public-read',
'ContentType' => 'application/octet-stream',
]);
$request = $client->createPresignedRequest($command, $expiry);
return (string) $request->getUri();
and it works fine for file uploads using Postman except that I’m getting 2 problems:
multipart/form-data; boundary=--------------------------532068335149033986173029
when testing with Postman.
I’ve googled around and couldn’t find anything related to that. I’m thinking maybe Digital Ocean Spaces just lacks some of the features of S3.
Any help is welcome. Thanks!
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.
Click below to sign up and get $100 of credit to try our products over 60 days!
@robbat2 thanks for answering personally.
DO spaces behaviour is not consistent with aws behaviour.
This is my typical snippet to get a presigned url with aws-sdk:
I can then PUT my file to the url generated without the need to send the metadata headers (x-amz-meta-* and x-amz-meta-acl) signed. This is a great advantage:
Do spaces on the other side complains with a 403 forbidden (invalid signature) because it requires passing those headers when making the PUT request.
Any chance to avoid this and replicate aws behaviour?
Hi, Spaces Engineering team member here.
This looks mostly like the AWS PHP SDK v3 you’re using, please do correct me if I’m wrong.
Based on the
multipart/form-data
string, I think you might be doing a request with thePOST
HTTP method rather than aPUT
HTTP method.If this is the case, you need to either do a PUT method for the actual upload (be sure to specify the headers & fields per your signed request), or instead generate a signed POST request to use.
The
public-read
you have specified is a constraint on what permissions should be present on the object AFTER it’s uploaded. Similarly for thecontent-type
.The SDK does provide explicit methods to ensure you get this correct:
$request->getMethod();
$request->getHeaders();
If you read the URI string closely, you should see a parameter that shows which headers were signed. Those will need to be preserved if any.