aws-sdk-core 3.178.0 → 3.233.0

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.
Files changed (196) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +709 -0
  3. data/VERSION +1 -1
  4. data/lib/aws-defaults/default_configuration.rb +1 -2
  5. data/lib/aws-defaults.rb +4 -1
  6. data/lib/aws-sdk-core/arn.rb +1 -3
  7. data/lib/aws-sdk-core/assume_role_credentials.rb +13 -5
  8. data/lib/aws-sdk-core/assume_role_web_identity_credentials.rb +14 -7
  9. data/lib/aws-sdk-core/binary/decode_handler.rb +3 -9
  10. data/lib/aws-sdk-core/binary/encode_handler.rb +1 -1
  11. data/lib/aws-sdk-core/binary/event_builder.rb +34 -37
  12. data/lib/aws-sdk-core/binary/event_stream_decoder.rb +1 -0
  13. data/lib/aws-sdk-core/binary/event_stream_encoder.rb +4 -3
  14. data/lib/aws-sdk-core/cbor/decoder.rb +308 -0
  15. data/lib/aws-sdk-core/cbor/encoder.rb +243 -0
  16. data/lib/aws-sdk-core/cbor.rb +53 -0
  17. data/lib/aws-sdk-core/client_side_monitoring.rb +9 -0
  18. data/lib/aws-sdk-core/client_stubs.rb +33 -55
  19. data/lib/aws-sdk-core/credential_provider.rb +5 -1
  20. data/lib/aws-sdk-core/credential_provider_chain.rb +38 -11
  21. data/lib/aws-sdk-core/credentials.rb +19 -6
  22. data/lib/aws-sdk-core/ec2_metadata.rb +1 -1
  23. data/lib/aws-sdk-core/ecs_credentials.rb +79 -11
  24. data/lib/aws-sdk-core/endpoints/endpoint.rb +3 -1
  25. data/lib/aws-sdk-core/endpoints/matchers.rb +21 -19
  26. data/lib/aws-sdk-core/endpoints.rb +101 -21
  27. data/lib/aws-sdk-core/error_handler.rb +46 -0
  28. data/lib/aws-sdk-core/errors.rb +14 -5
  29. data/lib/aws-sdk-core/event_emitter.rb +1 -17
  30. data/lib/aws-sdk-core/ini_parser.rb +8 -1
  31. data/lib/aws-sdk-core/instance_profile_credentials.rb +168 -155
  32. data/lib/aws-sdk-core/json/builder.rb +8 -1
  33. data/lib/aws-sdk-core/json/error_handler.rb +29 -13
  34. data/lib/aws-sdk-core/json/handler.rb +13 -6
  35. data/lib/aws-sdk-core/json/json_engine.rb +3 -1
  36. data/lib/aws-sdk-core/json/oj_engine.rb +7 -1
  37. data/lib/aws-sdk-core/json/parser.rb +33 -3
  38. data/lib/aws-sdk-core/json.rb +43 -14
  39. data/lib/aws-sdk-core/log/param_filter.rb +2 -2
  40. data/lib/aws-sdk-core/log/param_formatter.rb +7 -3
  41. data/lib/aws-sdk-core/log.rb +10 -0
  42. data/lib/aws-sdk-core/lru_cache.rb +75 -0
  43. data/lib/aws-sdk-core/pageable_response.rb +1 -1
  44. data/lib/aws-sdk-core/param_validator.rb +9 -4
  45. data/lib/aws-sdk-core/plugins/bearer_authorization.rb +2 -0
  46. data/lib/aws-sdk-core/plugins/checksum_algorithm.rb +332 -167
  47. data/lib/aws-sdk-core/plugins/client_metrics_plugin.rb +1 -1
  48. data/lib/aws-sdk-core/plugins/client_metrics_send_plugin.rb +14 -2
  49. data/lib/aws-sdk-core/plugins/credentials_configuration.rb +78 -56
  50. data/lib/aws-sdk-core/plugins/endpoint_pattern.rb +40 -32
  51. data/lib/aws-sdk-core/plugins/global_configuration.rb +8 -9
  52. data/lib/aws-sdk-core/plugins/http_checksum.rb +3 -8
  53. data/lib/aws-sdk-core/plugins/invocation_id.rb +1 -11
  54. data/lib/aws-sdk-core/plugins/logging.rb +2 -0
  55. data/lib/aws-sdk-core/plugins/protocols/api_gateway.rb +3 -1
  56. data/lib/aws-sdk-core/plugins/protocols/ec2.rb +2 -24
  57. data/lib/aws-sdk-core/plugins/protocols/json_rpc.rb +6 -8
  58. data/lib/aws-sdk-core/plugins/protocols/query.rb +4 -2
  59. data/lib/aws-sdk-core/plugins/protocols/rest_json.rb +3 -15
  60. data/lib/aws-sdk-core/plugins/protocols/rest_xml.rb +3 -0
  61. data/lib/aws-sdk-core/plugins/protocols/rpc_v2.rb +17 -0
  62. data/lib/aws-sdk-core/plugins/regional_endpoint.rb +74 -25
  63. data/lib/aws-sdk-core/plugins/request_compression.rb +11 -2
  64. data/lib/aws-sdk-core/plugins/retry_errors.rb +12 -3
  65. data/lib/aws-sdk-core/plugins/sign.rb +55 -34
  66. data/lib/aws-sdk-core/plugins/signature_v2.rb +2 -1
  67. data/lib/aws-sdk-core/plugins/signature_v4.rb +2 -1
  68. data/lib/aws-sdk-core/plugins/stub_responses.rb +59 -9
  69. data/lib/aws-sdk-core/plugins/telemetry.rb +75 -0
  70. data/lib/aws-sdk-core/plugins/transfer_encoding.rb +16 -9
  71. data/lib/aws-sdk-core/plugins/user_agent.rb +101 -26
  72. data/lib/aws-sdk-core/plugins.rb +39 -0
  73. data/lib/aws-sdk-core/process_credentials.rb +48 -29
  74. data/lib/aws-sdk-core/query/ec2_handler.rb +27 -0
  75. data/lib/aws-sdk-core/query/ec2_param_builder.rb +5 -7
  76. data/lib/aws-sdk-core/query/handler.rb +4 -4
  77. data/lib/aws-sdk-core/query/param_builder.rb +2 -2
  78. data/lib/aws-sdk-core/query.rb +2 -1
  79. data/lib/aws-sdk-core/refreshing_credentials.rb +12 -6
  80. data/lib/aws-sdk-core/resources.rb +8 -0
  81. data/lib/aws-sdk-core/rest/content_type_handler.rb +60 -0
  82. data/lib/aws-sdk-core/rest/handler.rb +3 -4
  83. data/lib/aws-sdk-core/rest/request/body.rb +32 -5
  84. data/lib/aws-sdk-core/rest/request/endpoint.rb +24 -4
  85. data/lib/aws-sdk-core/rest/request/headers.rb +15 -7
  86. data/lib/aws-sdk-core/rest/request/querystring_builder.rb +62 -36
  87. data/lib/aws-sdk-core/rest/response/body.rb +15 -1
  88. data/lib/aws-sdk-core/rest/response/header_list_parser.rb +79 -0
  89. data/lib/aws-sdk-core/rest/response/headers.rb +8 -3
  90. data/lib/aws-sdk-core/rest.rb +1 -0
  91. data/lib/aws-sdk-core/rpc_v2/builder.rb +62 -0
  92. data/lib/aws-sdk-core/rpc_v2/cbor_engine.rb +18 -0
  93. data/lib/aws-sdk-core/rpc_v2/content_type_handler.rb +47 -0
  94. data/lib/aws-sdk-core/rpc_v2/error_handler.rb +95 -0
  95. data/lib/aws-sdk-core/rpc_v2/handler.rb +79 -0
  96. data/lib/aws-sdk-core/rpc_v2/parser.rb +98 -0
  97. data/lib/aws-sdk-core/rpc_v2.rb +69 -0
  98. data/lib/aws-sdk-core/shared_config.rb +113 -41
  99. data/lib/aws-sdk-core/shared_credentials.rb +1 -7
  100. data/lib/aws-sdk-core/sso_credentials.rb +4 -1
  101. data/lib/aws-sdk-core/static_token_provider.rb +1 -2
  102. data/lib/aws-sdk-core/stubbing/protocols/ec2.rb +12 -11
  103. data/lib/aws-sdk-core/stubbing/protocols/json.rb +11 -10
  104. data/lib/aws-sdk-core/stubbing/protocols/query.rb +7 -6
  105. data/lib/aws-sdk-core/stubbing/protocols/rest.rb +2 -1
  106. data/lib/aws-sdk-core/stubbing/protocols/rest_json.rb +9 -8
  107. data/lib/aws-sdk-core/stubbing/protocols/rest_xml.rb +6 -5
  108. data/lib/aws-sdk-core/stubbing/protocols/rpc_v2.rb +39 -0
  109. data/lib/aws-sdk-core/stubbing/stub_data.rb +11 -0
  110. data/lib/aws-sdk-core/stubbing.rb +22 -0
  111. data/lib/aws-sdk-core/telemetry/base.rb +177 -0
  112. data/lib/aws-sdk-core/telemetry/no_op.rb +70 -0
  113. data/lib/aws-sdk-core/telemetry/otel.rb +235 -0
  114. data/lib/aws-sdk-core/telemetry/span_kind.rb +22 -0
  115. data/lib/aws-sdk-core/telemetry/span_status.rb +59 -0
  116. data/lib/aws-sdk-core/telemetry.rb +78 -0
  117. data/lib/aws-sdk-core/token.rb +3 -3
  118. data/lib/aws-sdk-core/token_provider.rb +4 -0
  119. data/lib/aws-sdk-core/token_provider_chain.rb +2 -6
  120. data/lib/aws-sdk-core/util.rb +41 -1
  121. data/lib/aws-sdk-core/waiters/poller.rb +10 -5
  122. data/lib/aws-sdk-core/xml/builder.rb +17 -9
  123. data/lib/aws-sdk-core/xml/error_handler.rb +35 -43
  124. data/lib/aws-sdk-core/xml/parser/frame.rb +4 -20
  125. data/lib/aws-sdk-core/xml/parser/stack.rb +2 -0
  126. data/lib/aws-sdk-core/xml/parser.rb +2 -6
  127. data/lib/aws-sdk-core.rb +82 -107
  128. data/lib/aws-sdk-sso/client.rb +189 -96
  129. data/lib/aws-sdk-sso/client_api.rb +7 -0
  130. data/lib/aws-sdk-sso/endpoint_parameters.rb +9 -6
  131. data/lib/aws-sdk-sso/endpoint_provider.rb +30 -28
  132. data/lib/aws-sdk-sso/endpoints.rb +2 -54
  133. data/lib/aws-sdk-sso/plugins/endpoints.rb +23 -22
  134. data/lib/aws-sdk-sso/types.rb +1 -0
  135. data/lib/aws-sdk-sso.rb +15 -11
  136. data/lib/aws-sdk-ssooidc/client.rb +609 -129
  137. data/lib/aws-sdk-ssooidc/client_api.rb +94 -1
  138. data/lib/aws-sdk-ssooidc/endpoint_parameters.rb +9 -6
  139. data/lib/aws-sdk-ssooidc/endpoint_provider.rb +30 -28
  140. data/lib/aws-sdk-ssooidc/endpoints.rb +2 -40
  141. data/lib/aws-sdk-ssooidc/errors.rb +62 -0
  142. data/lib/aws-sdk-ssooidc/plugins/endpoints.rb +23 -20
  143. data/lib/aws-sdk-ssooidc/types.rb +419 -53
  144. data/lib/aws-sdk-ssooidc.rb +15 -11
  145. data/lib/aws-sdk-sts/client.rb +414 -147
  146. data/lib/aws-sdk-sts/client_api.rb +48 -9
  147. data/lib/aws-sdk-sts/customizations.rb +5 -2
  148. data/lib/aws-sdk-sts/endpoint_parameters.rb +10 -9
  149. data/lib/aws-sdk-sts/endpoint_provider.rb +52 -57
  150. data/lib/aws-sdk-sts/endpoints.rb +2 -118
  151. data/lib/aws-sdk-sts/errors.rb +15 -0
  152. data/lib/aws-sdk-sts/plugins/endpoints.rb +23 -30
  153. data/lib/aws-sdk-sts/presigner.rb +3 -7
  154. data/lib/aws-sdk-sts/types.rb +209 -27
  155. data/lib/aws-sdk-sts.rb +15 -11
  156. data/lib/seahorse/client/async_base.rb +4 -5
  157. data/lib/seahorse/client/async_response.rb +19 -0
  158. data/lib/seahorse/client/base.rb +18 -21
  159. data/lib/seahorse/client/h2/connection.rb +18 -28
  160. data/lib/seahorse/client/h2/handler.rb +14 -3
  161. data/lib/seahorse/client/handler.rb +1 -1
  162. data/lib/seahorse/client/http/response.rb +1 -1
  163. data/lib/seahorse/client/net_http/connection_pool.rb +15 -12
  164. data/lib/seahorse/client/net_http/handler.rb +21 -9
  165. data/lib/seahorse/client/net_http/patches.rb +1 -4
  166. data/lib/seahorse/client/networking_error.rb +1 -1
  167. data/lib/seahorse/client/plugin.rb +9 -0
  168. data/lib/seahorse/client/plugins/endpoint.rb +0 -1
  169. data/lib/seahorse/client/plugins/h2.rb +4 -4
  170. data/lib/seahorse/client/plugins/net_http.rb +57 -16
  171. data/lib/seahorse/client/plugins/request_callback.rb +31 -0
  172. data/lib/seahorse/client/request_context.rb +9 -2
  173. data/lib/seahorse/client/response.rb +8 -0
  174. data/lib/seahorse/model/shapes.rb +2 -2
  175. data/lib/seahorse/util.rb +2 -1
  176. data/sig/aws-sdk-core/async_client_stubs.rbs +21 -0
  177. data/sig/aws-sdk-core/client_stubs.rbs +10 -0
  178. data/sig/aws-sdk-core/errors.rbs +22 -0
  179. data/sig/aws-sdk-core/resources/collection.rbs +21 -0
  180. data/sig/aws-sdk-core/structure.rbs +4 -0
  181. data/sig/aws-sdk-core/telemetry/base.rbs +46 -0
  182. data/sig/aws-sdk-core/telemetry/otel.rbs +22 -0
  183. data/sig/aws-sdk-core/telemetry/span_kind.rbs +15 -0
  184. data/sig/aws-sdk-core/telemetry/span_status.rbs +24 -0
  185. data/sig/aws-sdk-core/waiters/errors.rbs +20 -0
  186. data/sig/aws-sdk-core.rbs +7 -0
  187. data/sig/seahorse/client/async_base.rbs +18 -0
  188. data/sig/seahorse/client/base.rbs +25 -0
  189. data/sig/seahorse/client/handler_builder.rbs +16 -0
  190. data/sig/seahorse/client/response.rbs +61 -0
  191. metadata +105 -23
  192. /data/lib/aws-sdk-core/xml/parser/{engines/libxml.rb → libxml_engine.rb} +0 -0
  193. /data/lib/aws-sdk-core/xml/parser/{engines/nokogiri.rb → nokogiri_engine.rb} +0 -0
  194. /data/lib/aws-sdk-core/xml/parser/{engines/oga.rb → oga_engine.rb} +0 -0
  195. /data/lib/aws-sdk-core/xml/parser/{engines/ox.rb → ox_engine.rb} +0 -0
  196. /data/lib/aws-sdk-core/xml/parser/{engines/rexml.rb → rexml_engine.rb} +0 -0
