aws-sdk-core 3.171.1 → 3.234.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 (199) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +787 -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 +21 -13
  8. data/lib/aws-sdk-core/assume_role_web_identity_credentials.rb +16 -9
  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 +74 -25
  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 +92 -24
  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 +106 -22
  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 +7 -0
  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/formatter.rb +6 -0
  40. data/lib/aws-sdk-core/log/param_filter.rb +2 -2
  41. data/lib/aws-sdk-core/log/param_formatter.rb +7 -3
  42. data/lib/aws-sdk-core/log.rb +10 -0
  43. data/lib/aws-sdk-core/lru_cache.rb +75 -0
  44. data/lib/aws-sdk-core/pageable_response.rb +3 -1
  45. data/lib/aws-sdk-core/param_validator.rb +9 -4
  46. data/lib/aws-sdk-core/plugins/bearer_authorization.rb +2 -0
  47. data/lib/aws-sdk-core/plugins/checksum_algorithm.rb +348 -169
  48. data/lib/aws-sdk-core/plugins/client_metrics_plugin.rb +1 -1
  49. data/lib/aws-sdk-core/plugins/client_metrics_send_plugin.rb +14 -2
  50. data/lib/aws-sdk-core/plugins/credentials_configuration.rb +78 -56
  51. data/lib/aws-sdk-core/plugins/endpoint_pattern.rb +40 -32
  52. data/lib/aws-sdk-core/plugins/global_configuration.rb +8 -9
  53. data/lib/aws-sdk-core/plugins/http_checksum.rb +3 -8
  54. data/lib/aws-sdk-core/plugins/invocation_id.rb +1 -11
  55. data/lib/aws-sdk-core/plugins/logging.rb +2 -0
  56. data/lib/aws-sdk-core/plugins/protocols/api_gateway.rb +3 -1
  57. data/lib/aws-sdk-core/plugins/protocols/ec2.rb +2 -24
  58. data/lib/aws-sdk-core/plugins/protocols/json_rpc.rb +6 -8
  59. data/lib/aws-sdk-core/plugins/protocols/query.rb +4 -2
  60. data/lib/aws-sdk-core/plugins/protocols/rest_json.rb +3 -15
  61. data/lib/aws-sdk-core/plugins/protocols/rest_xml.rb +3 -0
  62. data/lib/aws-sdk-core/plugins/protocols/rpc_v2.rb +17 -0
  63. data/lib/aws-sdk-core/plugins/regional_endpoint.rb +162 -37
  64. data/lib/aws-sdk-core/plugins/request_compression.rb +226 -0
  65. data/lib/aws-sdk-core/plugins/retry_errors.rb +12 -3
  66. data/lib/aws-sdk-core/plugins/sign.rb +55 -33
  67. data/lib/aws-sdk-core/plugins/signature_v2.rb +2 -1
  68. data/lib/aws-sdk-core/plugins/signature_v4.rb +2 -1
  69. data/lib/aws-sdk-core/plugins/stub_responses.rb +59 -9
  70. data/lib/aws-sdk-core/plugins/telemetry.rb +75 -0
  71. data/lib/aws-sdk-core/plugins/transfer_encoding.rb +16 -9
  72. data/lib/aws-sdk-core/plugins/user_agent.rb +192 -14
  73. data/lib/aws-sdk-core/plugins.rb +39 -0
  74. data/lib/aws-sdk-core/process_credentials.rb +48 -29
  75. data/lib/aws-sdk-core/query/ec2_handler.rb +27 -0
  76. data/lib/aws-sdk-core/query/ec2_param_builder.rb +5 -7
  77. data/lib/aws-sdk-core/query/handler.rb +4 -4
  78. data/lib/aws-sdk-core/query/param_builder.rb +2 -2
  79. data/lib/aws-sdk-core/query.rb +2 -1
  80. data/lib/aws-sdk-core/refreshing_credentials.rb +20 -23
  81. data/lib/aws-sdk-core/resources.rb +8 -0
  82. data/lib/aws-sdk-core/rest/content_type_handler.rb +60 -0
  83. data/lib/aws-sdk-core/rest/handler.rb +3 -4
  84. data/lib/aws-sdk-core/rest/request/body.rb +32 -5
  85. data/lib/aws-sdk-core/rest/request/endpoint.rb +24 -4
  86. data/lib/aws-sdk-core/rest/request/headers.rb +15 -7
  87. data/lib/aws-sdk-core/rest/request/querystring_builder.rb +62 -36
  88. data/lib/aws-sdk-core/rest/response/body.rb +15 -1
  89. data/lib/aws-sdk-core/rest/response/header_list_parser.rb +79 -0
  90. data/lib/aws-sdk-core/rest/response/headers.rb +8 -3
  91. data/lib/aws-sdk-core/rest.rb +1 -0
  92. data/lib/aws-sdk-core/rpc_v2/builder.rb +62 -0
  93. data/lib/aws-sdk-core/rpc_v2/cbor_engine.rb +18 -0
  94. data/lib/aws-sdk-core/rpc_v2/content_type_handler.rb +47 -0
  95. data/lib/aws-sdk-core/rpc_v2/error_handler.rb +95 -0
  96. data/lib/aws-sdk-core/rpc_v2/handler.rb +79 -0
  97. data/lib/aws-sdk-core/rpc_v2/parser.rb +98 -0
  98. data/lib/aws-sdk-core/rpc_v2.rb +69 -0
  99. data/lib/aws-sdk-core/shared_config.rb +135 -39
  100. data/lib/aws-sdk-core/shared_credentials.rb +1 -7
  101. data/lib/aws-sdk-core/sso_credentials.rb +6 -3
  102. data/lib/aws-sdk-core/static_token_provider.rb +1 -2
  103. data/lib/aws-sdk-core/stubbing/protocols/ec2.rb +12 -11
  104. data/lib/aws-sdk-core/stubbing/protocols/json.rb +11 -10
  105. data/lib/aws-sdk-core/stubbing/protocols/query.rb +7 -6
  106. data/lib/aws-sdk-core/stubbing/protocols/rest.rb +2 -1
  107. data/lib/aws-sdk-core/stubbing/protocols/rest_json.rb +9 -8
  108. data/lib/aws-sdk-core/stubbing/protocols/rest_xml.rb +6 -5
  109. data/lib/aws-sdk-core/stubbing/protocols/rpc_v2.rb +39 -0
  110. data/lib/aws-sdk-core/stubbing/stub_data.rb +11 -0
  111. data/lib/aws-sdk-core/stubbing.rb +22 -0
  112. data/lib/aws-sdk-core/telemetry/base.rb +177 -0
  113. data/lib/aws-sdk-core/telemetry/no_op.rb +70 -0
  114. data/lib/aws-sdk-core/telemetry/otel.rb +235 -0
  115. data/lib/aws-sdk-core/telemetry/span_kind.rb +22 -0
  116. data/lib/aws-sdk-core/telemetry/span_status.rb +59 -0
  117. data/lib/aws-sdk-core/telemetry.rb +78 -0
  118. data/lib/aws-sdk-core/token.rb +3 -3
  119. data/lib/aws-sdk-core/token_provider.rb +4 -0
  120. data/lib/aws-sdk-core/token_provider_chain.rb +2 -6
  121. data/lib/aws-sdk-core/util.rb +41 -1
  122. data/lib/aws-sdk-core/waiters/poller.rb +12 -5
  123. data/lib/aws-sdk-core/xml/builder.rb +17 -9
  124. data/lib/aws-sdk-core/xml/error_handler.rb +35 -43
  125. data/lib/aws-sdk-core/xml/parser/frame.rb +4 -20
  126. data/lib/aws-sdk-core/xml/parser/stack.rb +2 -0
  127. data/lib/aws-sdk-core/xml/parser.rb +2 -6
  128. data/lib/aws-sdk-core.rb +82 -107
  129. data/lib/aws-sdk-sso/client.rb +205 -92
  130. data/lib/aws-sdk-sso/client_api.rb +7 -0
  131. data/lib/aws-sdk-sso/endpoint_parameters.rb +9 -6
  132. data/lib/aws-sdk-sso/endpoint_provider.rb +30 -28
  133. data/lib/aws-sdk-sso/endpoints.rb +3 -54
  134. data/lib/aws-sdk-sso/plugins/endpoints.rb +23 -22
  135. data/lib/aws-sdk-sso/types.rb +1 -0
  136. data/lib/aws-sdk-sso.rb +15 -11
  137. data/lib/aws-sdk-ssooidc/client.rb +625 -125
  138. data/lib/aws-sdk-ssooidc/client_api.rb +94 -1
  139. data/lib/aws-sdk-ssooidc/endpoint_parameters.rb +9 -6
  140. data/lib/aws-sdk-ssooidc/endpoint_provider.rb +30 -28
  141. data/lib/aws-sdk-ssooidc/endpoints.rb +3 -40
  142. data/lib/aws-sdk-ssooidc/errors.rb +62 -0
  143. data/lib/aws-sdk-ssooidc/plugins/endpoints.rb +23 -20
  144. data/lib/aws-sdk-ssooidc/types.rb +419 -53
  145. data/lib/aws-sdk-ssooidc.rb +15 -11
  146. data/lib/aws-sdk-sts/client.rb +526 -243
  147. data/lib/aws-sdk-sts/client_api.rb +48 -9
  148. data/lib/aws-sdk-sts/customizations.rb +5 -2
  149. data/lib/aws-sdk-sts/endpoint_parameters.rb +10 -9
  150. data/lib/aws-sdk-sts/endpoint_provider.rb +82 -84
  151. data/lib/aws-sdk-sts/endpoints.rb +3 -118
  152. data/lib/aws-sdk-sts/errors.rb +15 -0
  153. data/lib/aws-sdk-sts/plugins/endpoints.rb +23 -30
  154. data/lib/aws-sdk-sts/presigner.rb +3 -7
  155. data/lib/aws-sdk-sts/types.rb +217 -36
  156. data/lib/aws-sdk-sts.rb +15 -11
  157. data/lib/seahorse/client/async_base.rb +4 -5
  158. data/lib/seahorse/client/async_response.rb +19 -0
  159. data/lib/seahorse/client/base.rb +18 -21
  160. data/lib/seahorse/client/configuration.rb +0 -4
  161. data/lib/seahorse/client/h2/connection.rb +18 -28
  162. data/lib/seahorse/client/h2/handler.rb +14 -3
  163. data/lib/seahorse/client/handler.rb +1 -1
  164. data/lib/seahorse/client/http/response.rb +1 -1
  165. data/lib/seahorse/client/net_http/connection_pool.rb +15 -12
  166. data/lib/seahorse/client/net_http/handler.rb +21 -9
  167. data/lib/seahorse/client/net_http/patches.rb +1 -4
  168. data/lib/seahorse/client/networking_error.rb +1 -1
  169. data/lib/seahorse/client/plugin.rb +9 -0
  170. data/lib/seahorse/client/plugins/endpoint.rb +0 -1
  171. data/lib/seahorse/client/plugins/h2.rb +4 -4
  172. data/lib/seahorse/client/plugins/net_http.rb +57 -16
  173. data/lib/seahorse/client/plugins/request_callback.rb +31 -0
  174. data/lib/seahorse/client/request_context.rb +9 -2
  175. data/lib/seahorse/client/response.rb +8 -0
  176. data/lib/seahorse/model/operation.rb +3 -0
  177. data/lib/seahorse/model/shapes.rb +2 -2
  178. data/lib/seahorse/util.rb +2 -1
  179. data/sig/aws-sdk-core/async_client_stubs.rbs +21 -0
  180. data/sig/aws-sdk-core/client_stubs.rbs +10 -0
  181. data/sig/aws-sdk-core/errors.rbs +22 -0
  182. data/sig/aws-sdk-core/resources/collection.rbs +21 -0
  183. data/sig/aws-sdk-core/structure.rbs +4 -0
  184. data/sig/aws-sdk-core/telemetry/base.rbs +46 -0
  185. data/sig/aws-sdk-core/telemetry/otel.rbs +22 -0
  186. data/sig/aws-sdk-core/telemetry/span_kind.rbs +15 -0
  187. data/sig/aws-sdk-core/telemetry/span_status.rbs +24 -0
  188. data/sig/aws-sdk-core/waiters/errors.rbs +20 -0
  189. data/sig/aws-sdk-core.rbs +7 -0
  190. data/sig/seahorse/client/async_base.rbs +18 -0
  191. data/sig/seahorse/client/base.rbs +25 -0
  192. data/sig/seahorse/client/handler_builder.rbs +16 -0
  193. data/sig/seahorse/client/response.rbs +61 -0
  194. metadata +106 -23
  195. /data/lib/aws-sdk-core/xml/parser/{engines/libxml.rb → libxml_engine.rb} +0 -0
  196. /data/lib/aws-sdk-core/xml/parser/{engines/nokogiri.rb → nokogiri_engine.rb} +0 -0
  197. /data/lib/aws-sdk-core/xml/parser/{engines/oga.rb → oga_engine.rb} +0 -0
  198. /data/lib/aws-sdk-core/xml/parser/{engines/ox.rb → ox_engine.rb} +0 -0
  199. /data/lib/aws-sdk-core/xml/parser/{engines/rexml.rb → rexml_engine.rb} +0 -0
