aws-sdk-core 3.185.1 → 3.214.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 (177) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +409 -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/assume_role_credentials.rb +12 -5
  7. data/lib/aws-sdk-core/assume_role_web_identity_credentials.rb +13 -7
  8. data/lib/aws-sdk-core/binary/decode_handler.rb +3 -9
  9. data/lib/aws-sdk-core/binary/encode_handler.rb +1 -1
  10. data/lib/aws-sdk-core/binary/event_builder.rb +34 -37
  11. data/lib/aws-sdk-core/binary/event_stream_decoder.rb +1 -0
  12. data/lib/aws-sdk-core/binary/event_stream_encoder.rb +4 -3
  13. data/lib/aws-sdk-core/cbor/decoder.rb +310 -0
  14. data/lib/aws-sdk-core/cbor/encoder.rb +243 -0
  15. data/lib/aws-sdk-core/cbor.rb +53 -0
  16. data/lib/aws-sdk-core/client_side_monitoring.rb +9 -0
  17. data/lib/aws-sdk-core/client_stubs.rb +23 -19
  18. data/lib/aws-sdk-core/credential_provider.rb +1 -1
  19. data/lib/aws-sdk-core/credential_provider_chain.rb +13 -6
  20. data/lib/aws-sdk-core/credentials.rb +13 -6
  21. data/lib/aws-sdk-core/ec2_metadata.rb +1 -1
  22. data/lib/aws-sdk-core/ecs_credentials.rb +78 -11
  23. data/lib/aws-sdk-core/endpoints/endpoint.rb +3 -1
  24. data/lib/aws-sdk-core/endpoints/matchers.rb +6 -9
  25. data/lib/aws-sdk-core/endpoints.rb +74 -18
  26. data/lib/aws-sdk-core/error_handler.rb +41 -0
  27. data/lib/aws-sdk-core/errors.rb +11 -2
  28. data/lib/aws-sdk-core/event_emitter.rb +0 -16
  29. data/lib/aws-sdk-core/instance_profile_credentials.rb +55 -32
  30. data/lib/aws-sdk-core/json/builder.rb +8 -1
  31. data/lib/aws-sdk-core/json/error_handler.rb +17 -11
  32. data/lib/aws-sdk-core/json/handler.rb +13 -6
  33. data/lib/aws-sdk-core/json/json_engine.rb +3 -1
  34. data/lib/aws-sdk-core/json/oj_engine.rb +7 -1
  35. data/lib/aws-sdk-core/json/parser.rb +32 -2
  36. data/lib/aws-sdk-core/json.rb +43 -14
  37. data/lib/aws-sdk-core/log/param_filter.rb +2 -2
  38. data/lib/aws-sdk-core/log.rb +10 -0
  39. data/lib/aws-sdk-core/lru_cache.rb +75 -0
  40. data/lib/aws-sdk-core/pageable_response.rb +1 -1
  41. data/lib/aws-sdk-core/param_validator.rb +7 -2
  42. data/lib/aws-sdk-core/plugins/bearer_authorization.rb +2 -0
  43. data/lib/aws-sdk-core/plugins/checksum_algorithm.rb +6 -3
  44. data/lib/aws-sdk-core/plugins/client_metrics_plugin.rb +1 -0
  45. data/lib/aws-sdk-core/plugins/client_metrics_send_plugin.rb +14 -2
  46. data/lib/aws-sdk-core/plugins/credentials_configuration.rb +9 -3
  47. data/lib/aws-sdk-core/plugins/global_configuration.rb +8 -9
  48. data/lib/aws-sdk-core/plugins/http_checksum.rb +2 -1
  49. data/lib/aws-sdk-core/plugins/invocation_id.rb +1 -11
  50. data/lib/aws-sdk-core/plugins/logging.rb +2 -0
  51. data/lib/aws-sdk-core/plugins/protocols/api_gateway.rb +3 -1
  52. data/lib/aws-sdk-core/plugins/protocols/ec2.rb +2 -24
  53. data/lib/aws-sdk-core/plugins/protocols/json_rpc.rb +6 -8
  54. data/lib/aws-sdk-core/plugins/protocols/query.rb +4 -2
  55. data/lib/aws-sdk-core/plugins/protocols/rest_json.rb +3 -15
  56. data/lib/aws-sdk-core/plugins/protocols/rest_xml.rb +3 -0
  57. data/lib/aws-sdk-core/plugins/protocols/rpc_v2.rb +17 -0
  58. data/lib/aws-sdk-core/plugins/regional_endpoint.rb +74 -25
  59. data/lib/aws-sdk-core/plugins/request_compression.rb +11 -2
  60. data/lib/aws-sdk-core/plugins/retry_errors.rb +12 -3
  61. data/lib/aws-sdk-core/plugins/sign.rb +27 -15
  62. data/lib/aws-sdk-core/plugins/signature_v2.rb +2 -1
  63. data/lib/aws-sdk-core/plugins/signature_v4.rb +2 -1
  64. data/lib/aws-sdk-core/plugins/stub_responses.rb +30 -2
  65. data/lib/aws-sdk-core/plugins/telemetry.rb +75 -0
  66. data/lib/aws-sdk-core/plugins/transfer_encoding.rb +16 -9
  67. data/lib/aws-sdk-core/plugins/user_agent.rb +70 -26
  68. data/lib/aws-sdk-core/plugins.rb +39 -0
  69. data/lib/aws-sdk-core/process_credentials.rb +47 -28
  70. data/lib/aws-sdk-core/query/ec2_handler.rb +27 -0
  71. data/lib/aws-sdk-core/query/ec2_param_builder.rb +5 -7
  72. data/lib/aws-sdk-core/query/handler.rb +4 -4
  73. data/lib/aws-sdk-core/query/param_builder.rb +2 -2
  74. data/lib/aws-sdk-core/query.rb +2 -1
  75. data/lib/aws-sdk-core/refreshing_credentials.rb +12 -6
  76. data/lib/aws-sdk-core/resources.rb +8 -0
  77. data/lib/aws-sdk-core/rest/content_type_handler.rb +60 -0
  78. data/lib/aws-sdk-core/rest/handler.rb +3 -4
  79. data/lib/aws-sdk-core/rest/request/body.rb +32 -5
  80. data/lib/aws-sdk-core/rest/request/endpoint.rb +24 -4
  81. data/lib/aws-sdk-core/rest/request/headers.rb +14 -6
  82. data/lib/aws-sdk-core/rest/request/querystring_builder.rb +62 -36
  83. data/lib/aws-sdk-core/rest/response/body.rb +15 -1
  84. data/lib/aws-sdk-core/rest/response/header_list_parser.rb +79 -0
  85. data/lib/aws-sdk-core/rest/response/headers.rb +8 -3
  86. data/lib/aws-sdk-core/rest.rb +1 -0
  87. data/lib/aws-sdk-core/rpc_v2/builder.rb +62 -0
  88. data/lib/aws-sdk-core/rpc_v2/cbor_engine.rb +18 -0
  89. data/lib/aws-sdk-core/rpc_v2/content_type_handler.rb +47 -0
  90. data/lib/aws-sdk-core/rpc_v2/error_handler.rb +85 -0
  91. data/lib/aws-sdk-core/rpc_v2/handler.rb +79 -0
  92. data/lib/aws-sdk-core/rpc_v2/parser.rb +90 -0
  93. data/lib/aws-sdk-core/rpc_v2.rb +69 -0
  94. data/lib/aws-sdk-core/shared_config.rb +7 -2
  95. data/lib/aws-sdk-core/shared_credentials.rb +0 -7
  96. data/lib/aws-sdk-core/sso_credentials.rb +2 -1
  97. data/lib/aws-sdk-core/stubbing/protocols/ec2.rb +12 -11
  98. data/lib/aws-sdk-core/stubbing/protocols/json.rb +11 -10
  99. data/lib/aws-sdk-core/stubbing/protocols/query.rb +7 -6
  100. data/lib/aws-sdk-core/stubbing/protocols/rest.rb +2 -1
  101. data/lib/aws-sdk-core/stubbing/protocols/rest_json.rb +9 -8
  102. data/lib/aws-sdk-core/stubbing/protocols/rest_xml.rb +6 -5
  103. data/lib/aws-sdk-core/stubbing/protocols/rpc_v2.rb +39 -0
  104. data/lib/aws-sdk-core/stubbing.rb +22 -0
  105. data/lib/aws-sdk-core/telemetry/base.rb +177 -0
  106. data/lib/aws-sdk-core/telemetry/no_op.rb +70 -0
  107. data/lib/aws-sdk-core/telemetry/otel.rb +235 -0
  108. data/lib/aws-sdk-core/telemetry/span_kind.rb +22 -0
  109. data/lib/aws-sdk-core/telemetry/span_status.rb +59 -0
  110. data/lib/aws-sdk-core/telemetry.rb +78 -0
  111. data/lib/aws-sdk-core/util.rb +39 -0
  112. data/lib/aws-sdk-core/waiters/poller.rb +10 -5
  113. data/lib/aws-sdk-core/xml/builder.rb +17 -9
  114. data/lib/aws-sdk-core/xml/error_handler.rb +32 -42
  115. data/lib/aws-sdk-core/xml/parser/frame.rb +4 -20
  116. data/lib/aws-sdk-core/xml/parser/stack.rb +2 -0
  117. data/lib/aws-sdk-core/xml/parser.rb +2 -6
  118. data/lib/aws-sdk-core.rb +82 -107
  119. data/lib/aws-sdk-sso/client.rb +119 -55
  120. data/lib/aws-sdk-sso/client_api.rb +7 -0
  121. data/lib/aws-sdk-sso/endpoint_parameters.rb +9 -6
  122. data/lib/aws-sdk-sso/endpoints.rb +2 -54
  123. data/lib/aws-sdk-sso/plugins/endpoints.rb +23 -22
  124. data/lib/aws-sdk-sso/types.rb +1 -0
  125. data/lib/aws-sdk-sso.rb +15 -11
  126. data/lib/aws-sdk-ssooidc/client.rb +504 -83
  127. data/lib/aws-sdk-ssooidc/client_api.rb +83 -1
  128. data/lib/aws-sdk-ssooidc/endpoint_parameters.rb +9 -6
  129. data/lib/aws-sdk-ssooidc/endpoint_provider.rb +2 -2
  130. data/lib/aws-sdk-ssooidc/endpoints.rb +2 -40
  131. data/lib/aws-sdk-ssooidc/errors.rb +52 -0
  132. data/lib/aws-sdk-ssooidc/plugins/endpoints.rb +23 -20
  133. data/lib/aws-sdk-ssooidc/types.rb +373 -51
  134. data/lib/aws-sdk-ssooidc.rb +15 -11
  135. data/lib/aws-sdk-sts/client.rb +334 -105
  136. data/lib/aws-sdk-sts/client_api.rb +36 -10
  137. data/lib/aws-sdk-sts/customizations.rb +5 -1
  138. data/lib/aws-sdk-sts/endpoint_parameters.rb +10 -9
  139. data/lib/aws-sdk-sts/endpoint_provider.rb +2 -2
  140. data/lib/aws-sdk-sts/endpoints.rb +2 -118
  141. data/lib/aws-sdk-sts/plugins/endpoints.rb +23 -30
  142. data/lib/aws-sdk-sts/presigner.rb +1 -1
  143. data/lib/aws-sdk-sts/types.rb +188 -30
  144. data/lib/aws-sdk-sts.rb +15 -11
  145. data/lib/seahorse/client/async_base.rb +1 -1
  146. data/lib/seahorse/client/async_response.rb +19 -0
  147. data/lib/seahorse/client/base.rb +18 -7
  148. data/lib/seahorse/client/h2/handler.rb +14 -3
  149. data/lib/seahorse/client/handler.rb +1 -1
  150. data/lib/seahorse/client/net_http/connection_pool.rb +11 -11
  151. data/lib/seahorse/client/net_http/handler.rb +21 -9
  152. data/lib/seahorse/client/net_http/patches.rb +1 -4
  153. data/lib/seahorse/client/plugin.rb +9 -0
  154. data/lib/seahorse/client/plugins/endpoint.rb +0 -1
  155. data/lib/seahorse/client/plugins/h2.rb +3 -3
  156. data/lib/seahorse/client/plugins/net_http.rb +57 -16
  157. data/lib/seahorse/client/request_context.rb +8 -1
  158. data/lib/seahorse/model/shapes.rb +2 -2
  159. data/sig/aws-sdk-core/client_stubs.rbs +10 -0
  160. data/sig/aws-sdk-core/errors.rbs +22 -0
  161. data/sig/aws-sdk-core/resources/collection.rbs +21 -0
  162. data/sig/aws-sdk-core/structure.rbs +4 -0
  163. data/sig/aws-sdk-core/telemetry/base.rbs +46 -0
  164. data/sig/aws-sdk-core/telemetry/otel.rbs +22 -0
  165. data/sig/aws-sdk-core/telemetry/span_kind.rbs +15 -0
  166. data/sig/aws-sdk-core/telemetry/span_status.rbs +24 -0
  167. data/sig/aws-sdk-core/waiters/errors.rbs +20 -0
  168. data/sig/aws-sdk-core.rbs +7 -0
  169. data/sig/seahorse/client/base.rbs +25 -0
  170. data/sig/seahorse/client/handler_builder.rbs +16 -0
  171. data/sig/seahorse/client/response.rbs +61 -0
  172. metadata +61 -19
  173. /data/lib/aws-sdk-core/xml/parser/{engines/libxml.rb → libxml_engine.rb} +0 -0
  174. /data/lib/aws-sdk-core/xml/parser/{engines/nokogiri.rb → nokogiri_engine.rb} +0 -0
  175. /data/lib/aws-sdk-core/xml/parser/{engines/oga.rb → oga_engine.rb} +0 -0
  176. /data/lib/aws-sdk-core/xml/parser/{engines/ox.rb → ox_engine.rb} +0 -0
  177. /data/lib/aws-sdk-core/xml/parser/{engines/rexml.rb → rexml_engine.rb} +0 -0
