class Aws::S3::PresignedPost


“‘
})
}
’original-filename’: ‘${filename}’
metadata: {
key: ‘/fixed/key’,
post = Aws::S3::PresignedPost.new(creds, region, bucket, {
“‘ruby
filename in the `x-amz-meta-` hash with the uploaded object.
In the following example, we use `${filename}` to store the original
replaced with an empty string.
as “file.txt”). If no file or file name is provided, the variable is
(e.g., “C:Program Filesdirectory1file.txt” will be interpreted
only the text following the last slash (/) or backslash () will be used
If the browser or client provides a full or partial path to the file,
not supported with `starts_with` conditions.
file provided by the user and is recognized by all form fields. It is
The string `${filename}` is automatically replaced with the name of the
### The `${filename}` Variable
“`
#=> ’bar’
post.fields[‘x-amz-meta-foo’]

metadata(foo: ‘bar’)
key(‘/fixed/key’).
post = Aws::S3::PresignedPost.new(creds, region, bucket).
“‘ruby
form fields, you pass a hash value to these options/methods:
`:metadata_starts_with` and {#metadata_starts_with}. Unlike other
You can add rules for metadata fields using `:metadata`, {#metadata},
### Metadata
“`
})
# …
allow_any: [’Filename’],
key: ‘object-key’,
post = Aws::S3::PresignedPost.new(creds, region, bucket, {
“‘ruby
field with `:allow_any` or {#allow_any}.
To white-list a form field to send any value, you can name that
### Any Field Value
a value for these fields.
user can specify the value. The {PresignedPost} will not add
When using starts with, the form must contain a field where the
“`
})
# …
content_type_starts_with: ’image/‘,
key_starts_with: ’/images/‘,
post = Aws::S3::PresignedPost.new(creds, region, bucket, {
“`ruby
option or call the associated `#<field_name>_starts_with` method.
To specify a required prefix, use the `:<fieldname>_starts_with`
You can specify prefix values for many of the POST form fields.
### Field Starts With
Amazon S3 will reject the POST request.
If any of the given values are changed by the user in the form, then
“`
post.content_type(’text/plain’)
post = Aws::S3::PresignedPost.new(creds, region, bucket)
“‘ruby
or call the associated method.
Simply pass an option like `:content_type` to the constructor,
You can specify that a form field must be a certain value.
### Field Equals
* Specify the field may have any value.
* Specify what value the field starts with.
* Specify exactly what the value must be.
You can specify accepted form field values three ways:
field sent by the browser, Amazon S3 will reject the request.
field name that will be posted by the browser. If you omit a form
When you construct a {PresignedPost}, you must specify every form
## Post Policy
“`
<input type=“file” name=“file”/>
“`erb
Lastly, the form must have a file field with the name `file`.
“`
<% end %>
<input type=“hidden” name=“<%= name %>” value=“<%= value %>”/>
<% @post.fields.each do |name, value| %>
“`erb
the form. Typically these are rendered as hidden input fields.
The {#fields} method returns a hash of form fields to render inside
### Form Fields
* `enctype` - This must be `multipart/form-data`.
* `method` - This must be `post`.
* `action` - This must be the {#url}.
The follow attributes must be set on the form:
“`
</form>

<form action=“<%= @post.url %>” method=“post” enctype=“multipart/form-data”>
“`erb
as the form action.
a post form. The {#url} method returns the value you should use
To upload a file to Amazon S3 using a browser, you need to create
### Form Tag
tags that properly escapes values.
recommended to use some helper to build the form tag and input
You can use a {PresignedPost} object to build an HTML form. It is
## HTML Forms
“`
#=> { … }
fields
metadata(’original-filename’ => ‘${filename}’).
acl(‘public-read’).
content_length_range(0..1024).
key(‘/uploaded/object/key’).
post = Aws::S3::PresignedPost.new(creds, region, bucket).
#=> { … }
post.fields
})
}
‘original-filename’ => ‘${filename}’
metadata: {
acl: ‘public-read’,
content_length_range: 0..1024,
key: ‘/uploaded/object/key’,
post = Aws::S3::PresignedPost.new(creds, region, bucket, {
“‘ruby
The following two examples are equivalent.
methods such as {#key} and {#content_length_range}.
to the post object as options to {#initialize} or by calling
your bucket is in, and the name of your bucket. You can apply constraints
To generate a presigned post, you need AWS credentials, the region
## Basic Usage
See {Bucket#presigned_post} and {Object#presigned_post}.
@note Normally you do not need to construct a {PresignedPost} yourself.

def self.define_field(field, *args, &block)

Other tags:
    Api: - private
def self.define_field(field, *args, &block)
  @@allowed_fields << field
  options = args.last.is_a?(Hash) ? args.pop : {}
  field_name = args.last || field.to_s
  if block_given?
    define_method("#{field}", block)
  else
    define_method("#{field}") do |value|
      with(field_name, value)
    end
    if options[:starts_with]
      @@allowed_fields << "#{field}_starts_with".to_sym
      define_method("#{field}_starts_with") do |value|
        starts_with(field_name, value)
      end
    end
  end
end

def allow_any(*field_names)

Returns:
  • (self) -

Parameters:
  • field_names (Sting, Array) --
def allow_any(*field_names)
  field_names.flatten.each do |field_name|
    @key_set = true if field_name.to_s == 'key'
    starts_with(field_name, '')
  end
  self
end

def base64(str)

def base64(str)
  Base64.strict_encode64(str)
end

def bucket_url

def bucket_url
  # Taken from Aws::S3::Endpoints module
  params = Aws::S3::EndpointParameters.new(
    bucket: @bucket_name,
    region: @bucket_region,
    accelerate: @accelerate,
    use_global_endpoint: true
  )
  endpoint = Aws::S3::EndpointProvider.new.resolve_endpoint(params)
  endpoint.url
end

def check_required_values!

def check_required_values!
  unless @key_set
    msg = 'key required; you must provide a key via :key, '\
          ":key_starts_with, or :allow_any => ['key']"
    raise msg
  end
end

def credential_scope(datetime)

def credential_scope(datetime)
  parts = []
  parts << @credentials.access_key_id
  parts << datetime[0,8]
  parts << @bucket_region
  parts << 's3'
  parts << 'aws4_request'
  parts.join('/')
end

def fields

Returns:
  • (Hash) - A hash of fields to render in an HTML form
def fields
  check_required_values!
  datetime = Time.now.utc.strftime('%Y%m%dT%H%M%SZ')
  fields = @fields.dup
  fields.update('policy' => policy(datetime))
  fields.update(signature_fields(datetime))
  fields.update('x-amz-signature' => signature(datetime, fields['policy']))
end

def hexhmac(key, value)

def hexhmac(key, value)
  OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), key, value)
end

def hmac(key, value)

def hmac(key, value)
  OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'), key, value)
end

def initialize(credentials, bucket_region, bucket_name, options = {})

Options Hash: (**options)
  • :server_side_encryption_customer_key_starts_with (String) --
  • :server_side_encryption_customer_key (String) --
  • :server_side_encryption_customer_algorithm (String) --
  • :server_side_encryption_aws_kms_key_id (String) --
  • :server_side_encryption (String) --
  • :metadata_starts_with (Hash) --
  • :metadata (Hash) --
  • :website_redirect_location (String) --
  • :storage_class (String) --
  • :success_action_status (String) --
  • :success_action_redirect_starts_with (String) --
  • :success_action_redirect (String) --
  • :content_length_range (Range) --
  • :expires_starts_with (String) --
  • :expires (Time) -- See {PresignedPost#expires}.
  • :content_encoding_starts_with (String) --
  • :content_encoding (String) --
  • :content_disposition_starts_with (String) --
  • :content_disposition (String) --
  • :content_type_starts_with (String) --
  • :content_type (String) -- See {PresignedPost#content_type}.
  • :cache_control_starts_with (String) --
  • :cache_control (String) --
  • :acl_starts_with (String) --
  • :acl (String) -- See {PresignedPost#acl}.
  • :key_starts_with (String) --
  • :key (String) -- See {PresignedPost#key}.
  • :signature_expiration (Time) -- Specify when the signature on
  • :allow_any (Sting, Array) --
  • :url (String) -- See {PresignedPost#url}.
  • :use_accelerate_endpoint (Boolean) -- When `true`,

Parameters:
  • bucket_name (String) -- Name of the target bucket.
  • bucket_region (String) -- Region of the target bucket.
  • credentials (Credentials) -- Security credentials for signing
def initialize(credentials, bucket_region, bucket_name, options = {})
  @credentials = credentials.credentials
  @bucket_region = bucket_region
  @bucket_name = bucket_name
  @accelerate = !!options.delete(:use_accelerate_endpoint)
  options.delete(:url) if @accelerate # resource methods pass url
  @url = options.delete(:url) || bucket_url
  @fields = {}
  @key_set = false
  @signature_expiration = Time.now + 3600
  @conditions = [{ 'bucket' => @bucket_name }]
  options.each do |option_name, option_value|
    case option_name
    when :allow_any then allow_any(option_value)
    when :signature_expiration then @signature_expiration = option_value
    else
      if @@allowed_fields.include?(option_name)
        send("#{option_name}", option_value)
      else
        raise ArgumentError, "Unsupported option: #{option_name}"
      end
    end
  end
end

def policy(datetime)

Returns:
  • (Hash) -
def policy(datetime)
  check_required_values!
  policy = {}
  policy['expiration'] = @signature_expiration.utc.iso8601
  policy['conditions'] = @conditions.dup
  signature_fields(datetime).each do |name, value|
    policy['conditions'] << { name => value }
  end
  base64(Json.dump(policy))
end

def signature(datetime, string_to_sign)

def signature(datetime, string_to_sign)
  k_secret = @credentials.secret_access_key
  k_date = hmac('AWS4' + k_secret, datetime[0,8])
  k_region = hmac(k_date, @bucket_region)
  k_service = hmac(k_region, 's3')
  k_credentials = hmac(k_service, 'aws4_request')
  hexhmac(k_credentials, string_to_sign)
end

def signature_fields(datetime)

def signature_fields(datetime)
  fields = {}
  fields['x-amz-credential'] = credential_scope(datetime)
  fields['x-amz-algorithm'] = 'AWS4-HMAC-SHA256'
  fields['x-amz-date'] = datetime
  if session_token = @credentials.session_token
    fields['x-amz-security-token'] = session_token
  end
  fields
end

def starts_with(field_name, value, &block)

def starts_with(field_name, value, &block)
  @conditions << ['starts-with', "$#{field_name}", value.to_s]
  self
end

def with(field_name, value)

def with(field_name, value)
  fvar = '${filename}'
  if index = value.rindex(fvar)
    if index + fvar.size == value.size
      @fields[field_name] = value
      starts_with(field_name, value[0,index])
    else
      msg = "${filename} only supported at the end of #{field_name}"
      raise ArgumentError, msg
    end
  else
    @fields[field_name] = value.to_s
    @conditions << { field_name => value.to_s }
  end
  self
end