@@ -20,16 +20,31 @@ a default `:region` is searched for in the following locations:
20
20
  * `ENV['AWS_DEFAULT_REGION']`
21
21
  * `~/.aws/credentials`
22
22
  * `~/.aws/config`
23
- DOCS
23
+ DOCS
24
24
  resolve_region(cfg)
25
25
  end
26
26
 
27
+ option(:sigv4a_signing_region_set,
28
+ doc_type: Array,
29
+ rbs_type: 'Array[String]',
30
+ docstring: <<-DOCS) do |cfg|
31
+ A list of regions that should be signed with SigV4a signing. When
32
+ not passed, a default `:sigv4a_signing_region_set` is searched for
33
+ in the following locations:
34
+
35
+ * `Aws.config[:sigv4a_signing_region_set]`
36
+ * `ENV['AWS_SIGV4A_SIGNING_REGION_SET']`
37
+ * `~/.aws/config`
38
+ DOCS
39
+ resolve_sigv4a_signing_region_set(cfg)
40
+ end
41
+
27
42
  option(:use_dualstack_endpoint,
28
43
  doc_type: 'Boolean',
29
44
  docstring: <<-DOCS) do |cfg|
30
45
  When set to `true`, dualstack enabled endpoints (with `.aws` TLD)
31
46
  will be used if available.
