-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added Aws::S3::PresignedPost helper for creating browser upload forms. #752
Conversation
`Aws::S3::PresignedPost` is a utility class that makes it possible to upload a file from a web browser directly to Amazon S3. See #720.
Changes Unknown when pulling 4a3fd4b on presigned-post into * on master*. |
Haven't had a chance to look through the code yet, but presuming that it works as it should (and I believe it will), thanks a ton @trevorrowe! |
sweet, this is great! will you be cutting a new gem release soon which includes this feature @trevorrowe? |
@arunthampi The plan is to tag and release v2.0.34 on Thursday. I try to do a weekly update each Thursday unless there is a high priority security fix, bug fix, or API update. |
cool, thanks 👍 |
I tried using using Aws::S3::PresignedPost in my app (ref: 11ab665) with the jquery-file-upload plugin, I get a proper XML response but the file doesn't exist in the bucket. https://gist.github.com/arunthampi/f4e47fa5a1d2ed1b7abc Followed the tutorial here: https://devcenter.heroku.com/articles/direct-to-s3-image-uploads-in-rails, anything I'm missing? |
Looking at the xml response, the object should be found at the given |
Yes that's correct a HEAD or GET on this object returns a 403. The new signature format works for all regions yes? |
Confirmed that the exact same JS code uploads the file for the v1 version of |
I'm a bit confused. In your linked gist: https://gist.github.com/arunthampi/f4e47fa5a1d2ed1b7abc you show a 201 response. This indicates that your object was successfully uploaded to Amazon S3. If this is correct, then my suspicion is that you are extracting the key or location incorrectly from the response. When you say that it works with the v1 |
Apologies for the confusion, I've update the gist with the v1 https://gist.github.com/arunthampi/f4e47fa5a1d2ed1b7abc#file-presigned_post_v1-rb and here's v2: https://gist.github.com/arunthampi/f4e47fa5a1d2ed1b7abc#file-presigned_post_v2-rb and here's the the Javascript which does the file upload: https://gist.github.com/arunthampi/f4e47fa5a1d2ed1b7abc#file-fileupload-js-coffee the relevant lines where I extract the URL of the uploaded file is here: https://gist.github.com/arunthampi/f4e47fa5a1d2ed1b7abc#file-fileupload-js-coffee-L36-L37 |
I think I see the problem. In your v1 code you set the key as: Notice in v2 there is an extra forward slash at the beginning of the key. Depending on the structure of your |
doh! that was it, thanks much for your help! |
Generate a presigend post from an
Aws::S3::Bucket
orAws::S3::Object
by calling their#presigned_post
method. AnAws::S3::PresignedPost
object is constructed and returned.The rest of the comments below document using the presigned post class directly where you must manage your own credentials, region, and bucket name.
Basic Usage
You can apply constraints to the post object as options to {#initialize} or by calling methods such as {#key} and {#content_length_range}.
The following two examples are equivalent.
HTML Forms
You can use a
PresignedPost
object to build an HTML form. It is recommended to use some helper to build the form tag and input tags that properly escapes values.Form Tag
To upload a file to Amazon S3 using a browser, you need to create a post form. The
#url
method returns the value you should use as the form action.The follow attributes must be set on the form:
action
- This must be the#url
.method
- This must bepost
.enctype
- This must bemultipart/form-data
.Form Fields
The
#fields
method returns a hash of form fields to render inside the form. Typically these are rendered as hidden input fields.Lastly, the form must have a file field with the name
file
.Post Policy
When you construct a
PresignedPost
, you must specify every form field name that will be posted by the browser. If you omit a form field sent by the browser, Amazon S3 will reject the request. You can specify accepted form field values three ways:Field Equals
You can specify that a form field must be a certain value. Simply pass an option like
:content_type
to the constructor, or call the associated method.If any of the given values are changed by the user in the form, then Amazon S3 will reject the POST request.
Field Starts With
You can specify prefix values for many of the POST form fields. To specify a required prefix, use the
:<fieldname>_starts_with
option or call the associated#<field_name>_starts_with
method.When using starts with, the form must contain a field where the user can specify the value. The
PresignedPost
will not add a value for these fields.Any Field Value
To white-list a form field to send any value, you can name that field with
:allow_any
or#allow_any
.Metadata
You can add rules for metadata fields using
:metadata
,#metadata
,:metadata_starts_with
and#metadata_starts_with
. Unlike other form fields, you pass a hash value to these options/methods:The
${filename}
VariableThe string
${filename}
is automatically replaced with the name of the file provided by the user and is recognized by all form fields. It is not supported withstarts_with
conditions.If the browser or client provides a full or partial path to the file, only the text following the last slash (/) or backslash () will be used (e.g., "C:\Program Files\directory1\file.txt" will be interpreted as "file.txt"). If no file or file name is provided, the variable is replaced with an empty string.
In the following example, we use
${filename}
to store the original filename in thex-amz-meta-
hash with the uploaded object.See #720.