@@ -53,6 +53,8 @@ module Aws
53
53
  # @option options [String] :endpoint_mode ('IPv4') The endpoint mode for
54
54
  # the instance metadata service. This is either 'IPv4' ('169.254.169.254')
55
55
  # or 'IPv6' ('[fd00:ec2::254]').
56
+ # @option options [Boolean] :disable_imds_v1 (false) Disable the use of the
57
+ # legacy EC2 Metadata Service v1.
56
58
  # @option options [String] :ip_address ('169.254.169.254') Deprecated. Use
57
59
  # :endpoint instead. The IP address for the endpoint.
58
60
  # @option options [Integer] :port (80)
@@ -77,6 +79,9 @@ module Aws
77
79
  endpoint_mode = resolve_endpoint_mode(options)
78
80
  @endpoint = resolve_endpoint(options, endpoint_mode)
79
81
  @port = options[:port] || 80
82
+ @disable_imds_v1 = resolve_disable_v1(options)
83
+ # Flag for if v2 flow fails, skip future attempts
84
+ @imds_v1_fallback = false
80
85
  @http_open_timeout = options[:http_open_timeout] || 1
81
86
  @http_read_timeout = options[:http_read_timeout] || 1
82
87
  @http_debug_output = options[:http_debug_output]
@@ -123,6 +128,16 @@ module Aws
123
128
  end