32
- DOCS
47
+ DOCS
33
48
  resolve_use_dualstack_endpoint(cfg)
34
49
  end
35
50
 
@@ -39,7 +54,7 @@ will be used if available.
39
54
  When set to `true`, fips compatible endpoints will be used if available.
40
55
  When a `fips` region is used, the region is normalized and this config
41
56
  is set to `true`.
42
- DOCS
57
+ DOCS
43
58
  resolve_use_fips_endpoint(cfg)
44
59
  end
45
60
 
@@ -47,50 +62,71 @@ is set to `true`.
47
62
  # Legacy endpoints must continue to be generated at client time.
48
63
  option(:regional_endpoint, false)
49
64
 
50
- # NOTE: All of the defaults block code is effectively deprecated.
51
- # Because old services can depend on this new core version, we must
52
- # retain it.
65
+ option(:ignore_configured_endpoint_urls,
66
+ doc_type: 'Boolean',
67
+ docstring: <<-DOCS) do |cfg|
68
+ Setting to true disables use of endpoint URLs provided via environment
69
+ variables and the shared configuration file.
70
+ DOCS
71
+ resolve_ignore_configured_endpoint_urls(cfg)
72
+ end
73
+
53
74
  option(:endpoint, doc_type: String, docstring: <<-DOCS) do |cfg|
