aws-sdk-core 3.168.4 → 3.224.1

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 (205) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +719 -0
  3. data/VERSION +1 -1
  4. data/lib/aws-defaults/default_configuration.rb +5 -6
  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 +8 -1
  20. data/lib/aws-sdk-core/credential_provider_chain.rb +39 -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 +179 -53
  24. data/lib/aws-sdk-core/endpoints/condition.rb +5 -0
  25. data/lib/aws-sdk-core/endpoints/endpoint.rb +3 -1
  26. data/lib/aws-sdk-core/endpoints/endpoint_rule.rb +5 -1
  27. data/lib/aws-sdk-core/endpoints/error_rule.rb +5 -0
  28. data/lib/aws-sdk-core/endpoints/function.rb +5 -0
  29. data/lib/aws-sdk-core/endpoints/matchers.rb +19 -18
  30. data/lib/aws-sdk-core/endpoints/reference.rb +5 -0
  31. data/lib/aws-sdk-core/endpoints/rule.rb +5 -0
  32. data/lib/aws-sdk-core/endpoints/rule_set.rb +5 -0
  33. data/lib/aws-sdk-core/endpoints/rules_provider.rb +5 -0
  34. data/lib/aws-sdk-core/endpoints/templater.rb +6 -0
  35. data/lib/aws-sdk-core/endpoints/tree_rule.rb +5 -0
  36. data/lib/aws-sdk-core/endpoints/url.rb +1 -0
  37. data/lib/aws-sdk-core/endpoints.rb +79 -19
  38. data/lib/aws-sdk-core/error_handler.rb +41 -0
  39. data/lib/aws-sdk-core/errors.rb +14 -5
  40. data/lib/aws-sdk-core/event_emitter.rb +0 -16
  41. data/lib/aws-sdk-core/ini_parser.rb +7 -0
  42. data/lib/aws-sdk-core/instance_profile_credentials.rb +56 -32
  43. data/lib/aws-sdk-core/json/builder.rb +8 -1
  44. data/lib/aws-sdk-core/json/error_handler.rb +30 -14
  45. data/lib/aws-sdk-core/json/handler.rb +13 -6
  46. data/lib/aws-sdk-core/json/json_engine.rb +3 -1
  47. data/lib/aws-sdk-core/json/oj_engine.rb +7 -1
  48. data/lib/aws-sdk-core/json/parser.rb +33 -3
  49. data/lib/aws-sdk-core/json.rb +43 -14
  50. data/lib/aws-sdk-core/log/formatter.rb +6 -0
  51. data/lib/aws-sdk-core/log/param_filter.rb +2 -2
  52. data/lib/aws-sdk-core/log/param_formatter.rb +7 -3
  53. data/lib/aws-sdk-core/log.rb +10 -0
  54. data/lib/aws-sdk-core/lru_cache.rb +75 -0
  55. data/lib/aws-sdk-core/pageable_response.rb +3 -1
  56. data/lib/aws-sdk-core/param_validator.rb +9 -4
  57. data/lib/aws-sdk-core/plugins/bearer_authorization.rb +2 -0
  58. data/lib/aws-sdk-core/plugins/checksum_algorithm.rb +333 -168
  59. data/lib/aws-sdk-core/plugins/client_metrics_plugin.rb +1 -1
  60. data/lib/aws-sdk-core/plugins/client_metrics_send_plugin.rb +14 -2
  61. data/lib/aws-sdk-core/plugins/credentials_configuration.rb +9 -3
  62. data/lib/aws-sdk-core/plugins/endpoint_pattern.rb +40 -32
  63. data/lib/aws-sdk-core/plugins/global_configuration.rb +8 -9
  64. data/lib/aws-sdk-core/plugins/http_checksum.rb +3 -8
  65. data/lib/aws-sdk-core/plugins/invocation_id.rb +1 -11
  66. data/lib/aws-sdk-core/plugins/logging.rb +2 -0
  67. data/lib/aws-sdk-core/plugins/protocols/api_gateway.rb +3 -1
  68. data/lib/aws-sdk-core/plugins/protocols/ec2.rb +2 -24
  69. data/lib/aws-sdk-core/plugins/protocols/json_rpc.rb +6 -8
  70. data/lib/aws-sdk-core/plugins/protocols/query.rb +4 -2
  71. data/lib/aws-sdk-core/plugins/protocols/rest_json.rb +3 -15
  72. data/lib/aws-sdk-core/plugins/protocols/rest_xml.rb +3 -0
  73. data/lib/aws-sdk-core/plugins/protocols/rpc_v2.rb +17 -0
  74. data/lib/aws-sdk-core/plugins/regional_endpoint.rb +162 -37
  75. data/lib/aws-sdk-core/plugins/request_compression.rb +226 -0
  76. data/lib/aws-sdk-core/plugins/retry_errors.rb +12 -3
  77. data/lib/aws-sdk-core/plugins/sign.rb +44 -17
  78. data/lib/aws-sdk-core/plugins/signature_v2.rb +2 -1
  79. data/lib/aws-sdk-core/plugins/signature_v4.rb +2 -1
  80. data/lib/aws-sdk-core/plugins/stub_responses.rb +53 -9
  81. data/lib/aws-sdk-core/plugins/telemetry.rb +75 -0
  82. data/lib/aws-sdk-core/plugins/transfer_encoding.rb +16 -9
  83. data/lib/aws-sdk-core/plugins/user_agent.rb +191 -14
  84. data/lib/aws-sdk-core/plugins.rb +39 -0
  85. data/lib/aws-sdk-core/process_credentials.rb +48 -29
  86. data/lib/aws-sdk-core/query/ec2_handler.rb +27 -0
  87. data/lib/aws-sdk-core/query/ec2_param_builder.rb +5 -7
  88. data/lib/aws-sdk-core/query/handler.rb +4 -4
  89. data/lib/aws-sdk-core/query/param_builder.rb +2 -2
  90. data/lib/aws-sdk-core/query.rb +2 -1
  91. data/lib/aws-sdk-core/refreshing_credentials.rb +12 -12
  92. data/lib/aws-sdk-core/resources.rb +8 -0
  93. data/lib/aws-sdk-core/rest/content_type_handler.rb +60 -0
  94. data/lib/aws-sdk-core/rest/handler.rb +3 -4
  95. data/lib/aws-sdk-core/rest/request/body.rb +32 -5
  96. data/lib/aws-sdk-core/rest/request/endpoint.rb +24 -4
  97. data/lib/aws-sdk-core/rest/request/headers.rb +15 -7
  98. data/lib/aws-sdk-core/rest/request/querystring_builder.rb +62 -36
  99. data/lib/aws-sdk-core/rest/response/body.rb +15 -1
  100. data/lib/aws-sdk-core/rest/response/header_list_parser.rb +79 -0
  101. data/lib/aws-sdk-core/rest/response/headers.rb +8 -3
  102. data/lib/aws-sdk-core/rest.rb +1 -0
  103. data/lib/aws-sdk-core/rpc_v2/builder.rb +62 -0
  104. data/lib/aws-sdk-core/rpc_v2/cbor_engine.rb +18 -0
  105. data/lib/aws-sdk-core/rpc_v2/content_type_handler.rb +47 -0
  106. data/lib/aws-sdk-core/rpc_v2/error_handler.rb +85 -0
  107. data/lib/aws-sdk-core/rpc_v2/handler.rb +79 -0
  108. data/lib/aws-sdk-core/rpc_v2/parser.rb +90 -0
  109. data/lib/aws-sdk-core/rpc_v2.rb +69 -0
  110. data/lib/aws-sdk-core/shared_config.rb +125 -39
  111. data/lib/aws-sdk-core/shared_credentials.rb +1 -7
  112. data/lib/aws-sdk-core/sso_credentials.rb +5 -2
  113. data/lib/aws-sdk-core/stubbing/protocols/ec2.rb +12 -11
  114. data/lib/aws-sdk-core/stubbing/protocols/json.rb +11 -10
  115. data/lib/aws-sdk-core/stubbing/protocols/query.rb +7 -6
  116. data/lib/aws-sdk-core/stubbing/protocols/rest.rb +2 -1
  117. data/lib/aws-sdk-core/stubbing/protocols/rest_json.rb +9 -8
  118. data/lib/aws-sdk-core/stubbing/protocols/rest_xml.rb +6 -5
  119. data/lib/aws-sdk-core/stubbing/protocols/rpc_v2.rb +39 -0
  120. data/lib/aws-sdk-core/stubbing/stub_data.rb +11 -0
  121. data/lib/aws-sdk-core/stubbing.rb +22 -0
  122. data/lib/aws-sdk-core/telemetry/base.rb +177 -0
  123. data/lib/aws-sdk-core/telemetry/no_op.rb +70 -0
  124. data/lib/aws-sdk-core/telemetry/otel.rb +235 -0
  125. data/lib/aws-sdk-core/telemetry/span_kind.rb +22 -0
  126. data/lib/aws-sdk-core/telemetry/span_status.rb +59 -0
  127. data/lib/aws-sdk-core/telemetry.rb +78 -0
  128. data/lib/aws-sdk-core/util.rb +39 -0
  129. data/lib/aws-sdk-core/waiters/poller.rb +12 -5
  130. data/lib/aws-sdk-core/xml/builder.rb +17 -9
  131. data/lib/aws-sdk-core/xml/error_handler.rb +32 -42
  132. data/lib/aws-sdk-core/xml/parser/frame.rb +4 -20
  133. data/lib/aws-sdk-core/xml/parser/{engines/oga.rb → oga_engine.rb} +2 -0
  134. data/lib/aws-sdk-core/xml/parser/stack.rb +2 -0
  135. data/lib/aws-sdk-core/xml/parser.rb +2 -6
  136. data/lib/aws-sdk-core.rb +82 -107
  137. data/lib/aws-sdk-sso/client.rb +185 -79
  138. data/lib/aws-sdk-sso/client_api.rb +7 -0
  139. data/lib/aws-sdk-sso/endpoint_parameters.rb +9 -6
  140. data/lib/aws-sdk-sso/endpoint_provider.rb +37 -96
  141. data/lib/aws-sdk-sso/endpoints.rb +3 -54
  142. data/lib/aws-sdk-sso/plugins/endpoints.rb +23 -22
  143. data/lib/aws-sdk-sso/types.rb +1 -0
  144. data/lib/aws-sdk-sso.rb +15 -11
  145. data/lib/aws-sdk-ssooidc/client.rb +592 -112
  146. data/lib/aws-sdk-ssooidc/client_api.rb +89 -1
  147. data/lib/aws-sdk-ssooidc/endpoint_parameters.rb +9 -6
  148. data/lib/aws-sdk-ssooidc/endpoint_provider.rb +37 -95
  149. data/lib/aws-sdk-ssooidc/endpoints.rb +3 -40
  150. data/lib/aws-sdk-ssooidc/errors.rb +52 -0
  151. data/lib/aws-sdk-ssooidc/plugins/endpoints.rb +23 -20
  152. data/lib/aws-sdk-ssooidc/types.rb +407 -53
  153. data/lib/aws-sdk-ssooidc.rb +15 -11
  154. data/lib/aws-sdk-sts/client.rb +516 -238
  155. data/lib/aws-sdk-sts/client_api.rb +48 -11
  156. data/lib/aws-sdk-sts/customizations.rb +5 -1
  157. data/lib/aws-sdk-sts/endpoint_parameters.rb +10 -9
  158. data/lib/aws-sdk-sts/endpoint_provider.rb +91 -213
  159. data/lib/aws-sdk-sts/endpoints.rb +3 -118
  160. data/lib/aws-sdk-sts/errors.rb +16 -0
  161. data/lib/aws-sdk-sts/plugins/endpoints.rb +23 -30
  162. data/lib/aws-sdk-sts/presigner.rb +1 -1
  163. data/lib/aws-sdk-sts/types.rb +217 -36
  164. data/lib/aws-sdk-sts.rb +15 -11
  165. data/lib/seahorse/client/async_base.rb +4 -5
  166. data/lib/seahorse/client/async_response.rb +19 -0
  167. data/lib/seahorse/client/base.rb +18 -21
  168. data/lib/seahorse/client/configuration.rb +0 -4
  169. data/lib/seahorse/client/h2/connection.rb +25 -31
  170. data/lib/seahorse/client/h2/handler.rb +14 -3
  171. data/lib/seahorse/client/handler.rb +1 -1
  172. data/lib/seahorse/client/http/response.rb +1 -1
  173. data/lib/seahorse/client/net_http/connection_pool.rb +13 -11
  174. data/lib/seahorse/client/net_http/handler.rb +21 -9
  175. data/lib/seahorse/client/net_http/patches.rb +1 -4
  176. data/lib/seahorse/client/networking_error.rb +1 -1
  177. data/lib/seahorse/client/plugin.rb +9 -0
  178. data/lib/seahorse/client/plugins/endpoint.rb +0 -1
  179. data/lib/seahorse/client/plugins/h2.rb +4 -4
  180. data/lib/seahorse/client/plugins/net_http.rb +57 -16
  181. data/lib/seahorse/client/plugins/request_callback.rb +31 -0
  182. data/lib/seahorse/client/request_context.rb +8 -1
  183. data/lib/seahorse/client/response.rb +8 -0
  184. data/lib/seahorse/model/operation.rb +3 -0
  185. data/lib/seahorse/model/shapes.rb +2 -2
  186. data/sig/aws-sdk-core/async_client_stubs.rbs +21 -0
  187. data/sig/aws-sdk-core/client_stubs.rbs +10 -0
  188. data/sig/aws-sdk-core/errors.rbs +22 -0
  189. data/sig/aws-sdk-core/resources/collection.rbs +21 -0
  190. data/sig/aws-sdk-core/structure.rbs +4 -0
  191. data/sig/aws-sdk-core/telemetry/base.rbs +46 -0
  192. data/sig/aws-sdk-core/telemetry/otel.rbs +22 -0
  193. data/sig/aws-sdk-core/telemetry/span_kind.rbs +15 -0
  194. data/sig/aws-sdk-core/telemetry/span_status.rbs +24 -0
  195. data/sig/aws-sdk-core/waiters/errors.rbs +20 -0
  196. data/sig/aws-sdk-core.rbs +7 -0
  197. data/sig/seahorse/client/async_base.rbs +18 -0
  198. data/sig/seahorse/client/base.rbs +25 -0
  199. data/sig/seahorse/client/handler_builder.rbs +16 -0
  200. data/sig/seahorse/client/response.rbs +61 -0
  201. metadata +92 -23
  202. /data/lib/aws-sdk-core/xml/parser/{engines/libxml.rb → libxml_engine.rb} +0 -0
  203. /data/lib/aws-sdk-core/xml/parser/{engines/nokogiri.rb → nokogiri_engine.rb} +0 -0
  204. /data/lib/aws-sdk-core/xml/parser/{engines/ox.rb → ox_engine.rb} +0 -0
  205. /data/lib/aws-sdk-core/xml/parser/{engines/rexml.rb → rexml_engine.rb} +0 -0
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ class ErrorHandler < Seahorse::Client::Handler
5
+
6
+ private
7
+
8
+ def error(context)
9
+ body = context.http_response.body_contents
10
+ if body.empty?
11
+ code, message, data = http_status_error(context)
12
+ else
13
+ code, message, data = extract_error(body, context)
14
+ end
15
+ build_error(context, code, message, data)
16
+ end
17
+
18
+ def build_error(context, code, message, data)
19
+ errors_module = context.client.class.errors_module
20
+ errors_module.error_class(code).new(context, message, data)
21
+ end
22
+
23
+ def http_status_error(context)
24
+ [http_status_error_code(context), '', EmptyStructure.new]
25
+ end
26
+
27
+ def http_status_error_code(context)
28
+ status_code = context.http_response.status_code
29
+ {
30
+ 302 => 'MovedTemporarily',
31
+ 304 => 'NotModified',
32
+ 400 => 'BadRequest',
33
+ 403 => 'Forbidden',
34
+ 404 => 'NotFound',
35
+ 412 => 'PreconditionFailed',
36
+ 413 => 'RequestEntityTooLarge',
37
+ }[status_code] || "Http#{status_code}Error"
38
+ end
39
+
40
+ end
41
+ 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
 
