I'm trying to upload files from the browser (Chrome version 41.0) to S3 using a presigned URL with the PUT method. I'm generating the presigned URL on my server correctly, as it works fine from CURL:
curl -X PUT "Content-Type:" --data "junk" "https://mypresignedurl"
I'm now trying to upload from the browser using jQuery:
$.ajax({
url: "https://mypresignedurl",
method: 'PUT', // I've also tried type: 'PUT'
data: "junk",
})
This is refused by AWS with a SignatureDoesNotMatch code. The error specifies:
<StringToSign>GET 1427216999 /mybucket/myfile</StringToSign>
But I wasn't using GET - I was using PUT. If I check the network tab of Chrome, it correctly lists the request as a PUT. So why does AWS interpret browser PUT requests as GETs and reject them?
(This does not seem to be CORS-related. I've set CORS on my bucket, and then tested from CURL using -H "Origin: http://elsewhere.com". I've also tried passing "type" instead of "method". I've tried using POST instead of PUT - even then AWS still lists the StringToSign as a GET. I've tried various contentTypes. FWIW, my presignedURL upload logic all works fine from .NET in a WPF app.)