@@ -6,7 +6,7 @@ require 'resolv'
6
6
 
7
7
  module Aws
8
8
  # An auto-refreshing credential provider that loads credentials from
9
- # instances running in ECS.
9
+ # instances running in containers.
10
10
  #
11
11
  # ecs_credentials = Aws::ECSCredentials.new(retries: 3)
12
12
  # ec2 = Aws::EC2::Client.new(credentials: ecs_credentials)
@@ -17,6 +17,12 @@ module Aws
17
17
  # @api private
18
18
  class Non200Response < RuntimeError; end
19
19
 
20
+ # Raised when the token file cannot be read.
21
+ class TokenFileReadError < RuntimeError; end
22
+
23
+ # Raised when the token file is invalid.
24
+ class InvalidTokenError < RuntimeError; end
25
+
20
26
  # These are the errors we trap when attempting to talk to the
21
27
  # instance metadata service. Any of these imply the service
22
28
  # is not present, no responding or some other non-recoverable
@@ -41,7 +47,7 @@ module Aws
41
47
  # is set and `credential_path` is not set.
42
48
  # @option options [String] :credential_path By default, the value of the
43
49
  # AWS_CONTAINER_CREDENTIALS_RELATIVE_URI environment variable.
44
- # @option options [String] :endpoint The ECS credential endpoint.
50
+ # @option options [String] :endpoint The container credential endpoint.
45
51
  # By default, this is the value of the AWS_CONTAINER_CREDENTIALS_FULL_URI