@@ -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?
22
+ previous_item = item
20
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] ||= {}
@@ -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]
@@ -85,6 +90,7 @@ module Aws
85
90
  @token = nil
86
91
  @no_refresh_until = nil
87
92
  @async_refresh = false
93
+ @metrics = ['CREDENTIALS_IMDS']
88
94
  super
89
95
  end
90
96
 
@@ -123,6 +129,16 @@ module Aws
123
129
  end
124
130
  end
125
131
 
132
+ def resolve_disable_v1(options)
133
+ value = options[:disable_imds_v1]
134
+ value ||= ENV['AWS_EC2_METADATA_V1_DISABLED']
135
+ value ||= Aws.shared_config.ec2_metadata_v1_disabled(
136
+ profile: options[:profile]
137
+ )
138
+ value = value.to_s.downcase if value
139
+ Aws::Util.str_2_bool(value) || false
140
+ end
141
+
126
142
  def backoff(backoff)
127
143
  case backoff
128
144
  when Proc then backoff
@@ -141,7 +157,7 @@ module Aws
141
157
  # service is responding but is returning invalid JSON documents
142
158
  # in response to the GET profile credentials call.
143
159
  begin
144
- retry_errors([Aws::Json::ParseError, StandardError], max_retries: 3) do
160
+ retry_errors([Aws::Json::ParseError], max_retries: 3) do
145
161
  c = Aws::Json.load(get_credentials.to_s)
