Module: S3

Defined in:
lib/s3sync/S3_s3sync_mod.rb,
lib/s3sync/S3.rb

Overview

this module has two big classes: AWSAuthConnection and QueryStringAuthGenerator. both use identical apis, but the first actually performs the operation, while the second simply outputs urls with the appropriate authentication query string parameters, which could be used in another tool (such as your web browser for GETs).

Defined Under Namespace

Modules: CallingFormat Classes: AWSAuthConnection, Bucket, CommonPrefixEntry, GetResponse, ListAllMyBucketsParser, ListAllMyBucketsResponse, ListBucketParser, ListBucketResponse, ListEntry, ListProperties, Owner, QueryStringAuthGenerator, Response, S3Object

Constant Summary collapse

DEFAULT_HOST =
's3.amazonaws.com'
PORTS_BY_SECURITY =
{ true => 443, false => 80 }
METADATA_PREFIX =
'x-amz-meta-'
AMAZON_HEADER_PREFIX =
'x-amz-'

Class Method Summary collapse

Class Method Details

.canonical_string(method, bucket = "", path = "", path_args = {}, headers = {}, expires = nil) ⇒ Object

builds the canonical string for signing.



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/s3sync/S3.rb', line 41

def S3.canonical_string(method, bucket="", path="", path_args={}, headers={}, expires=nil)
  interesting_headers = {}
  headers.each do |key, value|
    lk = key.downcase
    if (lk == 'content-md5' or
        lk == 'content-type' or
        lk == 'date' or
        lk =~ /^#{AMAZON_HEADER_PREFIX}/o)
      interesting_headers[lk] = value.to_s.strip
    end
  end

  # these fields get empty strings if they don't exist.
  interesting_headers['content-type'] ||= ''
  interesting_headers['content-md5'] ||= ''

  # just in case someone used this.  it's not necessary in this lib.
  if interesting_headers.has_key? 'x-amz-date'
    interesting_headers['date'] = ''
  end

  # if you're using expires for query string auth, then it trumps date
  # (and x-amz-date)
  if not expires.nil?
    interesting_headers['date'] = expires
  end

  buf = "#{method}\n"
  interesting_headers.sort { |a, b| a[0] <=> b[0] }.each do |key, value|
    if key =~ /^#{AMAZON_HEADER_PREFIX}/o
      buf << "#{key}:#{value}\n"
    else
      buf << "#{value}\n"
    end
  end

  # build the path using the bucket and key
  if not bucket.empty?
    buf << "/#{bucket}"
  end
  # append the key (it might be empty string) 
  # append a slash regardless
  buf << "/#{path}"

  # if there is an acl, logging, or torrent parameter
  # add them to the string
  if path_args.has_key?('acl')
    buf << '?acl'
  elsif path_args.has_key?('torrent')
    buf << '?torrent'
  elsif path_args.has_key?('location')
    buf << '?location'
  elsif path_args.has_key?('logging')
    buf << '?logging'
  end

  return buf
end

.encode(aws_secret_access_key, str, urlencode = false) ⇒ Object

encodes the given string with the aws_secret_access_key, by taking the hmac-sha1 sum, and then base64 encoding it. optionally, it will also url encode the result of that to protect the string if it’s going to be used as a query string parameter.



104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/s3sync/S3.rb', line 104

def S3.encode(aws_secret_access_key, str, urlencode=false)
  digest = OpenSSL::Digest::Digest.new('sha1')
  b64_hmac =
    Base64.encode64(
                    OpenSSL::HMAC.digest(digest, aws_secret_access_key, str)).strip

  if urlencode
    return CGI::escape(b64_hmac)
  else
    return b64_hmac
  end
end

.path_args_hash_to_string(path_args = {}) ⇒ Object

build the path_argument string



118
119
120
121
122
123
124
125
126
127
128
# File 'lib/s3sync/S3.rb', line 118

def S3.path_args_hash_to_string(path_args={})
  arg_string = ''
  path_args.each { |k, v|
    arg_string << k
    if not v.nil?
      arg_string << "=#{CGI::escape(v)}"
    end
    arg_string << '&'
  }
  return arg_string
end