Class: AWS::S3::PresignedPost

Inherits:
Object
  • Object
show all
Defined in:
lib/aws/s3/presigned_post.rb

Overview

Helper to generate form fields for presigned POST requests to a bucket. You can use this to create a form that can be used from a web browser to upload objects to S3 while specifying conditions on what can be uploaded and how it is processed and stored.

Examples:

Form fields for uploading by file name

form = bucket.presigned_post(:key => "photos/${filename}")
form.url.to_s        # => "https://mybucket.s3.amazonaws.com/"
form.fields          # => { "AWSAccessKeyId" => "...", ... }

Generating a minimal HTML form

form = bucket.objects.myobj.presigned_post
hidden_inputs = form.fields.map do |(name, value)|
  %(<input type="hidden" name="#{name}" value="#{value}" />)
end
<<-END
<form action="#{form.url}"
      method="post"
      enctype="multipart/form-data">
  #{hidden_inputs}
  <input type="file" name="file" />
</form>
END

Restricting the size of the uploaded object

bucket.presigned_post(:content_length => 1..(10*1024))

Restricting the key prefix

bucket.presigned_post.where(:key).starts_with("photos/")

Defined Under Namespace

Classes: ConditionBuilder

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(bucket, opts = {}) ⇒ PresignedPost

Creates a new presigned post object.

Parameters:

  • bucket (Bucket)

    The bucket to which data can be uploaded using the form fields.

  • opts (Hash) (defaults to: {})

    Additional options for the upload. Aside from :secure, :expires, :content_length and :ignore the values provided here will be stored in the hash returned from the #fields method, and the policy in that hash will restrict their values to the values provided. If you instead want to only restrict the values and not provide them – for example, if your application generates separate form fields for those values – you should use the #where method on the returned object instead of providing the values here.

  • options (Hash)

    a customizable set of options