54
75
  The client endpoint is normally constructed from the `:region`
55
76
  option. You should only configure an `:endpoint` when connecting
56
77
  to test or custom endpoints. This should be a valid HTTP(S) URI.
57
- DOCS
58
- endpoint_prefix = cfg.api.metadata['endpointPrefix']
59
- if cfg.region && endpoint_prefix
60
- if cfg.respond_to?(:sts_regional_endpoints)
61
- sts_regional = cfg.sts_regional_endpoints
62
- end
78
+ DOCS
79
+ resolve_endpoint(cfg)
80
+ end
63
81
 
64
- # check region is a valid RFC host label
65
- unless Seahorse::Util.host_label?(cfg.region)
66
- raise Errors::InvalidRegionError
67
- end
82
+ def after_initialize(client)
83
+ region = client.config.region
84
+ raise Errors::MissingRegionError if region.nil? || region == ''
68
85
 
69
- region = cfg.region
70
- new_region = region.gsub('fips-', '').gsub('-fips', '')
71
- if region != new_region
72
- warn("Legacy region #{region} was transformed to #{new_region}."\
73
- '`use_fips_endpoint` config was set to true.')
74
- cfg.override_config(:use_fips_endpoint, true)
75
- cfg.override_config(:region, new_region)
76
- end
86
+ # resolve a default endpoint to preserve legacy behavior
87
+ initialize_default_endpoint(client) if client.config.endpoint.nil?
77
88
 
78
- Aws::Partitions::EndpointProvider.resolve(
79
- cfg.region,
80
- endpoint_prefix,
81
- sts_regional,
82
- {
83
- dualstack: cfg.use_dualstack_endpoint,
84
- fips: cfg.use_fips_endpoint
85
- }
86
- )
87
- end
89
+ region_set = client.config.sigv4a_signing_region_set
90
+ return if region_set.nil?
91
+ raise Errors::InvalidRegionSetError unless region_set.is_a?(Array)
92
+
93
+ region_set = region_set.compact.reject(&:empty?)
94
+ raise Errors::InvalidRegionSetError if region_set.empty?
95
+
96
+ client.config.sigv4a_signing_region_set = region_set
88
97
  end
