| ||||||||||||||||||
|
Shop the new tech.book(store)
New! Introducing the tech.book(store), a hub for Software Developers and Architects, Networking Administrators, TPMs, and other technology professionals to find highly-rated and highly-relevant career resources. Shop books on programming and big data, or read this week's blog posts by authors and thought-leaders in the tech industry. > Shop now |
Amazon’s Simple Storage Service (S3) provides cheap and unlimited online data storage for anyone with a credit card and an Amazon Web Service (AWS) account. If you have an AWS account, you can interact with the S3 service using specialized tools to upload and manage your files. It is very convenient to have access to this online storage resource for yourself, but there may be situations where you would like to allow others to upload files into your account.
For this purpose, S3 accepts uploads via specially-crafted and pre-authorized HTML POST forms. You can include these forms in any web page to allow your web site visitors to send you files using nothing more than a standard web browser.
In this article, I will demonstrate how to build simple S3 POST forms. I will assume that you have already signed up for the S3 service, and that you have an S3 client program for creating buckets and viewing files in your account. Before you proceed, create your own bucket to store uploaded files — in the examples below I will use a bucket named s3-bucket.
Here is a web page with an S3 POST Form that you can use as a template for your own forms:
<html> <head> <title>S3 POST Form</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </head> <body> <form action="https://s3-bucket.s3.amazonaws.com/" method="post" enctype="multipart/form-data"> <input type="hidden" name="key" value="uploads/${filename}"> <input type="hidden" name="AWSAccessKeyId" value="YOUR_AWS_ACCESS_KEY"> <input type="hidden" name="acl" value="private"> <input type="hidden" name="success_action_redirect" value="http://localhost/"> <input type="hidden" name="policy" value="YOUR_POLICY_DOCUMENT_BASE64_ENCODED"> <input type="hidden" name="signature" value="YOUR_CALCULATED_SIGNATURE"> <input type="hidden" name="Content-Type" value="image/jpeg"> File to upload to S3: <input name="file" type="file"> <br> <input type="submit" value="Upload File to S3"> </form> </body> </html> This template demonstrates some important features of an S3 POST form, and the web page that contains it:
meta tag in the head section that tells web browsers to use the UTF-8 unicode character encoding.action parameter specifies an S3 URL that includes the name of your destination bucket, in this case the bucket called s3-bucket.The S3 service uses information from the form’s input fields to authorize uploads, and to set the properties of uploaded file objects. Here is a description of the most common input fields:
| Field Name | Description |
|---|---|
| key | A name for the S3 object that will store the uploaded file’s data. This name can be set in advance when you know what information the user will upload, for example: uploads/monthly_report.txt. If you do not know the name of the file a user will upload, the key value can include the special variable |
| AWSAccessKeyId | The Access Key Identifier credential for your Amazon Web Service account. |
| acl | The access control policy to apply to the uploaded file. If you do not want the uploaded file to be made available to the general public, you should use the value private. To make the uploaded file publicly available, use the value public-read. |
| 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. |
| policy | A Base64-encoded policy document that applies rules to file uploads sent by the S3 POST form. This document is used to authorize the form, and to impose conditions on the files that can be uploaded. Policy documents will be described in more detail below. |
| signature | A signature value that authorizes the form and proves that only you could have created it. This value is calculated by signing the Base64-encoded policy document with your AWS Secret Key, a process that I will demonstrate below. |
| Content-Type | The content type (mime type) that will be applied to the uploaded file, for example image/jpeg for JPEG picture files. If you do not know what type of file a user will upload, you can either prompt the user to provide the appropriate content type, or write browser scripting code that will automatically set this value based on the file’s name.If you do not set the content type with this field, S3 will use the default value |
| file | The input field that allows a user to select a file to upload. This field must be the last one in the form, as any fields below it are ignored by S3. |
This overview of the form’s input fields should help you to modify the template POST form to suit your own purposes. At a minimum, you will need to edit the form’s action parameter to point to your own S3 bucket, and set the value of the AWSAccessKeyId field to your AWS Access Key credential.
To complete the form and make it acceptable to the S3 service, you will also need to generate a policy document and signature value.
S3 POST forms include a policy document that authorizes the form and imposes limits on the files that can be uploaded. When S3 receives a file via a POST form, it will check the policy document and signature to confirm that the form was created by someone who is allowed to store files in the target S3 account.
A policy document is a collection of properties expressed in JavaScript Object Notation, which simply means that the document’s structure and content must conform to a certain format. Every policy document contains two top-level items:
expiration - A Greenwich Mean Time (GMT) timestamp that specifies when the policy document will expire. Once a policy document has expired, the upload form will no longer work.conditions - A set of rules to define the values that may be included in the form’s input fields, and to impose size limits for file uploads. Here is a policy document corresponding to the POST form template above. This policy has an expiration date of January 1st 2009:
{"expiration": "2009-01-01T00:00:00Z", "conditions": [ {"bucket": "s3-bucket"}, ["starts-with", "$key", "uploads/"], {"acl": "private"}, {"success_action_redirect": "http://localhost/"}, ["starts-with", "$Content-Type", ""], ["content-length-range", 0, 1048576] ] } To create a valid S3 POST form, you must include a policy document whose conditions section contains a rule for almost every input field in the form. At a minimum, this document must include rules for the bucket and key values of the uploaded file object. In addition to these two rules, you will need to include a rule for every other input field in the form except for AWSAccessKeyId, signature, policy and file.
Because our template POST form includes the input fields acl, success_action_redirect, and Content-Type, our policy document includes rules corresponding to these fields. Our policy document also includes an extra content-length-range rule that limits the size of files that can be uploaded.
There are three kinds of rules you can apply in your policy document:
{"acl": "private"}starts-with, followed by the name of the input field preceded by a $ symbol, then the prefix string value for comparison. key and Content-Type fields because we do not know in advance the name of the file a user will upload, or what type of file it will be. The rule for the Content-Type field uses an empty string for comparison, which means it will permit any content type value. The rule for the object’s key name uses the prefix string “upload/”, which means that the key value must always start with the upload/ subdirectory path.content-length-range, followed by integer values to set the minimum and maximum file size. The policy document above includes a content length rule that will prevent the form from uploading files larger than 1MB in size (1,048,576 bytes).It is important to make sure that your policy document corresponds exactly to your S3 POST form. If there are any discrepancies between the input field values in your form and the rule values in your policy document, or if your form contains input fields that do not have corresponding rules in your policy, the S3 service will reject the form and return an incomprehensible XML error message to your users.
To complete your S3 POST form, you must sign it to prove to S3 that you actually created the form. If you do not sign the form properly, or if someone else tries to modify your form after it has been signed, the service will be unable to authorize it and will reject the upload.
To sign your form you need to perform two steps:
policy input field.signature input field after Base64-encoding it.Almost all programming languages include libraries for performing these two steps. Here are some example code fragments to do the job with different languages, assuming you have already defined the variables policy_document and aws_secret_key.
require 'base64' require 'openssl' require 'digest/sha1' policy = Base64.encode64(policy_document).gsub("\n","") signature = Base64.encode64( OpenSSL::HMAC.digest( OpenSSL::Digest::Digest.new('sha1'), aws_secret_key, policy) ).gsub("\n","") import sun.misc.BASE64Encoder; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; String policy = (new BASE64Encoder()).encode( policy_document.getBytes("UTF-8")).replaceAll("\n",""); Mac hmac = Mac.getInstance("HmacSHA1"); hmac.init(new SecretKeySpec( aws_secret_key.getBytes("UTF-8"), "HmacSHA1")); String signature = (new BASE64Encoder()).encode( hmac.doFinal(policy.getBytes("UTF-8"))) .replaceAll("\n", ""); import base64 import hmac, sha policy = base64.b64encode(policy_document) signature = base64.b64encode( hmac.new(aws_secret_key, policy, sha).digest()) Once you have calculated the values for the policy and signature input fields and included these values in your form, the form should be complete. Save the web page and form document as an .html file, open it in your favorite web browser, and test it by uploading some files to your S3 bucket.
The form web page and policy document templates in this article should give you a starting point for creating your own upload forms. With some minor modifications to the template documents and a little coding, you will be able to create authorized forms that make it easy for your web site visitors to upload files to your S3 account.
The S3 service’s POST support is a powerful feature with many potential uses. You could create a single upload form to allow your friends and colleagues to send you files that are too large for email, or you could modify your web applications to generate forms on-demand so your users can store their data in S3 rather than on your own server. Just remember that you will be liable for any S3 data transfer and storage fees incurred by the people who use your forms.
James Murty is a software developer with extensive experience creating web-based applications and architectures using Java. With a working background spanning a research institute, a small software house and various corporations he has a broad perspective on both the promise and the difficulties inherent in networked applications.
Most recently James has been excited to see the rise of web applications and services that provide compelling new tools and new ways of approaching old problems. While experimenting in this area he created JetS3t, an open source library and application suite that is the leading Java implementation available for Amazon's S3 data storage service.
Product Details
Would you like to update product info or give feedback on images? |