aws-sdk-core 2.0.9 → 2.0.10

Sign up to get free protection for your applications and to get access to all the features.
@@ -6,18 +6,6 @@
6
6
  "globalEndpoint":"s3.amazonaws.com",
7
7
  "serviceAbbreviation":"Amazon S3",
8
8
  "serviceFullName":"Amazon Simple Storage Service",
9
- "signatureVersion":"v4",
10
- "sigv2Regions": [
11
- "us-east-1",
12
- "us-west-1",
13
- "us-west-2",
14
- "ap-northeast-1",
15
- "ap-southeast-1",
16
- "ap-southeast-2",
17
- "sa-east-1",
18
- "eu-west-1",
19
- "us-gov-west-1"
20
- ],
21
9
  "timestampFormat":"rfc822",
22
10
  "protocol":"rest-xml"
23
11
  },
@@ -650,7 +638,8 @@
650
638
  "ap-northeast-1",
651
639
  "sa-east-1",
652
640
  "",
653
- "cn-north-1"
641
+ "cn-north-1",
642
+ "eu-central-1"
654
643
  ]
655
644
  },
656
645
  "BucketLoggingStatus":{
@@ -2038,7 +2027,11 @@
2038
2027
  "DisplayName":{"shape":"DisplayName"},
2039
2028
  "EmailAddress":{"shape":"EmailAddress"},
2040
2029
  "ID":{"shape":"ID"},
2041
- "Type":{"shape":"Type"},
2030
+ "Type":{
2031
+ "shape":"Type",
2032
+ "xmlAttribute":true,
2033
+ "locationName":"xsi:type"
2034
+ },
2042
2035
  "URI":{"shape":"URI"}
2043
2036
  },
2044
2037
  "xmlNamespace":{
@@ -3490,9 +3483,7 @@
3490
3483
  "CanonicalUser",
3491
3484
  "AmazonCustomerByEmail",
3492
3485
  "Group"
3493
- ],
3494
- "xmlAttribute":true,
3495
- "locationName":"xsi:type"
3486
+ ]
3496
3487
  },
3497
3488
  "URI":{"type":"string"},
3498
3489
  "UploadIdMarker":{"type":"string"},
@@ -140,7 +140,7 @@ module Aws
140
140
  autoload :S3LocationConstraint, 'aws-sdk-core/plugins/s3_location_constraint'
141
141
  autoload :S3Md5s, 'aws-sdk-core/plugins/s3_md5s'
142
142
  autoload :S3Redirects, 'aws-sdk-core/plugins/s3_redirects'
143
- autoload :S3RegionDetection, 'aws-sdk-core/plugins/s3_region_detection'
143
+ autoload :S3RequestSigner, 'aws-sdk-core/plugins/s3_request_signer'
144
144
  autoload :S3SseCpk, 'aws-sdk-core/plugins/s3_sse_cpk'
145
145
  autoload :S3UrlEncodedKeys, 'aws-sdk-core/plugins/s3_url_encoded_keys'
146
146
  autoload :SQSQueueUrls, 'aws-sdk-core/plugins/sqs_queue_urls'
@@ -102,7 +102,7 @@ module Aws
102
102
  add_plugin 'Aws::Plugins::S3Redirects'
103
103
  add_plugin 'Aws::Plugins::S3SseCpk'
104
104
  add_plugin 'Aws::Plugins::S3UrlEncodedKeys'
105
- add_plugin 'Aws::Plugins::S3RegionDetection'
105
+ add_plugin 'Aws::Plugins::S3RequestSigner'
106
106
  defs = client_class.waiters.instance_variable_get("@definitions")
107
107
  defs[:bucket_exists]['ignore_errors'] = ['NotFound']
108
108
  defs[:object_exists]['ignore_errors'] = ['NotFound']
@@ -1,4 +1,5 @@
1
1
  Aws.add_service(:ConfigService, {
2
2
  api: File.join(Aws::API_DIR, 'ConfigService.api.json'),
3
3
  docs: File.join(Aws::API_DIR, 'ConfigService.docs.json'),
4
+ paginators: File.join(Aws::API_DIR, 'ConfigService.paginators.json'),
4
5
  })
@@ -1,4 +1,5 @@
1
1
  Aws.add_service(:Lambda, {
2
2
  api: File.join(Aws::API_DIR, 'Lambda.api.json'),
3
3
  docs: File.join(Aws::API_DIR, 'Lambda.docs.json'),
4
+ paginators: File.join(Aws::API_DIR, 'Lambda.paginators.json'),
4
5
  })