46
52
  # environment variable. This value is ignored if `credential_path` or
47
53
  # ENV['AWS_CONTAINER_CREDENTIALS_RELATIVE_URI'] is set.
@@ -64,7 +70,6 @@ module Aws
64
70
  endpoint = options[:endpoint] ||
65
71
  ENV['AWS_CONTAINER_CREDENTIALS_FULL_URI']
66
72
  initialize_uri(options, credential_path, endpoint)
67
- @authorization_token = ENV['AWS_CONTAINER_AUTHORIZATION_TOKEN']
68
73
 
69
74
  @retries = options[:retries] || 5
70
75
  @http_open_timeout = options[:http_open_timeout] || 5
@@ -72,6 +77,7 @@ module Aws
72
77
  @http_debug_output = options[:http_debug_output]
73
78
  @backoff = backoff(options[:backoff])
74
79
  @async_refresh = false
80
+ @metrics = ['CREDENTIALS_HTTP']
75
81
  super
76
82
  end
77
83
 
@@ -103,11 +109,18 @@ module Aws
103
109
 
104
110
  def initialize_full_uri(endpoint)
105
111
  uri = URI.parse(endpoint)
112
+ validate_full_uri_scheme!(uri)
106
113
  validate_full_uri!(uri)
107
- @host = uri.host
114
+ @host = uri.hostname
108
115
  @port = uri.port
