Skip to content

Amazon S3 queryStringPut

One of the applications I am working on uses Amazon Simple Storage Solution as its storage architecture for potentially billions of files. Because I am working on a widely distributed client application that can not contain our private S3 key, I have a web service on my own server set up that will create Query String Authentication URLS for use with S3. My service creates the URL, passes it back to the client, and the client can then temporarily use that URL to get files from S3.
Performing a GET using Query String Authentication is well documented in the S3 API docs. What is –not- well documented is the fact that you can also do a “PUT” on S3s REST service to store files, if you have encoded your query string correctly.
In the PHP code sample provided by Amazon, the method queryStringGet exists. I was in need of queryStringPut, which was not included. What follows is my version of queryStringPut, in PHP:

function queryStringPut($bucket, $key, $expires)
{
$expires = time() + $expires;
$path = $bucket.”/”.$key;

$resource = urlencode($path);
$stringToSign = “PUT\n\n\n$expires\n/$path”;
$signature = urlencode($this->constructSig($stringToSign));
$queryString = “http://s3.amazonaws.com/$path?AWSAccessKeyId={$this->accessKeyId}&Expires=$expires&Signature=$signature”;
return $queryString;
}

The above code will produce a URL that can be used to post a file to S3 from a client application. The client code to use the URL produced by the above code can look something like this (in C#):


System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(url);
request.Method = “PUT”;
Stream newStream = request.GetRequestStream();
newStream.Write(bytes, 0, bytes.Length);
newStream.Close();
System.Net.WebResponse postResponse = request.GetResponse();

{ 5 } Comments

  1. AJ | May 28, 2008 at 3:57 am | Permalink

    I am a bit reluctant in using Query String Authentication. It looks like you can use the query to access other objects as well… by just changing the path and using the rest of the query. Is that true?

  2. AJ | May 28, 2008 at 4:00 am | Permalink

    Oh I see now, so the signature will be unique for this file as stringToSign has the path as well. Is that correct…?

  3. admin | June 6, 2008 at 4:03 pm | Permalink

    Yes, as the path changes, so does the stringToSign, resulting in a differernt signature for each resulting path. So it seems fairly secure.

  4. Mark S. Meritt | January 22, 2009 at 8:18 am | Permalink

    You seem to be a good person to ask about query string authentication since you’re putting yourself out here talking about how you’re using it!

    I’m a tiny little non-programmer who wants to give away free downloads of songs to people who sign up for my mailing list. I thought I’d create URLs using query string authentication to do this, and periodically update my mailing list autoresponder so that anyone who gets the URL would have say a week or two to get the file, then the link goes bad, so they can’t share it — so only people who keep signing up can get the links.

    But I have no secure server, I’m not a programmer, etc. I get the concept fine enough, but I have no clue where or how to actually create the URLs.

    I wondered if S3Fox might be able to, but I don’t think it has that functionality. I see someone has written a WP plugin — http://codepolice.net/index.php/2008/12/08/generate-expiring-urls-for-amazon-s3-via-a-wordpress-plugin/ — but I don’t want the URLs showing up on my WP pages/posts, I want to create them to put only in emails to my mailing list, plus I’d be concerned that the use of the Secret Key might not be secure with such a plugin.

    Any thoughts on a quick and painless path to what I’m after?

  5. admin | April 7, 2009 at 6:58 pm | Permalink

    First of all, I apologize for the delay in responding. For some reason I missed the notification when you posted your comment.

    To do what you’re after, I think you’d want to either use a PHP script to generate your URL for you, or generate the URL by some other means. Its been a while, but there were some free S3 clients that ran on windows back when I worked on this that would let you right click on an item in your S3 storage, and generate a URL for you with an expiration. So basically using one of these S3 Windows Clients (I’m sure there must be an equivalent for OSX as well) you can upload a file to S3, and generate a URL for it. I’m sorry I can not be more specific, as I haven’t used any desktop S3 clients in a while.

Post a Comment

Your email is never published nor shared. Required fields are marked *