89
98
 
90
- def after_initialize(client)
91
- if client.config.region.nil? || client.config.region == ''
92
- raise Errors::MissingRegionError
99
+ private
100
+
101
+ def initialize_default_endpoint(client)
102
+ client_module = Object.const_get(client.class.name.rpartition('::').first)
103
+ param_class = client_module.const_get(:EndpointParameters)
104
+ endpoint_provider = client.config.endpoint_provider
105
+ params = param_class.create(client.config)
106
+ endpoint = endpoint_provider.resolve_endpoint(params)
107
+ client.config.endpoint = endpoint.url
108
+ rescue ArgumentError, NameError
109
+ # fallback to legacy
110
+ client.config.endpoint = resolve_legacy_endpoint(client.config)
111
+ end
112
+
113
+ # set a default endpoint in config using legacy (endpoints.json) resolver
114
+ def resolve_legacy_endpoint(cfg)
115
+ endpoint_prefix = cfg.api.metadata['endpointPrefix']
116
+ if cfg.respond_to?(:sts_regional_endpoints)
117
+ sts_regional = cfg.sts_regional_endpoints
93
118
  end
119
+
120
+ endpoint = Aws::Partitions::EndpointProvider.resolve(
121
+ cfg.region,
122
+ endpoint_prefix,
123
+ sts_regional,
124
+ {
125
+ dualstack: cfg.use_dualstack_endpoint,
126
+ fips: cfg.use_fips_endpoint
127
+ }
128
+ )
129
+ URI(endpoint)
94
130
  end
95
131
 
96
132
  class << self
@@ -104,6 +140,12 @@ to test or custom endpoints. This should be a valid HTTP(S) URI.
104
140
  env_region || cfg_region
105
141
  end
106
142
 
143
+ def resolve_sigv4a_signing_region_set(cfg)
144
+ value = ENV['AWS_SIGV4A_SIGNING_REGION_SET']
145
+ value ||= Aws.shared_config.sigv4a_signing_region_set(profile: cfg.profile)
146
+ value.split(',') if value
147
+ end
148
+
107
149
  def resolve_use_dualstack_endpoint(cfg)
108
150
  value = ENV['AWS_USE_DUALSTACK_ENDPOINT']