124
129
  end
125
130
 
131
+ def resolve_disable_v1(options)
132
+ value = options[:disable_imds_v1]
133
+ value ||= ENV['AWS_EC2_METADATA_V1_DISABLED']
134
+ value ||= Aws.shared_config.ec2_metadata_v1_disabled(
135
+ profile: options[:profile]
136
+ )
137
+ value = value.to_s.downcase if value
138
+ Aws::Util.str_2_bool(value) || false
139
+ end
140
+
126
141
  def backoff(backoff)
127
142
  case backoff
128
143
  when Proc then backoff
@@ -141,7 +156,7 @@ module Aws
141
156
  # service is responding but is returning invalid JSON documents
142
157
  # in response to the GET profile credentials call.
143
158
  begin
144
- retry_errors([Aws::Json::ParseError, StandardError], max_retries: 3) do
159
+ retry_errors([Aws::Json::ParseError], max_retries: 3) do
145
160
  c = Aws::Json.load(get_credentials.to_s)
146
161
  if empty_credentials?(@credentials)
147
162
  @credentials = Credentials.new(
@@ -173,7 +188,6 @@ module Aws
173
188
  end
174
189
  end
175
190
  end
176
-
177
191
  end
178
192
  rescue Aws::Json::ParseError
179
193
  raise Aws::Errors::MetadataParserError
@@ -191,42 +205,53 @@ module Aws
191
205
  open_connection do |conn|
192
206
  # attempt to fetch token to start secure flow first
193
207
  # and rescue to failover
194
- begin
195
- retry_errors(NETWORK_ERRORS, max_retries: @retries) do
196
- unless token_set?
197
- created_time = Time.now
198
- token_value, ttl = http_put(
199
- conn, METADATA_TOKEN_PATH, @token_ttl
200
- )
201
- @token = Token.new(token_value, ttl, created_time) if token_value && ttl
202
- end
203
- end
204
- rescue *NETWORK_ERRORS
205
- # token attempt failed, reset token
206
- # fallback to non-token mode
207
- @token = nil
208
- end
209
-
208
+ fetch_token(conn) unless @imds_v1_fallback
210
209
  token = @token.value if token_set?
211
210
 
212
- begin
213
- metadata = http_get(conn, METADATA_PATH_BASE, token)
214
- profile_name = metadata.lines.first.strip
215
- http_get(conn, METADATA_PATH_BASE + profile_name, token)
216
- rescue TokenExpiredError
217
- # Token has expired, reset it
218
- # The next retry should fetch it
219
- @token = nil
220
- raise Non200Response
221
- end
211
+ # disable insecure flow if we couldn't get token
212
+ # and imds v1 is disabled
213
+ raise TokenRetrivalError if token.nil? && @disable_imds_v1
214
+
215
+ _get_credentials(conn, token)
222
216
  end
223
217
  end
224
- rescue
218
+ rescue => e
219
+ warn("Error retrieving instance profile credentials: #{e}")
225
220
  '{}'
226
221
  end
227
222
  end
228
223
  end
229
224
 
225
+ def fetch_token(conn)
226
+ retry_errors(NETWORK_ERRORS, max_retries: @retries) do
227
+ unless token_set?
228
+ created_time = Time.now
229
+ token_value, ttl = http_put(
230
+ conn, METADATA_TOKEN_PATH, @token_ttl
231
+ )
232
+ @token = Token.new(token_value, ttl, created_time) if token_value && ttl
233
+ end
234
+ end
235
+ rescue *NETWORK_ERRORS
236
+ # token attempt failed, reset token
237
+ # fallback to non-token mode
238
+ @token = nil
239
+ @imds_v1_fallback = true
240
+ end
241
+
242
+ # token is optional - if nil, uses v1 (insecure) flow
243
+ def _get_credentials(conn, token)
244
+ metadata = http_get(conn, METADATA_PATH_BASE, token)
245
+ profile_name = metadata.lines.first.strip
246
+ http_get(conn, METADATA_PATH_BASE + profile_name, token)
247
+ rescue TokenExpiredError
248
+ # Token has expired, reset it
249
+ # The next retry should fetch it
250
+ @token = nil
251
+ @imds_v1_fallback = false
252
+ raise Non200Response
253
+ end
254
+
230
255
  def token_set?
231
256
  @token && !@token.expired?
232
257
  end
@@ -237,7 +262,7 @@ module Aws
237
262
 
238
263
  def open_connection
239
264
  uri = URI.parse(@endpoint)
240
- http = Net::HTTP.new(uri.hostname || @endpoint, @port || uri.port)
265
+ http = Net::HTTP.new(uri.hostname || @endpoint, uri.port || @port)
241
266
  http.open_timeout = @http_open_timeout
242
267
  http.read_timeout = @http_read_timeout
243
268
  http.set_debug_output(@http_debug_output) if @http_debug_output
@@ -276,8 +301,6 @@ module Aws
276
301
  ]
