aws-sdk 1.3.7 → 1.3.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/aws/core.rb +2 -1
- data/lib/aws/core/authorize_v2.rb +1 -1
- data/lib/aws/core/authorize_v3.rb +1 -1
- data/lib/aws/core/authorize_v4.rb +149 -0
- data/lib/aws/core/client.rb +31 -13
- data/lib/aws/core/configuration.rb +26 -2
- data/lib/aws/core/http/curb_handler.rb +4 -5
- data/lib/aws/core/http/httparty_handler.rb +5 -4
- data/lib/aws/core/http/request.rb +22 -0
- data/lib/aws/iam/request.rb +7 -1
- metadata +5 -4
data/lib/aws/core.rb
CHANGED
@@ -59,7 +59,7 @@ require 'aws/core/autoloader'
|
|
59
59
|
module AWS
|
60
60
|
|
61
61
|
# Current version of the AWS SDK for Ruby
|
62
|
-
VERSION = "1.3.
|
62
|
+
VERSION = "1.3.8"
|
63
63
|
|
64
64
|
register_autoloads(self) do
|
65
65
|
autoload :Errors, 'errors'
|
@@ -72,6 +72,7 @@ module AWS
|
|
72
72
|
autoload :AsyncHandle, 'async_handle'
|
73
73
|
autoload :AuthorizeV2, 'authorize_v2'
|
74
74
|
autoload :AuthorizeV3, 'authorize_v3'
|
75
|
+
autoload :AuthorizeV4, 'authorize_v4'
|
75
76
|
autoload :AuthorizeWithSessionToken, 'authorize_with_session_token'
|
76
77
|
autoload :Cacheable, 'cacheable'
|
77
78
|
autoload :Client, 'client'
|
@@ -0,0 +1,149 @@
|
|
1
|
+
# Copyright 2011-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
4
|
+
# may not use this file except in compliance with the License. A copy of
|
5
|
+
# the License is located at
|
6
|
+
#
|
7
|
+
# http://aws.amazon.com/apache2.0/
|
8
|
+
#
|
9
|
+
# or in the "license" file accompanying this file. This file is
|
10
|
+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
11
|
+
# ANY KIND, either express or implied. See the License for the specific
|
12
|
+
# language governing permissions and limitations under the License.
|
13
|
+
|
14
|
+
# - docs don't match in task 2 between the sample and the detailed
|
15
|
+
# instructions, is the canonical request hex/hashed or just hexed?
|
16
|
+
# - the hashing method is never defined, is it a md5 hash?
|
17
|
+
# - the documentation does not discuss how to add the authorization
|
18
|
+
# to your get or post request, 2 simple examples are provided, but with
|
19
|
+
# no information about how to join the parts in the post request
|
20
|
+
# (not clear about spaces vs newlines, etc)
|
21
|
+
# - document does not displ
|
22
|
+
|
23
|
+
require 'time'
|
24
|
+
require 'openssl'
|
25
|
+
require 'digest'
|
26
|
+
|
27
|
+
# bug resigning
|
28
|
+
|
29
|
+
module AWS
|
30
|
+
module Core
|
31
|
+
|
32
|
+
# Mixed into clients that use signature v4 authorization.
|
33
|
+
module AuthorizeV4
|
34
|
+
|
35
|
+
def add_authorization! signer
|
36
|
+
self.access_key_id = signer.access_key_id
|
37
|
+
datetime = Time.now.utc.strftime("%Y%m%dT%H%M%SZ")
|
38
|
+
headers['content-type'] ||= 'application/x-www-form-urlencoded'
|
39
|
+
headers['host'] = host
|
40
|
+
headers['x-amz-date'] = datetime
|
41
|
+
headers['x-amz-security-token'] = signer.session_token if signer.session_token
|
42
|
+
headers['authorization'] = authorization(signer, datetime)
|
43
|
+
end
|
44
|
+
|
45
|
+
protected
|
46
|
+
|
47
|
+
def authorization signer, datetime
|
48
|
+
parts = []
|
49
|
+
parts << "AWS4-HMAC-SHA256 Credential=#{access_key_id}/#{credential_string(datetime)}"
|
50
|
+
parts << "SignedHeaders=#{signed_headers}"
|
51
|
+
parts << "Signature=#{hex16(signature(signer, datetime))}"
|
52
|
+
parts.join(', ')
|
53
|
+
end
|
54
|
+
|
55
|
+
def signature signer, datetime
|
56
|
+
k_secret = signer.secret_access_key
|
57
|
+
k_date = hmac("AWS4" + k_secret, datetime[0,8])
|
58
|
+
k_region = hmac(k_date, region)
|
59
|
+
k_service = hmac(k_region, service)
|
60
|
+
k_credentials = hmac(k_service, 'aws4_request')
|
61
|
+
hmac(k_credentials, string_to_sign(datetime))
|
62
|
+
end
|
63
|
+
|
64
|
+
def string_to_sign datetime
|
65
|
+
parts = []
|
66
|
+
parts << 'AWS4-HMAC-SHA256'
|
67
|
+
parts << datetime
|
68
|
+
parts << credential_string(datetime)
|
69
|
+
parts << hex16(hash(canonical_request))
|
70
|
+
parts.join("\n")
|
71
|
+
end
|
72
|
+
|
73
|
+
def credential_string datetime
|
74
|
+
parts = []
|
75
|
+
parts << datetime[0,8]
|
76
|
+
parts << region
|
77
|
+
parts << service
|
78
|
+
parts << 'aws4_request'
|
79
|
+
parts.join("/")
|
80
|
+
end
|
81
|
+
|
82
|
+
def canonical_request
|
83
|
+
parts = []
|
84
|
+
parts << action_name
|
85
|
+
parts << canonical_uri
|
86
|
+
parts << canonical_querystring
|
87
|
+
parts << canonical_headers + "\n"
|
88
|
+
parts << signed_headers
|
89
|
+
parts << hex16(hash(payload))
|
90
|
+
parts.join("\n")
|
91
|
+
end
|
92
|
+
|
93
|
+
def service
|
94
|
+
# this method is implemented in the request class for each service
|
95
|
+
raise NotImplementedError
|
96
|
+
end
|
97
|
+
|
98
|
+
def action_name
|
99
|
+
http_method.to_s.upcase
|
100
|
+
end
|
101
|
+
|
102
|
+
def canonical_uri
|
103
|
+
path
|
104
|
+
end
|
105
|
+
|
106
|
+
def payload
|
107
|
+
body || ''
|
108
|
+
end
|
109
|
+
|
110
|
+
def canonical_querystring
|
111
|
+
http_method.to_s.upcase == 'GET' ? url_encoded_params : ''
|
112
|
+
end
|
113
|
+
|
114
|
+
def signed_headers
|
115
|
+
to_sign = headers.keys.map{|k| k.to_s.downcase }
|
116
|
+
to_sign.delete('authorization')
|
117
|
+
to_sign.sort.join(";")
|
118
|
+
end
|
119
|
+
|
120
|
+
def canonical_headers
|
121
|
+
headers = []
|
122
|
+
self.headers.each_pair do |k,v|
|
123
|
+
header = [k.to_s.downcase, v]
|
124
|
+
headers << header unless header.first == 'authorization'
|
125
|
+
end
|
126
|
+
headers = headers.sort_by(&:first)
|
127
|
+
headers.map{|k,v| "#{k}:#{canonical_header_values(v)}" }.join("\n")
|
128
|
+
end
|
129
|
+
|
130
|
+
def canonical_header_values values
|
131
|
+
values = [values] unless values.is_a?(Array)
|
132
|
+
values.map(&:to_s).map(&:strip).join(',')
|
133
|
+
end
|
134
|
+
|
135
|
+
def hex16 string
|
136
|
+
string.unpack('H*').first
|
137
|
+
end
|
138
|
+
|
139
|
+
def hmac key, string
|
140
|
+
OpenSSL::HMAC.digest(OpenSSL::Digest::Digest.new('sha256'), key, string)
|
141
|
+
end
|
142
|
+
|
143
|
+
def hash string
|
144
|
+
Digest::SHA256.digest(string)
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
data/lib/aws/core/client.rb
CHANGED
@@ -54,20 +54,28 @@ module AWS
|
|
54
54
|
# HTTP requests that this client constructs.
|
55
55
|
#
|
56
56
|
def initialize options = {}
|
57
|
+
|
58
|
+
options = options.dup # so we don't modify the options passed in
|
59
|
+
|
60
|
+
@service_ruby_name = self.class.service_ruby_name
|
57
61
|
|
58
|
-
|
59
|
-
|
60
|
-
|
62
|
+
# translate these into service specific configuration options,
|
63
|
+
# e.g. :endpoint into :s3_endpoint
|
64
|
+
[:endpoint, :region, :port].each do |opt|
|
65
|
+
if options[opt]
|
66
|
+
options[:"#{service_ruby_name}_#{opt}"] = options.delete(opt)
|
67
|
+
end
|
61
68
|
end
|
62
69
|
|
63
|
-
|
64
|
-
@config = options_without_config.delete(:config)
|
70
|
+
@config = options.delete(:config)
|
65
71
|
@config ||= AWS.config
|
66
|
-
@config = @config.with(
|
72
|
+
@config = @config.with(options)
|
73
|
+
|
67
74
|
@signer = @config.signer
|
68
75
|
@http_handler = @config.http_handler
|
69
|
-
@
|
70
|
-
|
76
|
+
@endpoint = config.send(:"#{service_ruby_name}_endpoint")
|
77
|
+
@port = config.send(:"#{service_ruby_name}_port")
|
78
|
+
|
71
79
|
end
|
72
80
|
|
73
81
|
# @return [Configuration] This clients configuration.
|
@@ -77,11 +85,17 @@ module AWS
|
|
77
85
|
# This is normally a DefaultSigner, but it can be configured to
|
78
86
|
# an other object.
|
79
87
|
attr_reader :signer
|
80
|
-
|
81
|
-
# @return [String]
|
82
|
-
|
83
|
-
|
84
|
-
|
88
|
+
|
89
|
+
# @return [String] The snake-cased ruby name for the service
|
90
|
+
# (e.g. 's3', 'iam', 'dynamo_db', etc).
|
91
|
+
attr_reader :service_ruby_name
|
92
|
+
|
93
|
+
# @return [Integer] What port this client makes requests via.
|
94
|
+
attr_reader :port
|
95
|
+
|
96
|
+
# @return [String] Returns the service endpoint (hostname) this client
|
97
|
+
# makes requests against.
|
98
|
+
attr_reader :endpoint
|
85
99
|
|
86
100
|
# Returns a copy of the client with a different HTTP handler.
|
87
101
|
# You can pass an object like BuiltinHttpHandler or you can
|
@@ -125,6 +139,7 @@ module AWS
|
|
125
139
|
# @see new_stub_for
|
126
140
|
# @private
|
127
141
|
def stub_for method_name
|
142
|
+
@stubs ||= {}
|
128
143
|
@stubs[method_name] ||= new_stub_for(method_name)
|
129
144
|
end
|
130
145
|
|
@@ -381,7 +396,10 @@ module AWS
|
|
381
396
|
http_request = new_request
|
382
397
|
|
383
398
|
# configure the http request
|
399
|
+
http_request.service_ruby_name = service_ruby_name
|
384
400
|
http_request.host = endpoint
|
401
|
+
http_request.port = port
|
402
|
+
http_request.region = config.send(:"#{service_ruby_name}_region")
|
385
403
|
http_request.proxy_uri = config.proxy_uri
|
386
404
|
http_request.use_ssl = config.use_ssl?
|
387
405
|
http_request.ssl_verify_peer = config.ssl_verify_peer?
|
@@ -302,7 +302,7 @@ module AWS
|
|
302
302
|
default_value
|
303
303
|
end
|
304
304
|
|
305
|
-
transform ? transform.call(value) : value
|
305
|
+
transform ? transform.call(self, value) : value
|
306
306
|
|
307
307
|
end
|
308
308
|
|
@@ -346,6 +346,7 @@ module AWS
|
|
346
346
|
:signer,
|
347
347
|
:http_handler,
|
348
348
|
:"#{ruby_name}_endpoint",
|
349
|
+
:"#{ruby_name}_port",
|
349
350
|
:max_retries,
|
350
351
|
:stub_requests?,
|
351
352
|
:proxy_uri,
|
@@ -359,6 +360,29 @@ module AWS
|
|
359
360
|
|
360
361
|
add_option :"#{ruby_name}_endpoint", default_endpoint
|
361
362
|
|
363
|
+
add_option(:"#{ruby_name}_port") do |config,value|
|
364
|
+
value || (config.use_ssl? ? 443 : 80)
|
365
|
+
end
|
366
|
+
|
367
|
+
# users only need to specify service regions when they use
|
368
|
+
# a test endpoint with a sigv4 service
|
369
|
+
add_option(:"#{ruby_name}_region") do |config,value|
|
370
|
+
value || begin
|
371
|
+
endpoint = config.send("#{ruby_name}_endpoint")
|
372
|
+
if endpoint =~ /us-gov/
|
373
|
+
if matches = enpoint.match(/(us-gov-west-\d+)/)
|
374
|
+
matches[1]
|
375
|
+
else
|
376
|
+
'us-gov-west-1' # e.g. iam.us-gov.amazonaws.com
|
377
|
+
end
|
378
|
+
elsif matches = endpoint.match(/^.+\.(.+)\.amazonaws.com$/)
|
379
|
+
matches[1]
|
380
|
+
else
|
381
|
+
'us-east-1'
|
382
|
+
end
|
383
|
+
end
|
384
|
+
end
|
385
|
+
|
362
386
|
add_option_with_needs :"#{ruby_name}_client", needs, &create_block
|
363
387
|
|
364
388
|
end
|
@@ -376,7 +400,7 @@ module AWS
|
|
376
400
|
|
377
401
|
add_option :max_retries, 3
|
378
402
|
|
379
|
-
add_option :proxy_uri do |uri| uri ? URI.parse(uri.to_s) : nil end
|
403
|
+
add_option :proxy_uri do |config,uri| uri ? URI.parse(uri.to_s) : nil end
|
380
404
|
|
381
405
|
add_option :secret_access_key,
|
382
406
|
ENV['AWS_SECRET_ACCESS_KEY'] || ENV['AMAZON_SECRET_ACCESS_KEY']
|
@@ -86,11 +86,10 @@ module AWS
|
|
86
86
|
|
87
87
|
private
|
88
88
|
def make_easy_handle request, response, thread = nil
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
89
|
+
|
90
|
+
protocol = request.use_ssl? ? 'https' : 'http'
|
91
|
+
url = "#{protocol}://#{request.host}:#{request.port}#{request.uri}"
|
92
|
+
|
94
93
|
curl = Curl::Easy.new(url)
|
95
94
|
# curl.verbose = true
|
96
95
|
request.headers.each {|k, v| curl.headers[k] = v}
|
@@ -68,12 +68,13 @@ module AWS
|
|
68
68
|
end
|
69
69
|
|
70
70
|
if request.use_ssl?
|
71
|
-
|
72
|
-
opts[:ssl_ca_file] = request.ssl_ca_file if
|
73
|
-
request.ssl_verify_peer?
|
71
|
+
protocol = 'https'
|
72
|
+
opts[:ssl_ca_file] = request.ssl_ca_file if request.ssl_verify_peer?
|
74
73
|
else
|
75
|
-
|
74
|
+
protocol = 'http'
|
76
75
|
end
|
76
|
+
|
77
|
+
url = "#{protocol}://#{request.host}:#{request.port}#{request.uri}"
|
77
78
|
|
78
79
|
# get, post, put, delete, head
|
79
80
|
method = request.http_method.downcase
|
@@ -26,6 +26,7 @@ module AWS
|
|
26
26
|
@headers = CaseInsensitiveHash.new
|
27
27
|
@params = []
|
28
28
|
@use_ssl = true
|
29
|
+
@port = nil
|
29
30
|
@read_timeout = 60
|
30
31
|
end
|
31
32
|
|
@@ -33,6 +34,10 @@ module AWS
|
|
33
34
|
# before a timeout error is raised on the request. Defaults to
|
34
35
|
# 60 seconds.
|
35
36
|
attr_accessor :read_timeout
|
37
|
+
|
38
|
+
# @return [String] The snake-cased ruby name for the service
|
39
|
+
# (e.g. 's3', 'iam', 'dynamo_db', etc).
|
40
|
+
attr_accessor :service_ruby_name
|
36
41
|
|
37
42
|
# @return [String] hostname of the request
|
38
43
|
attr_accessor :host
|
@@ -57,6 +62,10 @@ module AWS
|
|
57
62
|
# @return [nil, URI] The URI to the proxy server requests are
|
58
63
|
# sent through if configured. Returns nil if there is no proxy.
|
59
64
|
attr_accessor :proxy_uri
|
65
|
+
|
66
|
+
# @return [String] The region name this request is for. Only needs
|
67
|
+
# to be populated for requests against signature v4 endpoints.
|
68
|
+
attr_accessor :region
|
60
69
|
|
61
70
|
# @param [Boolean] ssl If the request should be sent over ssl or not.
|
62
71
|
def use_ssl= use_ssl
|
@@ -67,6 +76,19 @@ module AWS
|
|
67
76
|
def use_ssl?
|
68
77
|
@use_ssl
|
69
78
|
end
|
79
|
+
|
80
|
+
# Override the default port (443 or 80). If you pass nil then
|
81
|
+
# the default port will take precedence.
|
82
|
+
# @param [Integer,nil] port_number
|
83
|
+
def port= port_number
|
84
|
+
@port = port_number
|
85
|
+
end
|
86
|
+
|
87
|
+
# @return [Integer] Returns the port the request will be made over.
|
88
|
+
# Defaults to 443 for SSL requests and 80 for non-SSL requests.
|
89
|
+
def port
|
90
|
+
@port || (use_ssl? ? 443 : 80)
|
91
|
+
end
|
70
92
|
|
71
93
|
# @param [Boolean] verify_peer If the client should verify the
|
72
94
|
# peer certificate or not.
|
data/lib/aws/iam/request.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aws-sdk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 11
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 3
|
9
|
-
-
|
10
|
-
version: 1.3.
|
9
|
+
- 8
|
10
|
+
version: 1.3.8
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Amazon Web Services
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-03-
|
18
|
+
date: 2012-03-16 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
prerelease: false
|
@@ -93,6 +93,7 @@ files:
|
|
93
93
|
- lib/aws/core/async_handle.rb
|
94
94
|
- lib/aws/core/authorize_v2.rb
|
95
95
|
- lib/aws/core/authorize_v3.rb
|
96
|
+
- lib/aws/core/authorize_v4.rb
|
96
97
|
- lib/aws/core/authorize_with_session_token.rb
|
97
98
|
- lib/aws/core/autoloader.rb
|
98
99
|
- lib/aws/core/cacheable.rb
|