109
151
  value ||= Aws.shared_config.use_dualstack_endpoint(
@@ -117,6 +159,89 @@ to test or custom endpoints. This should be a valid HTTP(S) URI.
117
159
  value ||= Aws.shared_config.use_fips_endpoint(profile: cfg.profile)
118
160
  Aws::Util.str_2_bool(value) || false
119
161
  end
162
+
163
+ def resolve_ignore_configured_endpoint_urls(cfg)
164
+ value = ENV['AWS_IGNORE_CONFIGURED_ENDPOINT_URLS']
165
+ value ||= Aws.shared_config.ignore_configured_endpoint_urls(profile: cfg.profile)
166
+ Aws::Util.str_2_bool(value&.downcase) || false
167
+ end
168
+
169
+ # NOTE: with Endpoints 2.0, some of this logic is deprecated
170
+ # but because new old service gems may depend on new core versions
171
+ # we must preserve that behavior.
172
+ # Additional behavior controls the setting of the custom SDK::Endpoint
173
+ # parameter.
174
+ # When the `regional_endpoint` config is set to true - this indicates to
175
+ # Endpoints2.0 that a custom endpoint has NOT been configured by the user.
176
+ def resolve_endpoint(cfg)
177
+ endpoint = resolve_custom_config_endpoint(cfg)
178
+ endpoint_prefix = cfg.api.metadata['endpointPrefix']
179
+
180
+ return endpoint unless endpoint.nil? && cfg.region && endpoint_prefix
181
+
182
+ validate_region!(cfg.region)
183
+ handle_legacy_pseudo_regions(cfg)
184
+
185
+ # set regional_endpoint flag - this indicates to Endpoints 2.0
186
+ # that a custom endpoint has NOT been configured by the user
187
+ cfg.override_config(:regional_endpoint, true)
188
+
189
+ # a default endpoint is resolved in after_initialize
190
+ nil
191
+ end
192
+
193
+ # get a custom configured endpoint from ENV or configuration
194
+ def resolve_custom_config_endpoint(cfg)
195
+ return if cfg.ignore_configured_endpoint_urls
196
+
197
+
198
+ env_service_endpoint(cfg) || env_global_endpoint(cfg) || shared_config_endpoint(cfg)
199
+ end
200
+
201
+ def env_service_endpoint(cfg)
202
+ service_id = cfg.api.metadata['serviceId'] || cfg.api.metadata['endpointPrefix']
203
+ env_service_id = service_id.gsub(" ", "_").upcase
204
+ return unless endpoint = ENV["AWS_ENDPOINT_URL_#{env_service_id}"]
205
+
206
+ cfg.logger&.debug(
207
+ "Endpoint configured from ENV['AWS_ENDPOINT_URL_#{env_service_id}']: #{endpoint}\n")
208
+ endpoint
209
+ end
210
+
211
+ def env_global_endpoint(cfg)
212
+ return unless endpoint = ENV['AWS_ENDPOINT_URL']
213
+
214
+ cfg.logger&.debug(
215
+ "Endpoint configured from ENV['AWS_ENDPOINT_URL']: #{endpoint}\n")
216
+ endpoint
217
+ end
218
+
219
+ def shared_config_endpoint(cfg)
220
+ service_id = cfg.api.metadata['serviceId'] || cfg.api.metadata['endpointPrefix']
221
+ return unless endpoint = Aws.shared_config.configured_endpoint(profile: cfg.profile, service_id: service_id)
222
+
223
+ cfg.logger&.debug(
224
+ "Endpoint configured from shared config(profile: #{cfg.profile}): #{endpoint}\n")
225
+ endpoint
226
+ end
227
+
228
+ # check region is a valid RFC host label
229
+ def validate_region!(region)
230
+ unless Seahorse::Util.host_label?(region)
231
+ raise Errors::InvalidRegionError
232
+ end
233
+ end
234
+
235
+ def handle_legacy_pseudo_regions(cfg)
236
+ region = cfg.region
237
+ new_region = region.gsub('fips-', '').gsub('-fips', '')
238
+ if region != new_region
239
+ warn("Legacy region #{region} was transformed to #{new_region}."\
240
+ '`use_fips_endpoint` config was set to true.')
241
+ cfg.override_config(:use_fips_endpoint, true)
242
+ cfg.override_config(:region, new_region)
243
+ end
244
+ end
120
245
  end
121
246
  end
122
247
  end
@@ -0,0 +1,226 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module Plugins
5
+ # @api private
6
+ class RequestCompression < Seahorse::Client::Plugin
7
+ DEFAULT_MIN_COMPRESSION_SIZE = 10_240
8
+ MIN_COMPRESSION_SIZE_LIMIT = 10_485_760
9
+ SUPPORTED_ENCODINGS = %w[gzip].freeze
10
+ CHUNK_SIZE = 1 * 1024 * 1024 # one MB
11
+
12
+ option(
13
+ :disable_request_compression,
14
+ default: false,
15
+ doc_type: 'Boolean',
16
+ docstring: <<-DOCS) do |cfg|
17
+ When set to 'true' the request body will not be compressed
18
+ for supported operations.
19
+ DOCS
20
+ resolve_disable_request_compression(cfg)
21
+ end
22
+
23
+ option(
24
+ :request_min_compression_size_bytes,
25
+ default: 10_240,
26
+ doc_type: 'Integer',
27
+ docstring: <<-DOCS) do |cfg|
28
+ The minimum size in bytes that triggers compression for request
29
+ bodies. The value must be non-negative integer value between 0
30
+ and 10485780 bytes inclusive.
31
+ DOCS
32
+ resolve_request_min_compression_size_bytes(cfg)
33
+ end
34
+
35
+ def after_initialize(client)
36
+ validate_disable_request_compression_input(client.config)
37
+ validate_request_min_compression_size_bytes_input(client.config)
38
+ end
39
+
40
+ def validate_disable_request_compression_input(cfg)
41
+ unless [true, false].include?(cfg.disable_request_compression)
42
+ raise ArgumentError,
43
+ 'Must provide either `true` or `false` for the '\
44
+ '`disable_request_compression` configuration option.'
45
+ end
46
+ end
47
+
48
+ def validate_request_min_compression_size_bytes_input(cfg)
49
+ value = Integer(cfg.request_min_compression_size_bytes)
50
+ unless value.between?(0, MIN_COMPRESSION_SIZE_LIMIT)
51
+ raise ArgumentError,
52
+ 'Must provide a non-negative integer value between '\
53
+ '`0` and `10485760` bytes inclusive for the '\
54
+ '`request_min_compression_size_bytes` configuration option.'
55
+ end
56
+ end
57
+
58
+ def add_handlers(handlers, _config)
59
+ # priority set to ensure compression happens BEFORE checksum
60
+ handlers.add(CompressionHandler, priority: 16, step: :build)
61
+ end
62
+
63
+ class << self
64
+ private
65
+
66
+ def resolve_disable_request_compression(cfg)
67
+ value = ENV['AWS_DISABLE_REQUEST_COMPRESSION'] ||
68
+ Aws.shared_config.disable_request_compression(profile: cfg.profile) ||
69
+ 'false'
70
+ Aws::Util.str_2_bool(value)
71
+ end
72
+
73
+ def resolve_request_min_compression_size_bytes(cfg)
74
+ value = ENV['AWS_REQUEST_MIN_COMPRESSION_SIZE_BYTES'] ||
75
+ Aws.shared_config.request_min_compression_size_bytes(profile: cfg.profile) ||
76
+ DEFAULT_MIN_COMPRESSION_SIZE.to_s
77
+ Integer(value)
78
+ end
79
+ end
80
+
81
+ # @api private
82
+ class CompressionHandler < Seahorse::Client::Handler
83
+ def call(context)
84
+ if should_compress?(context)
85
+ selected_encoding = request_encoding_selection(context)
86
+ if selected_encoding
87
+ if streaming?(context.operation.input)
88
+ process_streaming_compression(selected_encoding, context)
89
+ elsif context.http_request.body.size >= context.config.request_min_compression_size_bytes
90
+ process_compression(selected_encoding, context)
91
+ end
92
+ end
93
+ end
94
+ with_metric(selected_encoding) { @handler.call(context) }
95
+ end
96
+
97
+ private
98
+
99
+ def with_metric(encoding, &block)
100
+ case encoding
101
+ when 'gzip'
102
+ Aws::Plugins::UserAgent.metric('GZIP_REQUEST_COMPRESSION', &block)
103
+ else
104
+ block.call
105
+ end
106
+ end
107
+
108
+ def request_encoding_selection(context)
109
+ encoding_list = context.operation.request_compression['encodings']
110
+ encoding_list.find { |encoding| RequestCompression::SUPPORTED_ENCODINGS.include?(encoding) }
111
+ end
112
+
113
+ def update_content_encoding(encoding, context)
114
+ headers = context.http_request.headers
115
+ if headers['Content-Encoding']
116
+ headers['Content-Encoding'] += ", #{encoding}"
117
+ else
118
+ headers['Content-Encoding'] = encoding
119
+ end
120
+ end
121
+
122
+ def should_compress?(context)
123
+ context.operation.request_compression &&
124
+ !context.config.disable_request_compression
125
+ end
126
+
127
+ def streaming?(input)
128
+ if payload = input[:payload_member] # checking ref and shape
129
+ payload['streaming'] || payload.shape['streaming']
130
+ else
131
+ false
132
+ end
133
+ end
134
+
135
+ def process_compression(encoding, context)
136
+ case encoding
137
+ when 'gzip'
138
+ gzip_compress(context)
139
+ else
140
+ raise StandardError, "We currently do not support #{encoding} encoding"
141
+ end
142
+ update_content_encoding(encoding, context)
143
+ end
144
+
145
+ def gzip_compress(context)
146
+ compressed = StringIO.new
147
+ compressed.binmode
148
+ gzip_writer = Zlib::GzipWriter.new(compressed)
149
+ if context.http_request.body.respond_to?(:read)
150
+ update_in_chunks(gzip_writer, context.http_request.body)
151
+ else
152
+ gzip_writer.write(context.http_request.body)
153
+ end
154
+ gzip_writer.close
155
+ new_body = StringIO.new(compressed.string)
156
+ context.http_request.body = new_body
157
+ end
158
+
159
+ def update_in_chunks(compressor, io)
160
+ loop do
161
+ chunk = io.read(CHUNK_SIZE)
162
+ break unless chunk
163
+
164
+ compressor.write(chunk)
165
+ end
166
+ end
167
+
168
+ def process_streaming_compression(encoding, context)
169
+ case encoding
170
+ when 'gzip'
171
+ context.http_request.body = GzipIO.new(context.http_request.body)
172
+ else
173
+ raise StandardError, "We currently do not support #{encoding} encoding"
174
+ end
175
+ update_content_encoding(encoding, context)
176
+ end
177
+
178
+ # @api private
179
+ class GzipIO
180
+ def initialize(body)
181
+ @body = body
182
+ @buffer = ChunkBuffer.new
183
+ @gzip_writer = Zlib::GzipWriter.new(@buffer)
184
+ end
185
+
186
+ def read(length, buff = nil)
187
+ if @gzip_writer.closed?
188
+ # an empty string to signify an end as
189
+ # there will be nothing remaining to be read
190
+ StringIO.new('').read(length, buff)
191
+ return
192
+ end
193
+
194
+ chunk = @body.read(length)
195
+ if !chunk || chunk.empty?
196
+ # closing the writer will write one last chunk
197
+ # with a trailer (to be read from the @buffer)
198
+ @gzip_writer.close
199
+ else
200
+ # flush happens first to ensure that header fields
201
+ # are being sent over since write will override
202
+ @gzip_writer.flush
203
+ @gzip_writer.write(chunk)
204
+ end
205
+
206
+ StringIO.new(@buffer.last_chunk).read(length, buff)
207
+ end
208
+ end
209
+
210
+ # @api private
211
+ class ChunkBuffer
212
+ def initialize
213
+ @last_chunk = nil
214
+ end
215
+
216
+ attr_reader :last_chunk
217
+
218
+ def write(data)
219
+ @last_chunk = data
220
+ end
221
+ end
222
+ end
223
+
224
+ end
225
+ end
226
+ end
@@ -73,6 +73,7 @@ is only used in the `legacy` retry mode.
73
73
  :retry_jitter,
74
74
  default: :none,
75
75
  doc_type: Symbol,
76
+ rbs_type: '(:none | :equal | :full | ^(Integer) -> Integer)',
76
77
  docstring: <<-DOCS)
