I'm hosting files on Amazon S3 that I want to make accessible using pre-signed urls.
For simple GET requests this works perfectly. There are some clients however that perform a HEAD request first (to retrieve the file size). Since the signature in the URL includes the http verb (GET vs HEAD), the head request fails.
The client simply does:
HEAD http://(bucketname).s3.amazonaws.com/filename?AWSAccessKeyId=(mykey)&Expires=(timestamp)&Signature=(sig)
GET http://(bucketname).s3.amazonaws.com/filename?AWSAccessKeyId=(mykey)&Expires=(timestamp)&Signature=(sig)
I cannot change the clients to use a different url for head and get. Is there a way to make amazon use a signature that accepts both HEAD and GET for the same resource?
You can also simulate the HEAD
behavior with GET
if you specify Range
header for first byte only. The difference will be that you receive 206
instead of 200
code. Secondly full size will be in Content-Range
header.
curl -I -H "Range: bytes=0-0" <URL>
No. The HEAD
and the GET
need different signatures as there are subtle differences in the signature inputs.
Not sure what you're using to generate the pre-signed authentication URLs, but I know that some of the official AWS SDKs handle this, while others don't yet.
with the help of a friend, I found a solution that works for me: proxy the HEAD request on my server, and redirect for the GET request.
When a request comes in with a HEAD verb to get the file info, I use my S3 code on my server to get the HEAD info and then I sent it back to the requestor myself.
When a request comes in with a GET verb to get the file itself, I do a 302 redirect with a pre-signed URL.
this works perfectly to handle both HEAD and GET by not needing to pre-sign both. I only pre-sign the GET request for the actual file.