146
162
  if empty_credentials?(@credentials)
147
163
  @credentials = Credentials.new(
@@ -173,7 +189,6 @@ module Aws
173
189
  end
174
190
  end
175
191
  end
176
-
177
192
  end
178
193
  rescue Aws::Json::ParseError
179
194
  raise Aws::Errors::MetadataParserError
@@ -191,42 +206,53 @@ module Aws
191
206
  open_connection do |conn|
192
207
  # attempt to fetch token to start secure flow first
193
208
  # 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
-
209
+ fetch_token(conn) unless @imds_v1_fallback
210
210
  token = @token.value if token_set?
211
211
 
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
212
+ # disable insecure flow if we couldn't get token
213
+ # and imds v1 is disabled
214
+ raise TokenRetrivalError if token.nil? && @disable_imds_v1
215
+
216
+ _get_credentials(conn, token)
222
217
  end
223
218
  end
224
- rescue
219
+ rescue => e
220
+ warn("Error retrieving instance profile credentials: #{e}")
225
221
  '{}'
226
222
  end
227
223
  end
228
224
  end
229
225
 
226
+ def fetch_token(conn)
227
+ retry_errors(NETWORK_ERRORS, max_retries: @retries) do
228
+ unless token_set?
229
+ created_time = Time.now
230
+ token_value, ttl = http_put(
231
+ conn, METADATA_TOKEN_PATH, @token_ttl
232
+ )
233
+ @token = Token.new(token_value, ttl, created_time) if token_value && ttl
234
+ end
235
+ end
236
+ rescue *NETWORK_ERRORS
237
+ # token attempt failed, reset token
238
+ # fallback to non-token mode
239
+ @token = nil
240
+ @imds_v1_fallback = true
241
+ end
242
+
243
+ # token is optional - if nil, uses v1 (insecure) flow
244
+ def _get_credentials(conn, token)
245
+ metadata = http_get(conn, METADATA_PATH_BASE, token)
246
+ profile_name = metadata.lines.first.strip
247
+ http_get(conn, METADATA_PATH_BASE + profile_name, token)
248
+ rescue TokenExpiredError
249
+ # Token has expired, reset it
250
+ # The next retry should fetch it
251
+ @token = nil
252
+ @imds_v1_fallback = false
253
+ raise Non200Response
254
+ end
255
+
230
256
  def token_set?
231
257
  @token && !@token.expired?
232
258
  end
@@ -237,7 +263,7 @@ module Aws
237
263
 
238
264
  def open_connection
239
265
  uri = URI.parse(@endpoint)
240
- http = Net::HTTP.new(uri.hostname || @endpoint, @port || uri.port)
266
+ http = Net::HTTP.new(uri.hostname || @endpoint, uri.port || @port)
241
267
  http.open_timeout = @http_open_timeout
242
268
  http.read_timeout = @http_read_timeout
243
269
  http.set_debug_output(@http_debug_output) if @http_debug_output
@@ -276,8 +302,6 @@ module Aws
276
302
  ]