77
78
  A delay randomiser function used by the default backoff function.
78
79
  Some predefined functions can be referenced by name - :none, :equal, :full,
@@ -97,6 +98,7 @@ This option is only used in the `legacy` retry mode.
97
98
  :retry_mode,
98
99
  default: 'legacy',
99
100
  doc_type: String,
101
+ rbs_type: '("legacy" | "standard" | "adaptive")',
100
102
  docstring: <<-DOCS) do |cfg|
101
103
  Specifies which retry algorithm to use. Values are:
102
104
 
@@ -111,7 +113,6 @@ Specifies which retry algorithm to use. Values are:
111
113
  functionality of `standard` mode along with automatic client side
112
114
  throttling. This is a provisional mode that may change behavior
113
115
  in the future.
114
-
115
116
  DOCS
116
117
  resolve_retry_mode(cfg)
117
118
  end
@@ -233,7 +234,7 @@ a clock skew correction and retry requests with skewed client clocks.
233
234
 
234
235
  get_send_token(config)
235
236
  add_retry_headers(context)
236
- response = @handler.call(context)
237
+ response = with_metric(config.retry_mode) { @handler.call(context) }
237
238
  error_inspector = Retries::ErrorInspector.new(
238
239
  response.error, response.context.http_response.status_code
239
240
  )