@@ -41,7 +41,7 @@ module Aws
41
41
  class GlobalConfiguration < Seahorse::Client::Plugin
42
42
 
43
43
  # @api private
44
- IDENTIFIERS = Set.new
44
+ IDENTIFIERS = Set.new(SERVICE_MODULE_NAMES.map(&:downcase).map(&:to_sym))
45
45
 
46
46
  # @api private
47
47
  def before_initialize(client_class, options)
@@ -49,8 +49,9 @@ module Aws
49
49
 
50
50
  option(:sigv4_region) do |cfg|
51
51
  prefix = cfg.api.metadata('endpointPrefix')
52
- if matches = cfg.endpoint.to_s.match(/#{prefix}[.-](.+)\.amazonaws\.com/)
53
- matches[1]
52
+ endpoint = cfg.endpoint.to_s
53
+ if matches = endpoint.match(/#{prefix}[.-](.+)\.amazonaws\.com/)
54
+ matches[1] == 'us-gov' ? 'us-gov-west-1' : matches[1]
54
55
  elsif cfg.endpoint.to_s.match(/#{prefix}\.amazonaws\.com/)
55
56
  'us-east-1'
56
57
  else
@@ -75,8 +76,7 @@ module Aws
75
76
  private
76
77
 
77
78
  def sign_authenticated_requests(context)
78
- version = context[:signature_version] || context.config.signature_version
79
- if signer = SIGNERS[version]
79
+ if signer = SIGNERS[context.config.signature_version]
80
80
  require_credentials(context)
81
81
  signer.sign(context)
82
82
  end
@@ -94,7 +94,10 @@ module Aws
94
94
 
95
95
  end
96
96
 
97
- handler(Handler, step: :sign)
97
+ def add_handlers(handlers, config)
98
+ # See the S3RequestSignerPlugin for Amazon S3 signature logic
99
+ handlers.add(Handler, step: :sign) unless config.sigv4_name == 's3'
100
+ end
98
101
 
99
102
  end
100
103
  end
@@ -38,7 +38,8 @@ module Aws
38
38
  endpoint = context.http_request.endpoint
39
39
  if
40
40
  bucket_name &&
41
- S3BucketDns.dns_compatible?(bucket_name, https?(endpoint))
41
+ S3BucketDns.dns_compatible?(bucket_name, https?(endpoint)) &&
42
+ context.operation_name != 'get_bucket_location'
42
43
  then
43
44
  move_bucket_to_subdomain(bucket_name, endpoint)
44
45
  end
@@ -0,0 +1,241 @@
1
+ require 'set'
2
+
3
+ module Aws
4
+ module Plugins
5
+ # This plugin is an implementation detail and may be modified.
6
+ # @api private
7
+ class S3RequestSigner < Seahorse::Client::Plugin
8
+
9
+ class SigningHandler < Seahorse::Client::Handler
10
+
11
+ # List of regions that support older S3 signature versions.
12
+ # All new regions only support signature version 4.
13
+ V2_REGIONS = Set.new(%w(
14
+ us-east-1
15
+ us-west-1
16
+ us-west-2
17
+ ap-northeast-1
18
+ ap-southeast-1
19
+ ap-southeast-2
20
+ sa-east-1
21
+ eu-west-1
22
+ us-gov-west-1
23
+ ))
24
+
25
+ def call(context)
26
+ version = signature_version(context)
27
+ case version
28
+ when /v4/ then apply_v4_signature(context)
29
+ when /s3/ then apply_v2_signature(context)
30
+ else raise "unsupported signature version #{version.inspect}"
31
+ end
32
+ @handler.call(context)
33
+ end
34
+
35
+ private
36
+
37
+ def apply_v4_signature(context)
38
+ Signers::V4.new(
39
+ context.config.credentials, 's3',
40
+ context[:cached_sigv4_region] || context.config.sigv4_region,
41
+ ).sign(context.http_request)
42
+ end
43
+
44
+ def apply_v2_signature(context)
45
+ Signers::S3.sign(context)
46
+ end
47
+
48
+ def signature_version(context)
49
+ context[:cached_signature_version] ||
50
+ context.config.signature_version ||
51
+ version_by_region(context)
52
+ end
53
+
54
+ def version_by_region(context)
55
+ if classic_endpoint?(context)
56
+ classic_sigv(context)
57
+ else
58
+ regional_sigv(context)
59
+ end
60
+ end
61
+
62
+ def classic_endpoint?(context)
63
+ context.config.region == 'us-east-1'
64
+ end
65
+
66
+ # When accessing the classic endpoint, s3.amazonaws.com, we don't know
67
+ # the region name. This makes creating a version 4 signature difficult.
68
+ # Choose v4 only if using KMS encryptions, which requires v4.
69
+ def classic_sigv(context)
70
+ if kms_encrypted?(context)
71
+ :v4
72
+ else
73
+ :s3
74
+ end
75
+ end
76
+
77
+ def regional_sigv(context)
78
+ # Drop back to older S3 signature version when uploading objects for
79
+ # better performance. This optimization may be removed at some point
80
+ # in favor of always using signature version 4.
81
+ if V2_REGIONS.include?(context.config.region)
82
+ uploading_file?(context) && !kms_encrypted?(context) ? :s3 : :v4
83
+ else
84
+ :v4
85
+ end
86
+ end
87
+
88
+ def kms_encrypted?(context)
89
+ context.params[:server_side_encryption] == 'aws:kms'
90
+ end
91
+
92
+ def uploading_file?(context)
93
+ %w(put_object upload_part).include?(context.operation_name) &&
94
+ context.http_request.body.size > 0
95
+ end
96
+
97
+ end
98
+
99
+ # Abstract base class for the other two handlers
100
+ class Handler < Seahorse::Client::Handler
101
+
102
+ private
103
+
104
+ def new_hostname(context, region)
105
+ bucket = context.params[:bucket]
106
+ if region == 'us-east-1'
107
+ "#{bucket}.s3-external-1.amazonaws.com"
108
+ else
109
+ bucket + '.' + URI.parse(EndpointProvider.resolve(region, 's3')).host
110
+ end
111
+ end
112
+
113
+ end
114
+
115
+ # This handler will update the http endpoint when the bucket region
116
+ # is known/cached.
117
+ class CachedBucketRegionHandler < Handler
118
+
119
+ def call(context)
120
+ if bucket = context.params[:bucket]
121
+ use_regional_endpoint_when_known(context, bucket)
122
+ end
123
+ @handler.call(context)
124
+ end
125
+
126
+ private
127
+
128
+ def use_regional_endpoint_when_known(context, bucket)
129
+ cached_region = S3::BUCKET_REGIONS[bucket]
130
+ if cached_region && cached_region != context.config.region
131
+ context.http_request.endpoint.host = new_hostname(context, cached_region)
132
+ context[:cached_sigv4_region] = cached_region
133
+ context[:cached_signature_version] = :v4
134
+ end
135
+ end
136
+
137
+ end
138
+
139
+ # This handler detects when a request fails because signature version 4
140
+ # is required but not used. It follows up by making a request to
141
+ # determine the correct region, then finally a version 4 signed
142
+ # request against the regional endpoint.
143
+ class BucketSigningErrorHandler < Handler
144
+
145
+ SIGV4_MSG = /(Please use AWS4-HMAC-SHA256|AWS Signature Version 4)/
146
+
147
+ def call(context)
148
+ response = @handler.call(context)
149
+ handle_region_errors(response)
150
+ end
151
+
152
+ private
153
+
154
+ def handle_region_errors(response)
155
+ if sigv4_required_error?(response)
156
+ detect_region_and_retry(response)
157
+ elsif wrong_sigv4_region?(response)
158
+ extract_body_region_and_retry(response.context)
159
+ else
160
+ response
161
+ end
162
+ end
163
+
164
+ def sigv4_required_error?(resp)
165
+ resp.context.http_response.status_code == 400 &&
166
+ resp.context.http_response.body_contents.match(SIGV4_MSG) &&
167
+ resp.context.http_response.body.respond_to?(:truncate)
168
+ end
169
+
170
+ def wrong_sigv4_region?(resp)
171
+ resp.context.http_response.status_code == 400 &&
172
+ resp.context.http_response.body_contents.match(/<Region>.+?<\/Region>/)
173
+ end
174
+
175
+ def extract_body_region_and_retry(context)
176
+ actual_region = region_from_body(context)
177
+ updgrade_to_v4(context, actual_region)
178
+ log_warning(context, actual_region)
179
+ @handler.call(context)
180
+ end
181
+
182
+ def region_from_body(context)
183
+ context.http_response.body_contents.match(/<Region>(.+?)<\/Region>/)[1]
184
+ end
185
+
186
+ def detect_region_and_retry(resp)
187
+ context = resp.context
188
+ updgrade_to_v4(context, 'us-east-1')
189
+ resp = @handler.call(context)
190
+ if resp.successful?
191
+ resp
192
+ else
193
+ actual_region = region_from_location_header(context)
194
+ updgrade_to_v4(context, actual_region)
195
+ log_warning(context, actual_region)
196
+ @handler.call(context)
197
+ end
198
+ end
199
+
200
+ def updgrade_to_v4(context, region)
201
+ bucket = context.params[:bucket]
202
+ context.http_response.body.truncate(0)
203
+ context.http_request.headers.delete('authorization')
204
+ context.http_request.headers.delete('x-amz-security-token')
205
+ context.http_request.endpoint.host = new_hostname(context, region)
206
+ signer = Signers::V4.new(context.config.credentials, 's3', region)
207
+ signer.sign(context.http_request)
208
+ end
209
+
210
+ def region_from_location_header(context)
211
+ location = context.http_response.headers['location']
212
+ location.match(/s3[.-](.+?)\.amazonaws\.com/)[1]
213
+ end
214
+
215
+ def log_warning(context, actual_region)
216
+ S3::BUCKET_REGIONS[context.params[:bucket]] = actual_region
217
+ msg = "S3 client configured for #{context.config.region.inspect} " +
218
+ "but the bucket #{context.params[:bucket].inspect} is in " +
219
+ "#{actual_region.inspect}; Please configure the proper region " +
220
+ "to avoid multiple unecessary redirects and signing attempts\n"
221
+ if logger = context.config.logger
222
+ logger.warn(msg)
223
+ else
224
+ warn(msg)
225
+ end
226
+ end
227
+
228
+ end
229
+
230
+ # BEFORE signing
231
+ handle(CachedBucketRegionHandler, step: :sign, priority: 60)
232
+
233
+ # sign the request
234
+ handler(SigningHandler, step: :sign)
235
+
236
+ # AFTER signing
237
+ handle(BucketSigningErrorHandler, step: :sign, priority: 40)
238
+
239
+ end
240
+ end
241
+ end
@@ -123,11 +123,13 @@ module Aws
123
123
  # virtual hosted-style requests require the hostname to appear
124
124
  # in the canonicalized resource prefixed by a forward slash.
125
125
  if bucket = params[:bucket]
126
+ bucket = bucket.value
126
127
  ssl = endpoint.scheme == 'https'
127
- if Plugins::S3BucketDns.dns_compatible?(bucket.value, ssl) &&
128
- !@force_path_style
128
+ if Plugins::S3BucketDns.dns_compatible?(bucket, ssl) &&
129
+ !@force_path_style &&
130
+ !endpoint.path.match(/^\/#{Regexp.escape(bucket)}/)
129
131
  then
130
- parts << "/#{bucket.value}"
132
+ parts << "/#{bucket}"
131
133
  end
132
134
  end
133
135
 
@@ -9,7 +9,7 @@ module Aws
9
9
  new(
10
10
  context.config.credentials,
11
11
  context.config.sigv4_name,
12
- context[:sigv4_region] || context.config.sigv4_region
12
+ context.config.sigv4_region
13
13
  ).sign(context.http_request)
14
14
  end
15
15
 
@@ -1,3 +1,3 @@
1
1
  module Aws
2
- VERSION = '2.0.9'
2
+ VERSION = '2.0.10'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aws-sdk-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.9
4
+ version: 2.0.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Amazon Web Services
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-13 00:00:00.000000000 Z
11
+ date: 2014-11-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: multi_json
@@ -157,7 +157,7 @@ files:
157
157
  - lib/aws-sdk-core/plugins/s3_location_constraint.rb
158
158
  - lib/aws-sdk-core/plugins/s3_md5s.rb
159
159
  - lib/aws-sdk-core/plugins/s3_redirects.rb
160
- - lib/aws-sdk-core/plugins/s3_region_detection.rb
160
+ - lib/aws-sdk-core/plugins/s3_request_signer.rb
161
161
  - lib/aws-sdk-core/plugins/s3_sse_cpk.rb
162
162
  - lib/aws-sdk-core/plugins/s3_url_encoded_keys.rb
163
163
  - lib/aws-sdk-core/plugins/sqs_queue_urls.rb
@@ -1,144 +0,0 @@
1
- module Aws
2
- module Plugins
3
- # This plugin is an implementation detail and may be modified.
4
- # @api private
5
- class S3RegionDetection < Seahorse::Client::Plugin
6
-
7
- # Intentionally not documented - this should go away when all
8
- # services support signature version 4 in every region.
9
- option(:signature_version) do |cfg|
10
- if S3.sigv2_region?(cfg.region)
11
- 's3'
12
- else
13
- 'v4'
14
- end
15
- end
16
-
17
- class Handler < Seahorse::Client::Handler
18
-
19
- private
20
-
21
- def new_hostname(context, region)
22
- bucket = context.params[:bucket]
23
- if region == 'us-east-1'
24
- "#{bucket}.s3-external-1.amazonaws.com"
25
- else
26
- bucket + '.' + URI.parse(EndpointProvider.resolve(region, 's3')).host
27
- end
28
- end
29
-
30
- end
31
-
32
- class CachedBucketRegionHandler < Handler
33
-
34
- def call(context)
35
- if bucket = context.params[:bucket]
36
- use_regional_endpoint_when_known(context, bucket)
37
- end
38
- @handler.call(context)
39
- end
40
-
41
- private
42
-
43
- def use_regional_endpoint_when_known(context, bucket)
44
- cached_region = S3::BUCKET_REGIONS[bucket]
45
- if cached_region && cached_region != context.config.region
46
- context.http_request.endpoint.host = new_hostname(context, cached_region)
47
- context[:sigv4_region] = cached_region
48
- context[:signature_version] = 'v4'
49
- end
50
- end
51
-
52
- end
53
-
54
- class DetectRegionHandler < Handler
55
-
56
- def call(context)
57
- response = @handler.call(context)
58
- handle_region_errors(response)
59
- end
60
-
61
- private
62
-
63
- def handle_region_errors(response)
64
- if requires_sigv4?(response)
65
- detect_region_and_retry(response)
66
- elsif wrong_sigv4_region?(response)
67
- extract_body_region_and_retry(response.context)
68
- else
69
- response
70
- end
71
- end
72
-
73
- def requires_sigv4?(resp)
74
- resp.context.http_response.status_code == 400 &&
75
- resp.context.http_response.body_contents.include?('Please use AWS4-HMAC-SHA256') &&
76
- resp.context.http_response.body.respond_to?(:truncate)
77
- end
78
-
79
- def wrong_sigv4_region?(resp)
80
- resp.context.http_response.status_code == 400 &&
81
- resp.context.http_response.body_contents.match(/<Region>.+?<\/Region>/)
82
- end
83
-
84
- def extract_body_region_and_retry(context)
85
- actual_region = region_from_body(context)
86
- updgrade_to_v4(context, actual_region)
87
- log_warning(context, actual_region)
88
- @handler.call(context)
89
- end
90
-
91
- def region_from_body(context)
92
- context.http_response.body_contents.match(/<Region>(.+?)<\/Region>/)[1]
93
- end
94
-
95
- def detect_region_and_retry(resp)
96
- context = resp.context
97
- updgrade_to_v4(context, 'us-east-1')
98
- resp = @handler.call(context)
99
- actual_region = region_from_location_header(context)
100
- updgrade_to_v4(context, actual_region)
101
- log_warning(context, actual_region)
102
- @handler.call(context)
103
- end
104
-
105
- def updgrade_to_v4(context, region)
106
- bucket = context.params[:bucket]
107
- context.http_response.body.truncate(0)
108
- context.http_request.headers.delete('authorization')
109
- context.http_request.headers.delete('x-amz-security-token')
110
- context.http_request.endpoint.host = new_hostname(context, region)
111
- signer = Signers::V4.new(context.config.credentials, 's3', region)
112
- signer.sign(context.http_request)
113
- end
114
-
115
- def region_from_location_header(context)
116
- location = context.http_response.headers['location']
117
- location.match(/s3.(.+?)\.amazonaws\.com/)[1]
118
- end
119
-
120
- def log_warning(context, actual_region)
121
- S3::BUCKET_REGIONS[context.params[:bucket]] = actual_region
122
- msg = "S3 client configured for #{context.config.region.inspect} " +
123
- "but the bucket #{context.params[:bucket].inspect} is in " +
124
- "#{actual_region.inspect}; Please configure the proper region " +
125
- "to avoid multiple unecessary redirects and signing attempts"
126
- if logger = context.config.logger
127
- logger.warn(msg)
128
- else
129
- warn(msg)
130
- end
131
-
132
- end
133
-
134
- end
135
-
136
- # BEFORE the request is signed
137
- handle(CachedBucketRegionHandler, step: :sign, priority: 60)
138
-
139
- # AFTER the request is signed
140
- handle(DetectRegionHandler, step: :sign, priority: 40)
141
-
142
- end
143
- end
144
- end