277
303
  when 400
278
304
  raise TokenRetrivalError
279
- when 401
280
- raise TokenExpiredError
281
305
  else
282
306
  raise Non200Response
283
307
  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,18 +17,21 @@ 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]
26
24
  end
27
25
 
28
26
  def error_code(json, context)
29
- code = if aws_query_error?(context)
30
- context.http_response.headers['x-amzn-query-error'].split(';')[0]
31
- else
32
- json['__type']
33
- end
27
+ code =
28
+ if aws_query_error?(context)
29
+ query_header = context.http_response.headers['x-amzn-query-error']
30
+ error, _type = query_header.split(';') # type not supported
31
+ remove_prefix(error, context)
32
+ else
33
+ json['__type']
34
+ end
34
35
  code ||= json['code']
35
36
  code ||= context.http_response.headers['x-amzn-errortype']
36
37
  if code
@@ -45,6 +46,14 @@ module Aws
45
46
  context.http_response.headers['x-amzn-query-error']
46
47
  end
47
48
 
49
+ def remove_prefix(error_code, context)
50
+ if (prefix = context.config.api.metadata['errorPrefix'])
51
+ error_code.sub(/^#{prefix}/, '')
52
+ else
53
+ error_code
54
+ end
55
+ end
56
+
48
57
  def error_message(code, json)
49
58
  if code == 'RequestEntityTooLarge'
50
59
  'Request body must be less than 1 MB'
@@ -53,22 +62,29 @@ module Aws
53
62
  end
54
63
  end
55
64
 
56
- def parse_error_data(context, code)
65
+ def parse_error_data(context, body, code)
57
66
  data = EmptyStructure.new
58
- if error_rules = context.operation.errors
67
+ if (error_rules = context.operation.errors)
59
68
  error_rules.each do |rule|
60
69
  # match modeled shape name with the type(code) only
61
70
  # some type(code) might contains invalid characters
62
71
  # such as ':' (efs) etc
63
72
  match = rule.shape.name == code.gsub(/[^^a-zA-Z0-9]/, '')
64
- if match && rule.shape.members.any?
65
- data = Parser.new(rule).parse(context.http_response.body_contents)
66
- 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)
67
78
  end
68
79
  end
69
80
  data
70
81
  end
71
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
+
72
88
  end
73
89
  end
74
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
 
@@ -28,10 +31,26 @@ module Aws
28
31
  member_name, member_ref = shape.member_by_location_name(key)
29
32
  if member_ref
30
33
  target[member_name] = parse_ref(member_ref, value)
31
- elsif shape.union
34
+ elsif shape.union && key != '__type'
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