@@ -270,6 +271,10 @@ a clock skew correction and retry requests with skewed client clocks.
270
271
 
271
272
  private
272
273
 
274
+ def with_metric(retry_mode, &block)
275
+ Aws::Plugins::UserAgent.metric("RETRY_MODE_#{retry_mode.upcase}", &block)
276
+ end
277
+
273
278
  def get_send_token(config)
274
279
  # either fail fast or block until a token becomes available
275
280
  # must be configurable
@@ -357,7 +362,7 @@ a clock skew correction and retry requests with skewed client clocks.
357
362
  class LegacyHandler < Seahorse::Client::Handler
358
363
 
359
364
  def call(context)
360
- response = @handler.call(context)
365
+ response = with_metric { @handler.call(context) }
361
366
  if response.error
362
367
  error_inspector = Retries::ErrorInspector.new(
363
368
  response.error, response.context.http_response.status_code
@@ -376,6 +381,10 @@ a clock skew correction and retry requests with skewed client clocks.
376
381
 
377
382
  private
378
383
 
384
+ def with_metric(&block)
385
+ Aws::Plugins::UserAgent.metric('RETRY_MODE_LEGACY', &block)
386
+ end
387
+
379
388
  def retry_if_possible(response, error_inspector)
380
389
  context = response.context
381
390
  if should_retry?(context, error_inspector)