277
302
  when 400
278
303
  raise TokenRetrivalError
279
- when 401
280
- raise TokenExpiredError
281
304
  else
282
305
  raise Non200Response
283
306
  end
@@ -8,7 +8,7 @@ module Aws
8
8
 
9
9
  include Seahorse::Model::Shapes
10
10
 
11
- def initialize(rules)
11
+ def initialize(rules, _options = {})
12
12
  @rules = rules
13
13
  end
14
14
 
@@ -20,6 +20,8 @@ module Aws
20
20
  private
21
21
 
22
22
  def structure(ref, values)
23
+ return nil if values.nil?
24
+
23
25
  shape = ref.shape
24
26
  values.each_pair.with_object({}) do |(key, value), data|
25
27
  if shape.member?(key) && !value.nil?
@@ -31,11 +33,15 @@ module Aws
31
33
  end
32
34
 
33
35
  def list(ref, values)
36
+ return nil if values.nil?
37
+
34
38
  member_ref = ref.shape.member
35
39
  values.collect { |value| format(member_ref, value) }
36
40
  end
37
41
 
38
42
  def map(ref, values)
43
+ return nil if values.nil?
44
+
39
45
  value_ref = ref.shape.value
40
46
  values.each.with_object({}) do |(key, value), data|
41
47
  data[key] = format(value_ref, value)
