I'm running into an issue where S3 will occasionally return a 403 on the OPTIONS request pre-flight when trying to upload an object from the client side with a PUT request to a signed URL. The frustrating part is that 90% of the time it works fine, and when it does fail, if I retry the same request a few times, then it will go through.
Has anyone experienced something similar, and if so, how did you solve it?
This seems related to this issue, but isn't exactly the same, because they're going through CloudFront, and I'm going directly to S3.
Generating the signed URL on the server side
const params = {
Bucket: **my bucket**,
Key: 'test/my-test-file.csv',
Metadata: {
'created-by': req.user.id,
'job-id': job.id,
},
};
const url = s3.getSignedUrl('putObject', params);
Angular.JS HTTP Request to the Signed URL
return $http({
url: **signedUrlHere**,
method: 'PUT',
data: file,
headers: {
'Content-Type': '',
},
transformRequest: [],
});
Bucket CORS Settings
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
Request Headers
Host: s3.amazonaws.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:67.0) Gecko/20100101 Firefox/67.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: content-type
Referer: https://**.***.com/*/*/*
Origin: https://**.***.com
DNT: 1
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Response Headers
HTTP/1.1 403 Forbidden
x-amz-request-id: *********
x-amz-id-2: *******
Content-Type: application/xml
Transfer-Encoding: chunked
Date: Thu, 20 Jun 2019 02:54:39 GMT
Server: AmazonS3