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.



198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/aws/s3/presigned_post.rb', line 198

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

  @fields[:server_side_encryption] =
    config.s3_server_side_encryption unless
    @fields.key?(:server_side_encryption)
  @fields.delete(:server_side_encryption) if
    @fields[:server_side_encryption].nil?
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.



100
101
102
# File 'lib/aws/s3/presigned_post.rb', line 100

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.



96
97
98
# File 'lib/aws/s3/presigned_post.rb', line 96

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).



345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
# File 'lib/aws/s3/presigned_post.rb', line 345

def fields

  secret = config.credential_provider.secret_access_key
  signature = Core::Signer.sign(secret, policy, 'sha1')

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

  if token = config.credential_provider.session_token
    fields["x-amz-security-token"] = token
  end

  fields.merge(optional_fields)

end

#policyString

Returns The Base64-encoded JSON policy document.

Returns:

  • (String)

    The Base64-encoded JSON policy document.



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

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

#secure?Boolean

Returns True if #url generates an HTTPS url.

Returns:

  • (Boolean)

    True if #url generates an HTTPS url.



222
223
224
# File 'lib/aws/s3/presigned_post.rb', line 222

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.



230
231
232
233
234
235
# File 'lib/aws/s3/presigned_post.rb', line 230

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)


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

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.



327
328
329
# File 'lib/aws/s3/presigned_post.rb', line 327

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