Options Hash (opts):

  • :key (String)

    The key of the object that will be uploaded. If this is nil, then the object can be uploaded with any key that satisfies the conditions specified for the upload (see #where).

  • :secure (Boolean)

    By setting this to false, you can cause #url to return an HTTP URL. By default it returns an HTTPS URL.

  • :expires (Time, DateTime, Integer, String)

    The time at which the signature will expire. By default the signature will expire one hour after it is generated (e.g. when #fields is called).

    When the value is a Time or DateTime, the signature expires at the specified time. When it is an integer, the signature expires the specified number of seconds after it is generated. When it is a string, the string is parsed as a time (using Time.parse) and the signature expires at that time.

  • :cache_control (String)

    Sets the Cache-Control header stored with the object.

  • :content_type (String)

    Sets the Content-Type header stored with the object.

  • :content_disposition (String)

    Sets the Content-Disposition header stored with the object.

  • :expires_header (String)

    Sets the Expires header stored with the object.

  • :success_action_redirect (String)

    The URL to which the client is redirected upon successful upload.

  • :success_action_status (Integer)

    The status code returned to the client upon successful upload if :success_action_redirect is not specified. Accepts the values 200, 201, or 204 (default).

    If the value is set to 200 or 204, Amazon S3 returns an empty document with a 200 or 204 status code.

    If the value is set to 201, Amazon S3 returns an XML document with a 201 status code. For information on the content of the XML document, see POST Object.

  • :metadata (Hash)

    A hash of the metadata fields included in the signed fields. Additional metadata fields may be provided with the upload as long as they satisfy the conditions specified for the upload (see #where).

  • :content_length (Integer, Range)

    The range of acceptable object sizes for the upload. By default any size object may be uploaded.

  • :ignore (Array<String>)

    Additional fields which may be sent with the upload. These will be included in the policy so that they can be sent with any value. S3 will ignore them.



187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/aws/s3/presigned_post.rb', line 187

def initialize(bucket, opts = {})
  @bucket = bucket
  @key = opts[:key]
  @secure = (opts[:secure] != false)
  @fields = {}
  SPECIAL_FIELDS.each do |name|
    @fields[name] = opts[name] if opts.key?(name)
  end
  @metadata = opts[:metadata] || {}
  @content_length = range_value(opts[:content_length])
  @conditions = opts[:conditions] || {}
  @ignored_fields = [opts[:ignore]].flatten.compact
  @expires = opts[:expires]

  super
end

Instance Attribute Details

#bucketBucket (readonly)

Returns The bucket to which data can be uploaded using the form fields.

Returns:

  • (Bucket)

    The bucket to which data can be uploaded using the form fields



59
60
61
# File 'lib/aws/s3/presigned_post.rb', line 59

def bucket
  @bucket
end

#content_lengthRange (readonly)

Returns The range of acceptable object sizes for the upload. By default any size object may be uploaded.

Returns:

  • (Range)

    The range of acceptable object sizes for the upload. By default any size object may be uploaded.



75
76
77
# File 'lib/aws/s3/presigned_post.rb', line 75

def content_length
  @content_length
end

#expiresObject (readonly)

Returns The expiration time for the signature. By default the signature will expire an hour after it is generated.

Returns:

  • The expiration time for the signature. By default the signature will expire an hour after it is generated.



98
99
100
# File 'lib/aws/s3/presigned_post.rb', line 98

def expires
  @expires
end

#ignored_fieldsArray<String> (readonly)

Returns Additional fields which may be sent with the upload. These will be included in the policy so that they can be sent with any value. S3 will ignore them.

Returns:

  • (Array<String>)

    Additional fields which may be sent with the upload. These will be included in the policy so that they can be sent with any value. S3 will ignore them.



94
95
96
# File 'lib/aws/s3/presigned_post.rb', line 94

def ignored_fields
  @ignored_fields
end

#keyString (readonly)

Returns The key of the object that will be uploaded. If this is nil, then the object can be uploaded with any key that satisfies the conditions specified for the upload (see #where).

Returns:

  • (String)

    The key of the object that will be uploaded. If this is nil, then the object can be uploaded with any key that satisfies the conditions specified for the upload (see #where).



65
66
67
# File 'lib/aws/s3/presigned_post.rb', line 65

def key
  @key
end

#metadataHash (readonly)

Returns A hash of the metadata fields included in the signed fields. Additional metadata fields may be provided with the upload as long as they satisfy the conditions specified for the upload (see #where).

Returns:

  • (Hash)

    A hash of the metadata fields included in the signed fields. Additional metadata fields may be provided with the upload as long as they satisfy the conditions specified for the upload (see #where).



71
72
73
# File 'lib/aws/s3/presigned_post.rb', line 71

def 
  @metadata
end

Instance Method Details

#fieldsHash

Returns A collection of form fields (including a signature and a policy) that can be used to POST data to S3. Additional form fields may be added after the fact as long as they are described by a policy condition (see #where).

Returns:

  • (Hash)

    A collection of form fields (including a signature and a policy) that can be used to POST data to S3. Additional form fields may be added after the fact as long as they are described by a policy condition (see #where).



328
329
330
331
332
333
334
335
336
337
338
# File 'lib/aws/s3/presigned_post.rb', line 328

def fields
  signature =
    config.signer.sign(policy, "sha1")

  {
    "AWSAccessKeyId" => config.signer.access_key_id,
    "key" => key,
    "policy" => policy,
    "signature" => signature
  }.merge(optional_fields)
end

#policyString

Returns The Base64-encoded JSON policy document.

Returns:

  • (String)

    The Base64-encoded JSON policy document.



315
316
317
318
319
320
321
# File 'lib/aws/s3/presigned_post.rb', line 315

def policy
  json = {
    "expiration" => format_expiration,
    "conditions" => generate_conditions
  }.to_json
  Base64.encode64(json)
end

#secure?Boolean

Returns True if #url generates an HTTPS url.

Returns:

  • (Boolean)

    True if #url generates an HTTPS url.



205
206
207
# File 'lib/aws/s3/presigned_post.rb', line 205

def secure?
  @secure
end

#urlURI::HTTP, URI::HTTPS

Returns The URL to which the form fields should be POSTed. If you are using the fields in an HTML form, this is the URL to put in the action attribute of the form tag.

Returns:

  • (URI::HTTP, URI::HTTPS)

    The URL to which the form fields should be POSTed. If you are using the fields in an HTML form, this is the URL to put in the action attribute of the form tag.



213
214
215
216
217
218
# File 'lib/aws/s3/presigned_post.rb', line 213

def url
  req = Request.new
  req.bucket = bucket.name
  req.host = config.s3_endpoint
  build_uri(req)
end

#where(field) ⇒ ConditionBuilder

Adds a condition to the policy for the POST. Use #where_metadata to add metadata conditions.

Examples:

Restricting the ACL to “bucket-owner” ACLs

presigned_post.where(:acl).starts_with("bucket-owner")

Parameters:

  • field (Symbol)

    The field for which a condition should be added. Valid values:

    • :key

    • :content_length

    • :cache_control

    • :content_type

    • :content_disposition

    • :content_encoding

    • :expires_header

    • :acl

    • :success_action_redirect

    • :success_action_status

Returns:

  • (ConditionBuilder)

    An object that allows you to specify a condition on the field.

Raises:

  • (ArgumentError)


291
292
293
294
295
296
# File 'lib/aws/s3/presigned_post.rb', line 291

def where(field)
  raise ArgumentError.new("unrecognized field name #{field}") unless
    [:key, :content_length, *SPECIAL_FIELDS].include?(field) or
    field =~ /^x-amz-meta-/
  ConditionBuilder.new(self, field)
end

#where_metadata(field) ⇒ ConditionBuilder

Adds a condition to the policy for the POST to constrain the values of metadata fields uploaded with the object. If a metadata field does not have a condition associated with it and is not specified in the constructor (see #metadata) then S3 will reject it.

Parameters:

  • field (Symbol, String)

    The name of the metadata attribute. For example, :color corresponds to the “x-amz-meta-color” field in the POST body.

Returns:

  • (ConditionBuilder)

    An object that allows you to specify a condition on the metadata attribute.



310
311
312
# File 'lib/aws/s3/presigned_post.rb', line 310

def (field)
  where("x-amz-meta-#{field}")
end