class AWS::S3::PresignedPost
bucket.presigned_post.where(:key).starts_with(“photos/”)
@example Restricting the key prefix
bucket.presigned_post(:content_length => 1..(10*1024))
@example Restricting the size of the uploaded object
END
</form>
<input type=“file” name=“file” />
#{hidden_inputs}
<form action=“#{form.url}” method=“post” enctype=“multipart/form-data”>
<<-END
end
%(<input type=“hidden” name=“#{name}” value=“#{value}” />)
hidden_inputs = form.fields.map do |(name, value)|
form = bucket.objects.myobj.presigned_post
@example Generating a minimal HTML form
form.fields # => { “AWSAccessKeyId” => “…”, … }
form.url.to_s # => “mybucket.s3.amazonaws.com/”
form = bucket.presigned_post(:key => “photos/${filename}”)
@example Form fields for uploading by file name
stored.
conditions on what can be uploaded and how it is processed and
from a web browser to upload objects to S3 while specifying
a bucket. You can use this to create a form that can be used
Helper to generate form fields for presigned POST requests to
def build_uri(request)
def build_uri(request) uri_class = secure? ? URI::HTTPS : URI::HTTP uri_class.build(:host => request.host, :path => request.path, :query => request.querystring) end
def field_name(option_name)
def field_name(option_name) case option_name when :expires_header "Expires" when :server_side_encryption "x-amz-server-side-encryption" when :key, "Key", :policy, "Policy" option_name.to_s.downcase when :acl, :success_action_redirect, :success_action_status option_name.to_s else # e.g. Cache-Control from cache_control field_name = option_name.to_s.tr("_", "-"). gsub(/-(.)/) { |m| m.upcase } field_name[0,1] = field_name[0,1].upcase field_name end end
def field_value(option_name)
def field_value(option_name) case option_name when :acl @fields[:acl].to_s.tr("_", "-") when :server_side_encryption value = @fields[:server_side_encryption] if value.kind_of?(Symbol) value.to_s.upcase else value.to_s end else @fields[option_name].to_s end end
def fields
-
(Hash)
- A collection of form fields (including a
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
def format_expiration
def format_expiration time = expires || Time.now.utc + 60*60 time = case time when Time time when DateTime Time.parse(time.to_s) when Integer (Time.now + time) when String Time.parse(time) end time.utc.iso8601 end
def generate_conditions
def generate_conditions conditions = self.conditions.inject([]) do |list, (field, field_conds)| list + field_conds end conditions << { "bucket" => bucket.name } conditions += key_conditions conditions += optional_fields.map { |(n, v)| Hash[[[n, v]]] } conditions += range_conditions conditions += ignored_conditions if token = config.credential_provider.session_token conditions << { "x-amz-security-token" => token } end conditions end
def ignored_conditions
def ignored_conditions ignored_fields.map do |field| ["starts-with", "$#{field}", ""] end end
def initialize(bucket, opts = {})
(**opts)
-
:ignore
(Array
) -- Additional fields which -
:content_length
(Integer, Range
) -- The range of -
:metadata
(Hash
) -- A hash of the metadata fields -
:success_action_status
(Integer
) -- The status -
:success_action_redirect
(String
) -- The URL to -
:server_side_encryption
(Symbol
) -- If this -
:acl
(Symbol
) -- A canned access control -
:expires_header
(String
) -- Sets the Expires -
:content_disposition
(String
) -- Sets the -
:content_type
(String
) -- Sets the Content-Type -
:cache_control
(String
) -- Sets the Cache-Control -
:expires
(Time, DateTime, Integer, String
) -- The -
:secure
(Boolean
) -- By setting this to false, you -
:key
(String
) -- The key of the object that will
Parameters:
-
opts
(Hash
) -- Additional options for the upload. Aside -
bucket
(Bucket
) -- The bucket to which data can be uploaded
def initialize(bucket, opts = {}) @bucket = bucket @key = opts[:key] @secure = (opts[:secure] != false) @fields = {} # TODO normalize all values to @fields opts.each do |opt_key, opt_val| @fields[opt_key] = opt_val unless SPECIAL_FIELDS.include? opt_key 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
def key_conditions
def key_conditions [if key && key.include?("${filename}") ["starts-with", "$key", key[/^(.*)\$\{filename\}/, 1]] elsif key { "key" => key } else ["starts-with", "$key", ""] end] end
def optional_fields
def optional_fields fields = @fields.keys.inject({}) do |fields, option_name| fields[field_name(option_name)] = field_value(option_name) fields end @metadata.each do |key, value| fields["x-amz-meta-#{key}"] = value.to_s end fields end
def policy
-
(String)
- The Base64-encoded JSON policy document.
def policy json = { "expiration" => format_expiration, "conditions" => generate_conditions }.to_json Base64.encode64(json).tr("\n","") end
def range_conditions
def range_conditions if content_length [["content-length-range", *split_range(content_length)]] else [] end end
def range_value(range)
def range_value(range) case range when Integer range..range when Range range end end
def refine(opts)
- Api: - private
def refine(opts) self.class.new(bucket, { :conditions => conditions, :key => key, :metadata => metadata, :secure => secure?, :content_length => content_length, :expires => expires, :ignore => ignored_fields }.merge(@fields). merge(opts)) end
def secure?
-
(Boolean)
- True if {#url} generates an HTTPS url.
def secure? @secure end
def split_range(range)
def split_range(range) range = range_value(range) [range.begin, (range.exclude_end? ? range.end-1 : range.end)] end
def url
-
(URI::HTTP, URI::HTTPS)
- The URL to which the form
def url req = Request.new req.bucket = bucket.name req.host = config.s3_endpoint build_uri(req) end
def where(field)
-
(ConditionBuilder)
- An object that allows you to
Parameters:
-
field
(Symbol
) -- The field for which a condition should
Other tags:
- Example: Restricting the ACL to "bucket-owner" ACLs -
def where(field) ConditionBuilder.new(self, field) end
def where_metadata(field)
-
(ConditionBuilder)
- An object that allows you to
Parameters:
-
field
(Symbol, String
) -- The name of the metadata
def where_metadata(field) where("x-amz-meta-#{field}") end
def with_condition(field, condition)
def with_condition(field, condition) conditions = self.conditions.dup (conditions[field] ||= []) << condition refine(:conditions => conditions) end
def with_equality_condition(option_name, value)
- Api: - private
def with_equality_condition(option_name, value) field_name = field_name(option_name) with_condition(option_name, Hash[[[field_name, value]]]) end
def with_prefix_condition(option_name, prefix)
- Api: - private
def with_prefix_condition(option_name, prefix) field_name = field_name(option_name) with_condition(option_name, ["starts-with", "$#{field_name}", prefix]) end