I am creating an API for a backend service with Rails 4. The service needs to upload an image file to an amazon s3 bucket.
I'd like to use a direct upload url, so that the clients manage the uploads to s3 and the server is not kept busy.
Currently I have the following prototypical rails action
def create
filename = params[:filename]
s3_direct_post = S3_BUCKET.presigned_post(key: "offers/#{SecureRandom.uuid}/#{filename}", acl: 'public-read')
s3p = s3_direct_post.fields
url = "#{s3_direct_post.url}/#{filename}?X-Amz-Algorithm=#{s3p['x-amz-algorithm']}&X-Amz-Credential=#{s3p['x-amz-credential']}&X-Amz-Date=#{s3p['x-amz-date']}&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=#{s3p['x-amz-signature']}"
render json: {success: true, url: url}, status: :ok
end
This generates such an url:
https://my-bucket.s3.eu-central-1.amazonaws.com/test.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=MYKEY/20150420/eu-central-1/s3/aws4_request&X-Amz-Date=20150420T162603Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=MYSIGNATURE
Now I try to post the test.png to this url with the following:
curl -v -T test.png "url"
and I get the following error response:
<Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message><AWSAccessKeyId>MYKEY</AWSAccessKeyId>...
I believe the problem comes from the fact, that the specified X-Amz-SignedHeaders Header is wrong. I am not sure which headers are used by default from the amazon rails sdk gem.
How should I change my url generation, so that a mobile client can just take the url and post a file to it?