Web page to upload to Amazon AWS

Here’s how to make a simple web page to allow people to upload files to an Amazon AWS bucket from your site.  Some of the details are a bit murky, but it does seem to work. You will need a bucket with upload permissions enabled (and probably public downloads disabled).

First, you need a policy, saved as a text file.  Here’s mine:

{ "expiration": "2090-12-01T12:00:00.000Z",
  "conditions": [
    {"bucket": "MY-BUCKET"},
    ["starts-with", "$key", "upload"],
    {"acl": "public-read"},
    {"success_action_redirect": "http://example.com/successful_redirect.html"},
    {"x-amz-meta-uuid": "14365123651274"},

Replace MY-BUCKET with the name of your AWS bucket, and the successful_redirect URL with where the user should be taken when an upload succeeds.  I’ve no idea what the x-amz-meta-uuid does, to be honest; that’s the one of Amazon’s example.

Now, you need to encode this policy and sign it with your AWS secret key.  Save the policy as upload_policy and use this python script:

import base64
import hmac
import hashlib

aws_secret_key = 'MY-SECRET-KEY'

with open('upload_policy', 'r') as f:
    policy_document = f.read()

policy = base64.b64encode(policy_document)
signature = base64.b64encode(hmac.new(aws_secret_key, policy, hashlib.sha1).digest())

print 'Policy:'
print policy
print 'Signature:'
print signature

Replace MY-SECRET-KEY with your Amazon AWS secret key.  The script will print out policy and signature values, which you should paste into this HTML:

<form action="http://MY-BUCKET-NAME.s3.amazonaws.com/" method="post" enctype="multipart/form-data">
  <input type="hidden" name="key" value="upload-${filename}"/><br/>
  <input type="hidden" name="acl" value="public-read"/>
  <input type="hidden" name="success_action_redirect" value="http://example.com/successful_upload.html"/>
  <input type="hidden" name="x-amz-meta-uuid" value="14365123651274"/>
  <input type="hidden" name="AWSAccessKeyId" value="MY-ACCESS-KEY"/>
  <input type="hidden" name="Policy" value="MY-POLICY"/>
  <input type="hidden" name="Signature" value="MY-POLICY-SIGNATURE"/>
  <tr><td>File</td><td><input type="file" name="file"/></td></tr>
  <!-- The elements after this will be ignored -->
  <tr><td></td><td><input type="submit" name="submit" value="Upload"/></td></tr>

Once again, replace MY-BUCKET-NAME with your bucket, and the successful_upload URL with one appropriate for your site. MY-ACCESS-KEY needs replacing with your AWS access key.

Files that are uploaded should then appear in your AWS bucket.