moduleAwsmoduleS3# Allows you to create presigned URLs for S3 operations.## Example Use:## signer = Aws::S3::Presigner.new# url = signer.presigned_url(:get_object, bucket: "bucket", key: "key")#classPresigner# @api privateONE_WEEK=60*60*24*7# @api privateFIFTEEN_MINUTES=60*15BLACKLISTED_HEADERS=['accept','cache-control','content-length',# due to a ELB bug'expect','from','if-match','if-none-match','if-modified-since','if-unmodified-since','if-range','max-forwards','pragma','proxy-authorization','referer','te','user-agent'].freeze# @option options [Client] :client Optionally provide an existing# S3 clientdefinitialize(options={})@client=options[:client]||Aws::S3::Client.newend# @param [Symbol] method Symbolized method name of the operation you want# to presign.## @option params [Integer] :expires_in (900) The number of seconds# before the presigned URL expires. Defaults to 15 minutes. As signature# version 4 has a maximum expiry time of one week for presigned URLs,# attempts to set this value to greater than one week (604800) will# raise an exception.## @option params [Time] :time (Time.now) The starting time for when the# presigned url becomes active.## @option params [Boolean] :secure (true) When `false`, a HTTP URL# is returned instead of the default HTTPS URL.## @option params [Boolean] :virtual_host (false) When `true`, the# bucket name will be used as the hostname. This will cause# the returned URL to be 'http' and not 'https'.## @option params [Boolean] :use_accelerate_endpoint (false) When `true`,# Presigner will attempt to use accelerated endpoint.## @option params [Array<String>] :whitelist_headers ([]) Additional# headers to be included for the signed request. Certain headers beyond# the authorization header could, in theory, be changed for various# reasons (including but not limited to proxies) while in transit and# after signing. This would lead to signature errors being returned,# despite no actual problems with signing. (see BLACKLISTED_HEADERS)## @raise [ArgumentError] Raises an ArgumentError if `:expires_in`# exceeds one week.#defpresigned_url(method,params={})ifparams[:key].nil?orparams[:key]==''raiseArgumentError,":key must not be blank"endvirtual_host=!!params.delete(:virtual_host)time=params.delete(:time)whitelisted_headers=params.delete(:whitelist_headers)||[]unsigned_headers=BLACKLISTED_HEADERS-whitelisted_headersscheme=http_scheme(params,virtual_host)req=@client.build_request(method,params)use_bucket_as_hostname(req)ifvirtual_hostsign_but_dont_send(req,expires_in(params),scheme,time,unsigned_headers)req.send_request.dataendprivatedefhttp_scheme(params,virtual_host)ifparams.delete(:secure)==false||virtual_host'http'else@client.config.endpoint.schemeendenddefexpires_in(params)if(expires_in=params.delete(:expires_in))ifexpires_in>ONE_WEEKmsg="expires_in value of #{expires_in} exceeds one-week maximum"raiseArgumentError,msgendexpires_inelseFIFTEEN_MINUTESendenddefuse_bucket_as_hostname(req)req.handlers.remove(Plugins::BucketDns::Handler)req.handledo|context|uri=context.http_request.endpointuri.host=context.params[:bucket]uri.path.sub!("/#{context.params[:bucket]}",'')uri.scheme='http'uri.port=80@handler.call(context)endend# @param [Seahorse::Client::Request] reqdefsign_but_dont_send(req,expires_in,scheme,time,unsigned_headers)http_req=req.context.http_requestreq.handlers.remove(Aws::S3::Plugins::S3Signer::LegacyHandler)req.handlers.remove(Aws::S3::Plugins::S3Signer::V4Handler)req.handlers.remove(Seahorse::Client::Plugins::ContentLength::Handler)signer=build_signer(req.context.config,unsigned_headers)req.context[:presigned_url]=truereq.handle(step: :send)do|context|ifscheme!=http_req.endpoint.schemeendpoint=http_req.endpoint.dupendpoint.scheme=schemeendpoint.port=(scheme=='http'?80:443)http_req.endpoint=URI.parse(endpoint.to_s)end# hoist x-amz-* headers to the querystringquery=http_req.endpoint.query?http_req.endpoint.query.split('&'):[]http_req.headers.keys.eachdo|key|ifkey.match(/^x-amz/i)value=Aws::Sigv4::Signer.uri_escape(http_req.headers.delete(key))key=Aws::Sigv4::Signer.uri_escape(key)query<<"#{key}=#{value}"endendhttp_req.endpoint.query=query.join('&')unlessquery.empty?url=signer.presign_url(http_method: http_req.http_method,url: http_req.endpoint,headers: http_req.headers,body_digest: 'UNSIGNED-PAYLOAD',expires_in: expires_in,time: time).to_sSeahorse::Client::Response.new(context: context,data: url)endenddefbuild_signer(cfg,unsigned_headers)Aws::Sigv4::Signer.new(service: 's3',region: cfg.region,credentials_provider: cfg.credentials,unsigned_headers: unsigned_headers,uri_escape_path: false)endendendend