@@ -49,6 +55,7 @@ module Aws
49
55
  when MapShape then map(ref, value)
50
56
  when TimestampShape then timestamp(ref, value)
51
57
  when BlobShape then encode(value)
58
+ when FloatShape then Util.serialize_number(value)
52
59
  else value
53
60
  end
54
61
  end
@@ -2,10 +2,8 @@
2
2
 
3
3
  module Aws
4
4
  module Json
5
- class ErrorHandler < Xml::ErrorHandler
5
+ class ErrorHandler < Aws::ErrorHandler
6
6
 
7
- # @param [Seahorse::Client::RequestContext] context
8
- # @return [Seahorse::Client::Response]
9
7
  def call(context)
10
8
  @handler.call(context).on(300..599) do |response|
11
9
  response.error = error(context)
@@ -19,7 +17,7 @@ module Aws
19
17
  json = Json.load(body)
20
18
  code = error_code(json, context)
21
19
  message = error_message(code, json)
22
- data = parse_error_data(context, code)
20
+ data = parse_error_data(context, body, code)
23
21
  [code, message, data]
24
22
  rescue Json::ParseError
25
23
  [http_status_error_code(context), '', EmptyStructure.new]
@@ -28,7 +26,8 @@ module Aws
28
26
  def error_code(json, context)
29
27
  code =
30
28
  if aws_query_error?(context)
31
- error = context.http_response.headers['x-amzn-query-error'].split(';')[0]
29
+ query_header = context.http_response.headers['x-amzn-query-error']
30
+ error, _type = query_header.split(';') # type not supported
32
31
  remove_prefix(error, context)
33
32
  else
34
33
  json['__type']
@@ -48,7 +47,7 @@ module Aws
48
47
  end
49
48
 
50
49
  def remove_prefix(error_code, context)
