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
"<form action=\"\#{form.url}\" method=\"post\" enctype=\"multipart/form-data\">\n  \#{hidden_inputs}\n  <input type=\"file\" name=\"file\" />\n</form>\n"

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.

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.



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

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



57
58
59
# File 'lib/aws/s3/presigned_post.rb', line 57

def bucket
  @bucket
end

#content_lengthRange (readonly)



73
74
75
# File 'lib/aws/s3/presigned_post.rb', line 73

def content_length
  @content_length
end

#expiresObject (readonly)



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

def expires
  @expires
end

#ignored_fieldsArray<String> (readonly)



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

def ignored_fields
  @ignored_fields
end

#keyString (readonly)



63
64
65
# File 'lib/aws/s3/presigned_post.rb', line 63

def key
  @key
end

#metadataHash (readonly)



69
70
71
# File 'lib/aws/s3/presigned_post.rb', line 69

def 
  
end

Instance Method Details

#fieldsHash



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

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



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

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

#secure?Boolean



220
221
222
# File 'lib/aws/s3/presigned_post.rb', line 220

def secure?
  @secure
end

#urlURI::HTTP, URI::HTTPS



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

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

Raises:

  • (ArgumentError)


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

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.



325
326
327
# File 'lib/aws/s3/presigned_post.rb', line 325

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