109
116
  @scheme = uri.scheme
110
- @credential_path = uri.path
117
+ @credential_path = uri.request_uri
118
+ end
119
+
120
+ def validate_full_uri_scheme!(full_uri)
121
+ return if full_uri.is_a?(URI::HTTP) || full_uri.is_a?(URI::HTTPS)
122
+
123
+ raise ArgumentError, "'#{full_uri}' must be a valid HTTP or HTTPS URI"
111
124
  end
112
125
 
113
126
  # Validate that the full URI is using a loopback address if scheme is http.
@@ -115,19 +128,24 @@ module Aws
115
128
  return unless full_uri.scheme == 'http'
116
129
 
117
130
  begin
118
- return if ip_loopback?(IPAddr.new(full_uri.host))
131
+ return if valid_ip_address?(IPAddr.new(full_uri.host))
119
132
  rescue IPAddr::InvalidAddressError
120
133
  addresses = Resolv.getaddresses(full_uri.host)
121
- return if addresses.all? { |addr| ip_loopback?(IPAddr.new(addr)) }
134
+ return if addresses.all? { |addr| valid_ip_address?(IPAddr.new(addr)) }
122
135
  end
123
136
 
124
137
  raise ArgumentError,
125
- 'AWS_CONTAINER_CREDENTIALS_FULL_URI must use a loopback '\
126
- 'address when using the http scheme.'
138
+ 'AWS_CONTAINER_CREDENTIALS_FULL_URI must use a local loopback '\
139
+ 'or an ECS or EKS link-local address when using the http scheme.'
140
+ end
141
+
142
+ def valid_ip_address?(ip_address)
143
+ ip_loopback?(ip_address) || ecs_or_eks_ip?(ip_address)
127
144
  end
128
145
 
129
146
  # loopback? method is available in Ruby 2.5+
130
147
  # Replicate the logic here.
148
+ # loopback (IPv4 127.0.0.0/8, IPv6 ::1/128)
131
149
  def ip_loopback?(ip_address)
132
150
  case ip_address.family
