class Aws::Signers::S3

def self.sign(context)

def self.sign(context)
  new(
    context.config.credentials,
    context.params,
    context.config.force_path_style
  ).sign(context.http_request)
end

def authorization(request)

def authorization(request)
  "AWS #{credentials.access_key_id}:#{signature(request)}"
end

def canonicalized_headers(request)


is generated.
See the developer guide for more information on how this element

CanonicalizedAmzHeaders
def canonicalized_headers(request)
  x_amz = request.headers.select{|k, v| k =~ /^x-amz-/i }
  x_amz = x_amz.collect{|k, v| [k.downcase, v] }
  x_amz = x_amz.sort_by{|k, v| k }
  x_amz = x_amz.collect{|k, v| "#{k}:#{v.to_s.strip}" }.join("\n")
  x_amz == '' ? nil : x_amz
end

def canonicalized_resource(endpoint)

Other tags:
    Api: - private
def canonicalized_resource(endpoint)
  parts = []
  # virtual hosted-style requests require the hostname to appear
  # in the canonicalized resource prefixed by a forward slash.
  if bucket = params[:bucket]
    bucket = bucket.value
    ssl = endpoint.scheme == 'https'
    if Plugins::S3BucketDns.dns_compatible?(bucket, ssl) && !@force_path_style
      parts << "/#{bucket}"
    end
  end
  # append the path name (no querystring)
  parts << endpoint.path
  # lastly any sub resource querystring params need to be appened
  # in lexigraphical ordered joined by '&' and prefixed by '?'
  params = signed_querystring_params(endpoint)
  unless params.empty?
    parts << '?'
    parts << params.sort.collect{|p| p.to_s }.join('&')
  end
  parts.join
end

def digest(secret, string_to_sign)

def digest(secret, string_to_sign)
  Base64.encode64(hmac(secret, string_to_sign)).strip
end

def hmac(key, value)

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

def initialize(credentials, params, force_path_style)

Parameters:
  • credentials (CredentialProvider) --
def initialize(credentials, params, force_path_style)
  @credentials = credentials.credentials
  @params = Query::ParamList.new
  params.each_pair do |param_name, param_value|
    @params.set(param_name, param_value)
  end
  @force_path_style = force_path_style
end

def sign(request)

def sign(request)
  if token = credentials.session_token
    request.headers["X-Amz-Security-Token"] = token
  end
  request.headers['Authorization'] = authorization(request)
end

def signature(request)

def signature(request)
  string_to_sign = string_to_sign(request)
  signature = digest(credentials.secret_access_key, string_to_sign)
  uri_escape(signature)
end

def signed_querystring_params(endpoint)

def signed_querystring_params(endpoint)
  endpoint.query.to_s.split('&').select do |p|
    SIGNED_QUERYSTRING_PARAMS.include?(p.split('=')[0])
  end.map { |p| CGI.unescape(p) }
end

def signing_string_date(request)

def signing_string_date(request)
  # if a date is provided via x-amz-date then we should omit the
  # Date header from the signing string (should appear as a blank line)
  if request.headers.detect{|k,v| k.to_s =~ /^x-amz-date$/i }
    ''
  else
    request.headers['Date'] = Time.now.httpdate
  end
end

def string_to_sign(request)


CanonicalizedAmzHeaders + CanonicalizedResource;
date ` "\n" `
content-type ` "\n" `
content-md5 ` "\n" `
HTTP-Verb ` "\n" `
StringToSign =

From the S3 developer guide:
def string_to_sign(request)
  [
    request.http_method,
    request.headers.values_at('Content-Md5', 'Content-Type').join("\n"),
    signing_string_date(request),
    canonicalized_headers(request),
    canonicalized_resource(request.endpoint),
  ].flatten.compact.join("\n")
end

def uri_escape(s)

def uri_escape(s)
  #URI.escape(s)
  # URI.escape is deprecated, replacing it with escape from webrick
  # to squelch the massive number of warnings generated from Ruby.
  # The following script was used to determine the differences
  # between the various escape methods available. The webrick
  # escape only had two differences and it is available in the
  # standard lib.
  #
  #     (0..255).each {|c|
  #       s = [c].pack("C")
  #       e = [
  #         CGI.escape(s),
  #         ERB::Util.url_encode(s),
  #         URI.encode_www_form_component(s),
  #         WEBrick::HTTPUtils.escape_form(s),
  #         WEBrick::HTTPUtils.escape(s),
  #         URI.escape(s),
  #       ]
  #       next if e.uniq.length == 1
  #       puts("%5s %5s %5s %5s %5s %5s %5s" % ([s.inspect] + e))
  #     }
  #
  WEBrick::HTTPUtils.escape(s).gsub('%5B', '[').gsub('%5D', ']')
end