Upload file to S3 directly (from webforms)



  • According to doc, policy field is optional in POST Forms, if the bucket is public-writable, which is not recommended. But I couldn’t get it working. Tried set acl, policy, and CORS, neither one works. Anyway it’s not good practice. Move on to make policy working in POST form is actually not that hard.
  • Policy needs base64 encoded, the format of policy is a JSON string, note, this is the policy stay in POST Form, web client only, not in anywhere on bucket settings. Don’t be confused by the same term applied on bucket permission settings.
  • Signature needs based64 encoded too, after SHA-1 encrypted with your account secret, which should be pared with the AWSaccesskeyId field in POST Form.
  • The doc listed a few scripts in different language showing how to encrypt and encode policy/signature. You can actually do this manually using some online tool:
    http://www.base64encode.org/ base64 encode
    http://www.freeformatter.com/hmac-generator.html#ad-output SHA-1 encrypt
    https://conv.darkbyte.ru/  or http://home.paulschou.net/tools/xlate/ base64 encode the encrypted signature in hex string.
    Note: that base64encode.org page only do regular ASCII string base64 encoding.
  • When pasting base64 string in POST form, watch out for the extra new line tag after = or ==, remove it otherwise S3 will complain invalid signature.


To manually get policy and signature:

  1.  Copy paste policy string into http://www.base64encode.org/, to get base64 encoded policy string.
  2.  Copy paste base64 encoded policy string into http://www.freeformatter.com/hmac-generator.html#ad-output, and put your account secret as secret key, to get encrypted signature in hex string.
  3. Copy paste encrypted signature hex string into https://conv.darkbyte.ru/ or http://home.paulschou.net/tools/xlate/, right in HEX textarea, click decode, the string shown in Base64 textarea is the final base64encoded encrypted singature string your webForm needed.

One little thing, how to get the response?

By default, S3 won’t check duplicated file name, so if you upload an existing file name, the old one on S3 will be overwritten. (There is an option in SDK to prevent this.)

Good practice will be generate guid file name before upload.

To get some response back from S3 upload, you can use success_action_redirect field.

According to doc:

success_action_redirect The URL address to which the user’s web browser will be redirected after the file is uploaded. This URL should point to a “Successful Upload” page on your web site, so you can inform your users that their files have been accepted. S3 will add bucket, key and etag parameters to this URL value to inform your web application of the location and hash value of the uploaded file.

How to display/grab those parameters without creating a dynamic page (PHP) on a host?

I found a very useful service: http://ivanzuzak.info/urlecho/

To set the success_action_redirect value to http://urlecho.appspot.com/echo?debugMode=1

Note that debugMode is on, so you can see those return code on page.

A typical output I got looks like this:

Request received:

Status code:

Content-Length: 0
etag: "48b918c648abfa0267ffdc9975ea8bbf"
key: uploads/uploaded-file.pdf
Cache-Control: max-age=3600
bucket: your-bucket-name
Access-Control-Allow-Origin: *
Content-Type: text/html; charset=utf-8


Last thing, did I mention that this POST form page is a pure static page so you can simply upload to S3 and it will just works?


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s