133
151
  when Socket::AF_INET
@@ -139,6 +157,20 @@ module Aws
139
157
  end
140
158
  end
141
159
 
160
+ # Verify that the IP address is a link-local address from ECS or EKS.
161
+ # ECS container host (IPv4 `169.254.170.2`)
162
+ # EKS container host (IPv4 `169.254.170.23`, IPv6 `fd00:ec2::23`)
163
+ def ecs_or_eks_ip?(ip_address)
164
+ case ip_address.family
165
+ when Socket::AF_INET
166
+ [0xa9feaa02, 0xa9feaa17].include?(ip_address)
167
+ when Socket::AF_INET6
168
+ ip_address == 0xfd00_0ec2_0000_0000_0000_0000_0000_0023
169
+ else
170
+ false
171
+ end
172
+ end
173
+
142
174
  def backoff(backoff)
143
175
  case backoff
144
176
  when Proc then backoff
@@ -174,10 +206,37 @@ module Aws
174
206
  http_get(conn, @credential_path)
175
207
  end
176
208
  end
177
- rescue StandardError
209
+ rescue TokenFileReadError, InvalidTokenError
210
+ raise
211
+ rescue StandardError => e
212
+ warn("Error retrieving ECS Credentials: #{e.message}")
178
213
  '{}'
179
214
  end
180
215
 
216
+ def fetch_authorization_token
217
+ if (path = ENV['AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE'])
218
+ fetch_authorization_token_file(path)
219
+ elsif (token = ENV['AWS_CONTAINER_AUTHORIZATION_TOKEN'])
220
+ token
221
+ end
222
+ end
223
+
224
+ def fetch_authorization_token_file(path)
225
+ File.read(path).strip
226
+ rescue Errno::ENOENT
227
+ raise TokenFileReadError,
228
+ 'AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE is set '\
229
+ "but the file doesn't exist: #{path}"
230
+ end
231
+
232
+ def validate_authorization_token!(token)
233
+ return unless token.include?("\r\n")
234
+
235
+ raise InvalidTokenError,
236
+ 'Invalid Authorization token: token contains '\
237
+ 'a newline and carriage return character.'
238
+ end
239
+
181
240
  def open_connection
182
241
  http = Net::HTTP.new(@host, @port, nil)
183
242
  http.open_timeout = @http_open_timeout
@@ -190,18 +249,27 @@ module Aws
190
249
 
191
250
  def http_get(connection, path)
192
251
  request = Net::HTTP::Get.new(path)
193
- request['Authorization'] = @authorization_token if @authorization_token
252
+ set_authorization_token(request)
194
253
  response = connection.request(request)
195
254
  raise Non200Response unless response.code.to_i == 200
196
255
 
197
256
  response.body
198
257
  end
199
258
 
259
+ def set_authorization_token(request)
260
+ if (authorization_token = fetch_authorization_token)
261
+ validate_authorization_token!(authorization_token)
262
+ request['Authorization'] = authorization_token
263
+ end
264
+ end
265
+
200
266
  def retry_errors(error_classes, options = {})
201
267
  max_retries = options[:max_retries]
202
268
  retries = 0
203
269
  begin
204
270
  yield
271
+ rescue TokenFileReadError, InvalidTokenError
272
+ raise
205
273
  rescue *error_classes => _e
206
274
  raise unless retries < max_retries
207
275
 
@@ -3,15 +3,17 @@
3
3
  module Aws
4
4
  module Endpoints
5
5
  class Endpoint
6
- def initialize(url:, properties: {}, headers: {})
6
+ def initialize(url:, properties: {}, headers: {}, metadata: {})
7
7
  @url = url
8
8
  @properties = properties
9
9
  @headers = headers
10
+ @metadata = metadata
10
11
  end
11
12
 
12
13
  attr_reader :url
13
14
  attr_reader :properties
14
15
  attr_reader :headers
16
+ attr_reader :metadata
15
17
  end
16
18
  end
17
19
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'cgi'
3
+ require "cgi/escape"
4
+ require "cgi/util" if RUBY_VERSION < "3.5"
4
5
 
5
6
  module Aws
6
7
  module Endpoints
@@ -28,7 +29,11 @@ module Aws
28
29
 
29
30
  val = if (index = parts.first[BRACKET_REGEX, 1])
30
31
  # remove brackets and index from part before indexing
31
- value[parts.first.gsub(BRACKET_REGEX, '')][index.to_i]
32
+ if (base = parts.first.gsub(BRACKET_REGEX, '')) && !base.empty?
33
+ value[base][index.to_i]
34
+ else
35
+ value[index.to_i]
36
+ end
32
37
  else
33
38
  value[parts.first]
34
39
  end
@@ -79,25 +84,18 @@ module Aws
79
84
  return false if value.empty?
80
85
 
81
86
  if allow_sub_domains
82
- labels = value.split('.')
87
+ labels = value.split('.', -1)
83
88
  return labels.all? { |l| valid_host_label?(l) }
84
89
  end
85
90
 
86
- value =~ /\A(?!-)[a-zA-Z0-9-]{1,63}(?<!-)\z/
91
+ !!(value =~ /\A(?!-)[a-zA-Z0-9-]{1,63}(?<!-)\z/)
87
92
  end
