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();