51
- if prefix = context.config.api.metadata['errorPrefix']
50
+ if (prefix = context.config.api.metadata['errorPrefix'])
52
51
  error_code.sub(/^#{prefix}/, '')
53
52
  else
54
53
  error_code
@@ -63,22 +62,29 @@ module Aws
63
62
  end
64
63
  end
65
64
 
66
- def parse_error_data(context, code)
65
+ def parse_error_data(context, body, code)
67
66
  data = EmptyStructure.new
68
- if error_rules = context.operation.errors
67
+ if (error_rules = context.operation.errors)
69
68
  error_rules.each do |rule|
70
69
  # match modeled shape name with the type(code) only
71
70
  # some type(code) might contains invalid characters
72
71
  # such as ':' (efs) etc
73
72
  match = rule.shape.name == code.gsub(/[^^a-zA-Z0-9]/, '')
74
- if match && rule.shape.members.any?
75
- data = Parser.new(rule).parse(context.http_response.body_contents)
76
- end
73
+ next unless match && rule.shape.members.any?
74
+
75
+ data = Parser.new(rule).parse(body)
76
+ # errors support HTTP bindings
77
+ apply_error_headers(rule, context, data)
77
78
  end
78
79
  end
79
80
  data
80
81
  end
81
82
 
83
+ def apply_error_headers(rule, context, data)
84
+ headers = Aws::Rest::Response::Headers.new(rule)
85
+ headers.apply(context.http_response, data)
86
+ end
87
+
82
88
  end
83
89
  end
84
90
  end
@@ -12,8 +12,7 @@ module Aws
12
12
  build_request(context)
13
13
  response = @handler.call(context)
14
14
  response.on(200..299) { |resp| parse_response(resp) }
15
- response.on(200..599) { |resp| apply_request_id(context) }
16
- response
15
+ response.on(200..599) { |_resp| apply_request_id(context) }
17
16
  end
18
17
 
19
18
  private
@@ -22,6 +21,7 @@ module Aws
22
21
  context.http_request.http_method = 'POST'
23
22
  context.http_request.headers['Content-Type'] = content_type(context)
24
23
  context.http_request.headers['X-Amz-Target'] = target(context)
24
+ context.http_request.headers['X-Amzn-Query-Mode'] = 'true' if query_compatible?(context)
25
25
  context.http_request.body = build_body(context)
26
26
  end
27
27
 
@@ -38,10 +38,10 @@ module Aws
38
38
  end
39
39
 
40
40
  def parse_body(context)
41
+ json = context.http_response.body_contents
41
42
  if simple_json?(context)
42
- Json.load(context.http_response.body_contents)
43
- elsif rules = context.operation.output
44
- json = context.http_response.body_contents
43
+ Json.load(json)
44
+ elsif (rules = context.operation.output)
45
45
  if json.is_a?(Array)
46
46
  # an array of emitted events
47
47
  if json[0].respond_to?(:response)
@@ -59,7 +59,10 @@ module Aws
59
59
  end
60
60
  resp_struct
61
61
  else
62
- Parser.new(rules).parse(json == '' ? '{}' : json)
62
+ Parser.new(
63
+ rules,
64
+ query_compatible: query_compatible?(context)
65
+ ).parse(json)
63
66
  end
64
67
  else
65
68
  EmptyStructure.new
@@ -83,6 +86,10 @@ module Aws
83
86
  context.config.simple_json
84
87
  end
85
88
 
89
+ def query_compatible?(context)
90
+ context.config.api.metadata.key?('awsQueryCompatible')
91
+ end
92
+
86
93
  end
87
94
  end
88
95
  end
@@ -1,8 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'json'
4
+
3
5
  module Aws
4
6
  module Json
5
- module JSONEngine
7
+ module JsonEngine
6
8
  class << self
7
9
  def load(json)
8
10
  JSON.parse(json)
@@ -1,10 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'oj'
4
+
3
5
  module Aws
4
6
  module Json
5
7
  module OjEngine
6
8
  # @api private
7
- LOAD_OPTIONS = { mode: :compat, symbol_keys: false, empty_string: false }.freeze
9
+ LOAD_OPTIONS = {
10
+ mode: :compat,
11
+ symbol_keys: false,
12
+ empty_string: false
13
+ }.freeze
8
14
 
9
15
  # @api private
10
16
  DUMP_OPTIONS = { mode: :compat }.freeze
@@ -10,12 +10,15 @@ module Aws
10
10
  include Seahorse::Model::Shapes
11
11
 
12
12
  # @param [Seahorse::Model::ShapeRef] rules
13
- def initialize(rules)
13
+ def initialize(rules, query_compatible: false)
14
14
  @rules = rules
15
+ @query_compatible = query_compatible
15
16
  end
16
17
 
17
18
  # @param [String<JSON>] json
18
19
  def parse(json, target = nil)
20
+ json = '{}' if json.empty?
21
+
19
22
  parse_ref(@rules, Json.load(json), target)
20
23
  end
21
24
 
@@ -32,6 +35,22 @@ module Aws
32
35
  target[:unknown] = { 'name' => key, 'value' => value }
33
36
  end
34
37
  end
38
+ # In services that were previously Query/XML, members that were
39
+ # "flattened" defaulted to empty lists. In JSON, these values are nil,
40
+ # which is backwards incompatible. To preserve backwards compatibility,
41
+ # we set a default value of [] for these members.
42
+ if @query_compatible
43
+ ref.shape.members.each do |member_name, member_target|
44
+ next unless target[member_name].nil?
45
+
46
+ if flattened_list?(member_target.shape)
47
+ target[member_name] = []
48
+ elsif flattened_map?(member_target.shape)
49
+ target[member_name] = {}
50
+ end
51
+ end
52
+ end
53
+
35
54
  if shape.union
36
55
  # convert to subclass
37
56
  member_subclass = shape.member_subclass(target.member).new
@@ -52,6 +71,8 @@ module Aws
52
71
  def map(ref, values, target = nil)
53
72
  target = {} if target.nil?
54
73
  values.each do |key, value|
74
+ next if value.nil?
75
+
55
76
  target[key] = parse_ref(ref.shape.value, value)
56
77
  end
57
78
  target
@@ -68,6 +89,7 @@ module Aws
68
89
  when TimestampShape then time(value)
69
90
  when BlobShape then Base64.decode64(value)
70
91
  when BooleanShape then value.to_s == 'true'
92
+ when FloatShape then Util.deserialize_number(value)
71
93
  else value
72
94
  end
73
95
  end
@@ -76,7 +98,15 @@ module Aws
76
98
  # @param [String, Integer] value
77
99
  # @return [Time]
78
100
  def time(value)
79
- value.is_a?(Numeric) ? Time.at(value) : Time.parse(value)
101
+ value.is_a?(Numeric) ? Time.at(value) : Aws::Util.deserialize_time(value)
102
+ end
103
+
104
+ def flattened_list?(shape)
105
+ shape.is_a?(ListShape) && shape.flattened
106
+ end
107
+
108
+ def flattened_map?(shape)
109
+ shape.is_a?(MapShape) && shape.flattened
80
110
  end
81
111
 
82
112
  end
@@ -1,12 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'json'
4
3
  require_relative 'json/builder'
5
4
  require_relative 'json/error_handler'
6
5
  require_relative 'json/handler'
7
6
  require_relative 'json/parser'
8
- require_relative 'json/json_engine'
9
- require_relative 'json/oj_engine'
10
7
 
11
8
  module Aws
12
9
  # @api private
@@ -21,29 +18,61 @@ module Aws
21
18
  end
22
19
 
23
20
  class << self
24
- def load(json)
25
- ENGINE.load(json)
21
+ # @param [Symbol,Class] engine
22
+ # Must be one of the following values:
23
+ #
24
+ # * :oj
25
+ # * :json
26
+ #
27
+ def engine=(engine)
28
+ @engine = Class === engine ? engine : load_engine(engine)
29
+ end
30
+
31
+ # @return [Class] Returns the default engine.
32
+ # One of:
33
+ #
34
+ # * {OjEngine}
35
+ # * {JsonEngine}
36
+ #
37
+ def engine
38
+ set_default_engine unless @engine
39
+ @engine
26
40
  end
27
41
 
28
- def load_file(path)
29
- load(File.open(path, 'r', encoding: 'UTF-8', &:read))
42
+ def load(json)
43
+ @engine.load(json)
30
44
  end
31
45
 
32
46
  def dump(value)
33
- ENGINE.dump(value)
47
+ @engine.dump(value)
48
+ end
49
+
50
+ def set_default_engine
51
+ [:oj, :json].each do |name|
52
+ @engine ||= try_load_engine(name)
53
+ end
54
+ unless @engine
55
+ raise 'Unable to find a compatible json library. ' \
56
+ 'Ensure that you have installed or added to your Gemfile one of ' \
57
+ 'oj or json'
58
+ end
34
59
  end
35
60
 
36
61
  private
37
62
 
38
- def select_engine
39
- require 'oj'
40
- OjEngine
63
+ def load_engine(name)
64
+ require "aws-sdk-core/json/#{name}_engine"
65
+ const_name = name[0].upcase + name[1..-1] + 'Engine'
66
+ const_get(const_name)
67
+ end
68
+
69
+ def try_load_engine(name)
70
+ load_engine(name)
41
71
  rescue LoadError
42
- JSONEngine
72
+ false
43
73
  end
44
74
  end
45
75
 
46
- # @api private
47
- ENGINE = select_engine
76
+ set_default_engine
48
77
  end
49
78
  end
@@ -55,14 +55,14 @@ module Aws
55
55
  filtered[key] = if @enabled && filters.include?(key)
56
56
  '[FILTERED]'
57
57
  else
58
- filter(value, type)
58
+ filter(value, value.class)
59
59
  end
60
60
  end
61
61
  filtered
62
62
  end
63
63
 
64
64
  def filter_array(values, type)
65
- values.map { |value| filter(value, type) }
65
+ values.map { |value| filter(value, value.class) }
66
66
  end
67
67
 
68
68
  end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ # setup autoloading for Log module
5
+ module Log
6
+ autoload :Formatter, 'aws-sdk-core/log/formatter'
7
+ autoload :ParamFilter, 'aws-sdk-core/log/param_filter'
8
+ autoload :ParamFormatter, 'aws-sdk-core/log/param_formatter'
9
+ end
10
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ # @api private
5
+ # A simple thread safe LRU cache
6
+ class LRUCache
7
+ # @param [Hash] options
8
+ # @option options [Integer] :max_entries (100) Maximum number of entries
9
+ # @option options [Integer] :expiration (nil) Expiration time in seconds
10
+ def initialize(options = {})
11
+ @max_entries = options[:max_entries] || 100
12
+ @expiration = options[:expiration]
13
+ @entries = {}
14
+ @mutex = Mutex.new
15
+ end
16
+
17
+ # @param [String] key
18
+ # @return [Object]
19
+ def [](key)
20
+ @mutex.synchronize do
21
+ value = @entries[key]
22
+ if value
23
+ @entries.delete(key)
24
+ @entries[key] = value unless value.expired?
25
+ end
26
+ @entries[key]&.value
27
+ end
28
+ end
29
+
30
+ # @param [String] key
31
+ # @param [Object] value
32
+ def []=(key, value)
33
+ @mutex.synchronize do
34
+ @entries.shift unless @entries.size < @max_entries
35
+ # delete old value if exists
36
+ @entries.delete(key)
37
+ @entries[key] = Entry.new(value: value, expiration: @expiration)
38
+ @entries[key].value
39
+ end
40
+ end
41
+
42
+ # @param [String] key
43
+ # @return [Boolean]
44
+ def key?(key)
45
+ @mutex.synchronize do
46
+ @entries.delete(key) if @entries.key?(key) && @entries[key].expired?
47
+ @entries.key?(key)
48
+ end
49
+ end
50
+
51
+ def clear
52
+ @mutex.synchronize do
53
+ @entries.clear
54
+ end
55
+ end
56
+
57
+ # @api private
58
+ class Entry
59
+ def initialize(options = {})
60
+ @value = options[:value]
61
+ @expiration = options[:expiration]
62
+ @created_time = Time.now
63
+ end
64
+
65
+ # @return [Object]
66
+ attr_reader :value
67
+
68
+ def expired?
69
+ return false unless @expiration
70
+
71
+ Time.now - @created_time > @expiration
72
+ end
73
+ end
74
+ end
75
+ end
@@ -201,7 +201,7 @@ module Aws
201
201
  def next_response(params)
202
202
  params = next_page_params(params)
203
203
  request = context.client.build_request(context.operation_name, params)
204
- Aws::Plugins::UserAgent.feature('paginator') do
204
+ Aws::Plugins::UserAgent.metric('PAGINATOR') do
205
205
  request.send_request
206
206
  end
207
207
  end
@@ -71,9 +71,10 @@ module Aws
71
71
  end
72
72
 
73
73
  if @validate_required && shape.union
74
- if values.length > 1
74
+ set_values = values.to_h.length
75
+ if set_values > 1
75
76
  errors << "multiple values provided to union at #{context} - must contain exactly one of the supported types: #{shape.member_names.join(', ')}"
76
- elsif values.length == 0
77
+ elsif set_values == 0
77
78
  errors << "No values provided to union at #{context} - must contain exactly one of the supported types: #{shape.member_names.join(', ')}"
78
79
  end
79
80
  end
@@ -106,6 +107,8 @@ module Aws
106
107
  # validate members
107
108
  member_ref = ref.shape.member
108
109
  values.each.with_index do |value, index|
110
+ next unless value
111
+
109
112
  shape(member_ref, value, errors, context + "[#{index}]")
110
113
  end
111
114
  end
@@ -121,6 +124,8 @@ module Aws
121
124
 
122
125
  values.each do |key, value|
123
126
  shape(key_ref, key, errors, "#{context} #{key.inspect} key")
127
+ next unless value
128
+
124
129
  shape(value_ref, value, errors, context + "[#{key.inspect}]")
125
130
  end
126
131
  end
@@ -4,6 +4,8 @@ module Aws
4
4
  # @api private
5
5
  module Plugins
6
6
  # @api private
7
+ # Deprecated - does not look at new traits like `auth` and `unsignedPayload`
8
+ # Necessary to exist after endpoints 2.0 for old service clients + new core
7
9
  class BearerAuthorization < Seahorse::Client::Plugin
8
10
 
9
11
  option(:token_provider,