88
93
 
89
94
  # AWS
90
95
 
91
96
  # aws.partition(value: string) Option<Partition>
92
97
  def self.aws_partition(value)
93
- partition =
94
- Aws::Partitions.find { |p| p.region?(value) } ||
95
- Aws::Partitions.find { |p| value.match(p.region_regex) } ||
96
- Aws::Partitions.find { |p| p.name == 'aws' }
97
-
98
- return nil unless partition
99
-
100
- partition.metadata
98
+ Aws::Partitions::Metadata.partition(value)
101
99
  end
102
100
 
103
101
  # aws.parseArn(value: string) Option<ARN>
@@ -114,13 +112,17 @@ module Aws
114
112
 
115
113
  # aws.isVirtualHostableS3Bucket(value: string, allowSubDomains: bool) bool
116
114
  def self.aws_virtual_hostable_s3_bucket?(value, allow_sub_domains = false)
117
- !!(value.size < 64 &&
118
- # regular naming rules
119
- value =~ /^[a-z0-9][a-z0-9\-#{'.' if allow_sub_domains}]+[a-z0-9]$/ &&
120
- # not IP address
121
- value !~ /(\d+\.){3}\d+/ &&
122
- # no dash and hyphen together
123
- value !~ /[.-]{2}/)
115
+ return false if value.empty?
116
+
117
+ if allow_sub_domains
118
+ labels = value.split('.', -1)
119
+ return labels.all? { |l| aws_virtual_hostable_s3_bucket?(l) }
120
+ end
121
+
122
+ # must be between 3 and 63 characters long, no uppercase
123
+ value =~ /\A(?!-)[a-z0-9-]{3,63}(?<!-)\z/ &&
124
+ # not an IP address
125
+ value !~ /(\d+\.){3}\d+/
124
126
  end
125
127
  end
126
128
  end
@@ -14,15 +14,33 @@ require_relative 'endpoints/templater'
14
14
  require_relative 'endpoints/tree_rule'
15
15
  require_relative 'endpoints/url'
16
16
 
17
+ require 'aws-sigv4'
18
+
17
19
  module Aws
18
20
  # @api private
19
21
  module Endpoints
22
+ # Maps config auth scheme preferences to endpoint auth scheme names.
23
+ ENDPOINT_AUTH_PREFERENCE_MAP = {
24
+ 'sigv4' => %w[sigv4 sigv4-s3express],
25
+ 'sigv4a' => ['sigv4a'],
26
+ 'httpBearerAuth' => ['bearer'],
27
+ 'noAuth' => ['none']
28
+ }.freeze
29
+ SUPPORTED_ENDPOINT_AUTH = ENDPOINT_AUTH_PREFERENCE_MAP.values.flatten.freeze
30
+
31
+ # Maps configured auth scheme preferences to modeled auth traits.
32
+ MODELED_AUTH_PREFERENCE_MAP = {
33
+ 'sigv4' => 'aws.auth#sigv4',
34
+ 'sigv4a' => 'aws.auth#sigv4a',
35
+ 'httpBearerAuth' => 'smithy.api#httpBearerAuth',
36
+ 'noAuth' => 'smithy.api#noAuth'
37
+ }.freeze
38
+ SUPPORTED_MODELED_AUTH = MODELED_AUTH_PREFERENCE_MAP.values.freeze
39
+
20
40
  class << self
21
41
  def resolve_auth_scheme(context, endpoint)
22
42
  if endpoint && (auth_schemes = endpoint.properties['authSchemes'])
23
- auth_scheme = auth_schemes.find do |scheme|
24
- Aws::Plugins::Sign::SUPPORTED_AUTH_TYPES.include?(scheme['name'])
25
- end
43
+ auth_scheme = endpoint_auth_scheme_preference(auth_schemes, context.config.auth_scheme_preference)
26
44
  raise 'No supported auth scheme for this endpoint.' unless auth_scheme
27
45
 
28
46
  merge_signing_defaults(auth_scheme, context.config)
@@ -33,8 +51,86 @@ module Aws
33
51
 
34
52
  private
35
53
 
54
+ def endpoint_auth_scheme_preference(auth_schemes, preferred_auth)
55
+ ordered_auth = preferred_auth.each_with_object([]) do |pref, list|
56
+ next unless ENDPOINT_AUTH_PREFERENCE_MAP.key?(pref)
57
+
58
+ ENDPOINT_AUTH_PREFERENCE_MAP[pref].each { |name| list << { 'name' => name } }
59
+ end
60
+ ordered_auth += auth_schemes
61
+ ordered_auth.find { |auth| SUPPORTED_ENDPOINT_AUTH.include?(auth['name']) }
62
+ end
63
+
64
+ def merge_signing_defaults(auth_scheme, config)
65
+ if %w[sigv4 sigv4a sigv4-s3express].include?(auth_scheme['name'])
66
+ auth_scheme['signingName'] ||= sigv4_name(config)
67
+
68
+ # back fill disableNormalizePath for S3 until it gets correctly set in the rules
69
+ if auth_scheme['signingName'] == 's3' &&
70
+ !auth_scheme.include?('disableNormalizePath') &&
71
+ auth_scheme.include?('disableDoubleEncoding')
72
+ auth_scheme['disableNormalizePath'] = auth_scheme['disableDoubleEncoding']
73
+ end
74
+ if auth_scheme['name'] == 'sigv4a'
75
+ # config option supersedes endpoint properties
76
+ auth_scheme['signingRegionSet'] =
77
+ config.sigv4a_signing_region_set || auth_scheme['signingRegionSet'] || [config.region]
78
+ else
79
+ auth_scheme['signingRegion'] ||= config.region
80
+ end
81
+ end
82
+ auth_scheme
83
+ end
84
+
85
+ def sigv4_name(config)
86
+ config.api.metadata['signingName'] || config.api.metadata['endpointPrefix']
87
+ end
88
+
36
89
  def default_auth_scheme(context)
37
- case default_api_authtype(context)
90
+ if (modeled_auth = default_api_auth(context))
91
+ auth = modeled_auth_scheme_preference(modeled_auth, context.config.auth_scheme_preference)
92
+ case auth
93
+ when 'aws.auth#sigv4', 'aws.auth#sigv4a'
94
+ auth_scheme = { 'name' => auth.split('#').last }
95
+ if s3_or_s3v4_signature_version?(context)
96
+ auth_scheme = auth_scheme.merge(
97
+ 'disableDoubleEncoding' => true,
98
+ 'disableNormalizePath' => true
99
+ )
100
+ end
101
+ merge_signing_defaults(auth_scheme, context.config)
102
+ when 'smithy.api#httpBearerAuth'
103
+ { 'name' => 'bearer' }
104
+ when 'smithy.api#noAuth'
105
+ { 'name' => 'none' }
106
+ else
107
+ raise 'No supported auth trait for this endpoint.'
108
+ end
109
+ else
110
+ legacy_default_auth_scheme(context)
111
+ end
112
+ end
113
+
114
+ def modeled_auth_scheme_preference(modeled_auth, preferred_auth)
115
+ ordered_auth = preferred_auth.map { |pref| MODELED_AUTH_PREFERENCE_MAP[pref] }.compact
116
+ ordered_auth += modeled_auth
117
+ ordered_auth.find { |auth| SUPPORTED_MODELED_AUTH.include?(auth) }
118
+ end
119
+
120
+ def default_api_auth(context)
121
+ context.config.api.operation(context.operation_name)['auth'] ||
122
+ context.config.api.metadata['auth']
123
+ end
124
+
125
+ def s3_or_s3v4_signature_version?(context)
126
+ %w[s3 s3v4].include?(context.config.api.metadata['signatureVersion'])
127
+ end
128
+
129
+ # Legacy auth resolution - looks for deprecated signatureVersion
130
+ # and authType traits.
131
+
132
+ def legacy_default_auth_scheme(context)
133
+ case legacy_default_api_authtype(context)
38
134
  when 'v4', 'v4-unsigned-body'
39
135
  auth_scheme = { 'name' => 'sigv4' }
40
136
  merge_signing_defaults(auth_scheme, context.config)
@@ -52,27 +148,11 @@ module Aws
52
148
  end
53
149
  end
54
150
 
55
- def merge_signing_defaults(auth_scheme, config)
56
- if %w[sigv4 sigv4a].include?(auth_scheme['name'])
57
- auth_scheme['signingName'] ||= sigv4_name(config)
58
- if auth_scheme['name'] == 'sigv4a'
59
- auth_scheme['signingRegionSet'] ||= ['*']
60
- else
61
- auth_scheme['signingRegion'] ||= config.region
62
- end
63
- end
64
- auth_scheme
65
- end
66
-
67
- def default_api_authtype(context)
151
+ def legacy_default_api_authtype(context)
68
152
  context.config.api.operation(context.operation_name)['authtype'] ||
69
153
  context.config.api.metadata['signatureVersion']
70
154
  end
71
155
 
72
- def sigv4_name(config)
73
- config.api.metadata['signingName'] ||
74
- config.api.metadata['endpointPrefix']
75
- end
76
156
  end
77
157
  end
78
158
  end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ # @api private
5
+ class ErrorHandler < Seahorse::Client::Handler
6
+
7
+ private
8
+
9
+ def error(context)
10
+ body = context.http_response.body_contents
11
+ # This is not correct per protocol tests. Some headers will determine the error code.
12
+ # If the body is empty, there is still potentially an error code from the header, but
13
+ # we are making a generic http status error instead. In a new major version, we should
14
+ # always try to extract header, and during extraction, check headers and body.
15
+ if body.empty?
16
+ code, message, data = http_status_error(context)
17
+ else
18
+ code, message, data = extract_error(body, context)
19
+ end
20
+ build_error(context, code, message, data)
21
+ end
22
+
23
+ def build_error(context, code, message, data)
24
+ errors_module = context.client.class.errors_module
25
+ errors_module.error_class(code).new(context, message, data)
26
+ end
27
+
28
+ def http_status_error(context)
29
+ [http_status_error_code(context), '', EmptyStructure.new]
30
+ end
31
+
32
+ def http_status_error_code(context)
33
+ status_code = context.http_response.status_code
34
+ {
35
+ 302 => 'MovedTemporarily',
36
+ 304 => 'NotModified',
37
+ 400 => 'BadRequest',
38
+ 403 => 'Forbidden',
39
+ 404 => 'NotFound',
40
+ 412 => 'PreconditionFailed',
41
+ 413 => 'RequestEntityTooLarge',
42
+ }[status_code] || "Http#{status_code}Error"
43
+ end
44
+
45
+ end
46
+ end
@@ -12,7 +12,7 @@ module Aws
12
12
  class ServiceError < RuntimeError
13
13
 
14
14
  # @param [Seahorse::Client::RequestContext] context
15
- # @param [String] message
15
+ # @param [String, nil] message
16
16
  # @param [Aws::Structure] data
17
17
  def initialize(context, message, data = Aws::EmptyStructure.new)
18
18
  @code = self.class.code
@@ -30,11 +30,11 @@ module Aws
30
30
  attr_reader :context
31
31
 
32
32
  # @return [Aws::Structure]
33
- attr_reader :data
33
+ attr_accessor :data
34
34
 
35
35
  class << self
36
36
 
37
- # @return [String]
37
+ # @return [String, nil]
38
38
  attr_accessor :code
39
39
 
40
40
  end
@@ -68,7 +68,7 @@ module Aws
68
68
  end
69
69
  end
70
70
 
71
- # Rasied when endpoint discovery failed for operations
71
+ # Raised when endpoint discovery failed for operations
72
72
  # that requires endpoints from endpoint discovery
73
73
  class EndpointDiscoveryError < RuntimeError
74
74
  def initialize(*args)
@@ -78,7 +78,7 @@ module Aws
78
78
  end
79
79
  end
80
80
 
81
- # raised when hostLabel member is not provided
81
+ # Raised when hostLabel member is not provided
82
82
  # at operation input when endpoint trait is available
83
83
  # with 'hostPrefix' requirement
84
84
  class MissingEndpointHostLabelValue < RuntimeError
@@ -236,6 +236,15 @@ module Aws
236
236
  end
237
237
  end
238
238
 
239
+ # Raised when a client is constructed and the sigv4a region set is invalid.
240
+ # It is invalid when it is empty and/or contains empty strings.
241
+ class InvalidRegionSetError < ArgumentError
242
+ def initialize(*args)
243
+ msg = 'The provided sigv4a region set was empty or invalid.'
244
+ super(msg)
245
+ end
246
+ end
247
+
239
248
  # Raised when a client is contsructed and the region is not valid.
240
249
  class InvalidRegionError < ArgumentError
241
250
  def initialize(*args)
@@ -6,7 +6,6 @@ module Aws
6
6
  def initialize
7
7
  @listeners = {}
8
8
  @validate_event = true
9
- @status = :sleep
10
9
  @signal_queue = Queue.new
11
10
  end
12
11
 
@@ -32,7 +31,7 @@ module Aws
32
31
  def emit(type, params)
33
32
  unless @stream
34
33
  raise Aws::Errors::SignalEventError.new(
35
- "Singaling events before making async request"\
34
+ "Signaling events before making async request"\
36
35
  " is not allowed."
37
36
  )
38
37
  end
@@ -40,25 +39,10 @@ module Aws
40
39
  Aws::ParamValidator.validate!(
41
40
  @encoder.rules.shape.member(type), params)
42
41
  end
43
- _ready_for_events?
44
42
  @stream.data(
45
43
  @encoder.encode(type, params),
46
44
  end_stream: type == :end_stream
47
45
  )
48
46
  end
49
-
50
- private
51
-
52
- def _ready_for_events?
53
- return true if @status == :ready
54
-
55
- # blocked until once initial 200 response is received
56
- # signal will be available in @signal_queue
57
- # and this check will no longer be blocked
58
- @signal_queue.pop
59
- @status = :ready
60
- true
61
- end
62
-
63
47
  end
64
48
  end
@@ -8,6 +8,8 @@ module Aws
8
8
  def ini_parse(raw)
9
9
  current_profile = nil
10
10
  current_prefix = nil
11
+ item = nil
12
+ previous_item = nil
11
13
  raw.lines.inject({}) do |acc, line|
12
14
  line = line.split(/^|\s;/).first # remove comments
13
15
  profile = line.match(/^\[([^\[\]]+)\]\s*(#.+)?$/) unless line.nil?
@@ -17,11 +19,16 @@ module Aws
17
19
  current_profile = named_profile[1] if named_profile
18
20
  elsif current_profile
19
21
  unless line.nil?
20
- item = line.match(/^(.+?)\s*=\s*([^\s].*?)\s*$/)
22
+ previous_item = item
23
+ item = line.match(/^(.+?)\s*=\s*(.+?)\s*$/)
21
24
  prefix = line.match(/^(.+?)\s*=\s*$/)
22
25
  end
23
26
  if item && item[1].match(/^\s+/)
24
27
  # Need to add lines to a nested configuration.
28
+ if current_prefix.nil? && previous_item[2].strip.empty?
29
+ current_prefix = previous_item[1]
30
+ acc[current_profile][current_prefix] = {}
31
+ end
25
32
  inner_item = line.match(/^\s*(.+?)\s*=\s*(.+?)\s*$/)
26
33
  acc[current_profile] ||= {}
27
34
  acc[current_profile][current_prefix] ||= {}