aws-sdk-core 3.165.0 → 3.201.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (164) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +462 -0
  3. data/VERSION +1 -1
  4. data/lib/aws-defaults/default_configuration.rb +4 -4
  5. data/lib/aws-sdk-core/binary/decode_handler.rb +3 -9
  6. data/lib/aws-sdk-core/binary/encode_handler.rb +1 -1
  7. data/lib/aws-sdk-core/binary/event_builder.rb +34 -37
  8. data/lib/aws-sdk-core/binary/event_stream_decoder.rb +1 -0
  9. data/lib/aws-sdk-core/binary/event_stream_encoder.rb +4 -3
  10. data/lib/aws-sdk-core/cbor/cbor_engine.rb +19 -0
  11. data/lib/aws-sdk-core/cbor/decoder.rb +310 -0
  12. data/lib/aws-sdk-core/cbor/encoder.rb +243 -0
  13. data/lib/aws-sdk-core/cbor.rb +106 -0
  14. data/lib/aws-sdk-core/client_stubs.rb +18 -14
  15. data/lib/aws-sdk-core/credential_provider.rb +4 -1
  16. data/lib/aws-sdk-core/credential_provider_chain.rb +8 -5
  17. data/lib/aws-sdk-core/ec2_metadata.rb +1 -1
  18. data/lib/aws-sdk-core/ecs_credentials.rb +178 -53
  19. data/lib/aws-sdk-core/endpoints/condition.rb +5 -0
  20. data/lib/aws-sdk-core/endpoints/endpoint_rule.rb +5 -1
  21. data/lib/aws-sdk-core/endpoints/error_rule.rb +5 -0
  22. data/lib/aws-sdk-core/endpoints/function.rb +5 -0
  23. data/lib/aws-sdk-core/endpoints/matchers.rb +18 -10
  24. data/lib/aws-sdk-core/endpoints/reference.rb +5 -0
  25. data/lib/aws-sdk-core/endpoints/rule.rb +5 -0
  26. data/lib/aws-sdk-core/endpoints/rule_set.rb +5 -0
  27. data/lib/aws-sdk-core/endpoints/rules_provider.rb +5 -0
  28. data/lib/aws-sdk-core/endpoints/templater.rb +6 -0
  29. data/lib/aws-sdk-core/endpoints/tree_rule.rb +5 -0
  30. data/lib/aws-sdk-core/endpoints/url.rb +1 -0
  31. data/lib/aws-sdk-core/endpoints.rb +69 -19
  32. data/lib/aws-sdk-core/error_handler.rb +41 -0
  33. data/lib/aws-sdk-core/errors.rb +12 -3
  34. data/lib/aws-sdk-core/event_emitter.rb +0 -16
  35. data/lib/aws-sdk-core/ini_parser.rb +7 -0
  36. data/lib/aws-sdk-core/instance_profile_credentials.rb +55 -32
  37. data/lib/aws-sdk-core/json/builder.rb +8 -1
  38. data/lib/aws-sdk-core/json/error_handler.rb +29 -14
  39. data/lib/aws-sdk-core/json/handler.rb +12 -6
  40. data/lib/aws-sdk-core/json/json_engine.rb +3 -1
  41. data/lib/aws-sdk-core/json/oj_engine.rb +7 -1
  42. data/lib/aws-sdk-core/json/parser.rb +33 -3
  43. data/lib/aws-sdk-core/json.rb +43 -14
  44. data/lib/aws-sdk-core/log/formatter.rb +6 -0
  45. data/lib/aws-sdk-core/lru_cache.rb +75 -0
  46. data/lib/aws-sdk-core/pageable_response.rb +3 -1
  47. data/lib/aws-sdk-core/param_validator.rb +9 -4
  48. data/lib/aws-sdk-core/plugins/bearer_authorization.rb +2 -0
  49. data/lib/aws-sdk-core/plugins/checksum_algorithm.rb +7 -4
  50. data/lib/aws-sdk-core/plugins/client_metrics_plugin.rb +1 -0
  51. data/lib/aws-sdk-core/plugins/client_metrics_send_plugin.rb +14 -2
  52. data/lib/aws-sdk-core/plugins/credentials_configuration.rb +2 -0
  53. data/lib/aws-sdk-core/plugins/global_configuration.rb +8 -9
  54. data/lib/aws-sdk-core/plugins/http_checksum.rb +2 -1
  55. data/lib/aws-sdk-core/plugins/invocation_id.rb +1 -11
  56. data/lib/aws-sdk-core/plugins/logging.rb +2 -0
  57. data/lib/aws-sdk-core/plugins/protocols/api_gateway.rb +3 -1
  58. data/lib/aws-sdk-core/plugins/protocols/ec2.rb +2 -24
  59. data/lib/aws-sdk-core/plugins/protocols/json_rpc.rb +6 -8
  60. data/lib/aws-sdk-core/plugins/protocols/query.rb +4 -2
  61. data/lib/aws-sdk-core/plugins/protocols/rest_json.rb +3 -15
  62. data/lib/aws-sdk-core/plugins/protocols/rest_xml.rb +3 -0
  63. data/lib/aws-sdk-core/plugins/protocols/rpc_v2.rb +17 -0
  64. data/lib/aws-sdk-core/plugins/regional_endpoint.rb +140 -35
  65. data/lib/aws-sdk-core/plugins/request_compression.rb +226 -0
  66. data/lib/aws-sdk-core/plugins/retries/error_inspector.rb +2 -1
  67. data/lib/aws-sdk-core/plugins/retry_errors.rb +12 -3
  68. data/lib/aws-sdk-core/plugins/sign.rb +43 -19
  69. data/lib/aws-sdk-core/plugins/signature_v2.rb +2 -1
  70. data/lib/aws-sdk-core/plugins/signature_v4.rb +2 -1
  71. data/lib/aws-sdk-core/plugins/stub_responses.rb +1 -0
  72. data/lib/aws-sdk-core/plugins/transfer_encoding.rb +16 -9
  73. data/lib/aws-sdk-core/plugins/user_agent.rb +152 -14
  74. data/lib/aws-sdk-core/process_credentials.rb +45 -27
  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 +12 -12
  81. data/lib/aws-sdk-core/rest/content_type_handler.rb +60 -0
  82. data/lib/aws-sdk-core/rest/handler.rb +3 -4
  83. data/lib/aws-sdk-core/rest/request/body.rb +32 -5
  84. data/lib/aws-sdk-core/rest/request/endpoint.rb +24 -4
  85. data/lib/aws-sdk-core/rest/request/headers.rb +15 -7
  86. data/lib/aws-sdk-core/rest/request/querystring_builder.rb +62 -36
  87. data/lib/aws-sdk-core/rest/response/body.rb +15 -1
  88. data/lib/aws-sdk-core/rest/response/header_list_parser.rb +79 -0
  89. data/lib/aws-sdk-core/rest/response/headers.rb +8 -3
  90. data/lib/aws-sdk-core/rest.rb +1 -0
  91. data/lib/aws-sdk-core/rpc_v2/builder.rb +62 -0
  92. data/lib/aws-sdk-core/rpc_v2/content_type_handler.rb +45 -0
  93. data/lib/aws-sdk-core/rpc_v2/error_handler.rb +84 -0
  94. data/lib/aws-sdk-core/rpc_v2/handler.rb +74 -0
  95. data/lib/aws-sdk-core/rpc_v2/parser.rb +90 -0
  96. data/lib/aws-sdk-core/rpc_v2.rb +6 -0
  97. data/lib/aws-sdk-core/shared_config.rb +77 -18
  98. data/lib/aws-sdk-core/sso_credentials.rb +80 -45
  99. data/lib/aws-sdk-core/sso_token_provider.rb +3 -2
  100. data/lib/aws-sdk-core/stubbing/protocols/rpc_v2.rb +41 -0
  101. data/lib/aws-sdk-core/stubbing/stub_data.rb +11 -0
  102. data/lib/aws-sdk-core/util.rb +39 -0
  103. data/lib/aws-sdk-core/waiters/poller.rb +4 -2
  104. data/lib/aws-sdk-core/xml/builder.rb +17 -9
  105. data/lib/aws-sdk-core/xml/error_handler.rb +32 -42
  106. data/lib/aws-sdk-core/xml/parser/frame.rb +4 -20
  107. data/lib/aws-sdk-core/xml/parser/{engines/oga.rb → oga_engine.rb} +2 -0
  108. data/lib/aws-sdk-core/xml/parser/stack.rb +2 -0
  109. data/lib/aws-sdk-core/xml/parser.rb +2 -6
  110. data/lib/aws-sdk-core.rb +8 -2
  111. data/lib/aws-sdk-sso/client.rb +103 -46
  112. data/lib/aws-sdk-sso/client_api.rb +6 -0
  113. data/lib/aws-sdk-sso/endpoint_provider.rb +41 -96
  114. data/lib/aws-sdk-sso/endpoints.rb +1 -0
  115. data/lib/aws-sdk-sso/plugins/endpoints.rb +4 -2
  116. data/lib/aws-sdk-sso/types.rb +0 -35
  117. data/lib/aws-sdk-sso.rb +1 -1
  118. data/lib/aws-sdk-ssooidc/client.rb +488 -74
  119. data/lib/aws-sdk-ssooidc/client_api.rb +82 -1
  120. data/lib/aws-sdk-ssooidc/endpoint_provider.rb +41 -95
  121. data/lib/aws-sdk-ssooidc/endpoints.rb +15 -0
  122. data/lib/aws-sdk-ssooidc/errors.rb +52 -0
  123. data/lib/aws-sdk-ssooidc/plugins/endpoints.rb +6 -2
  124. data/lib/aws-sdk-ssooidc/types.rb +372 -83
  125. data/lib/aws-sdk-ssooidc.rb +1 -1
  126. data/lib/aws-sdk-sts/client.rb +361 -288
  127. data/lib/aws-sdk-sts/client_api.rb +24 -11
  128. data/lib/aws-sdk-sts/endpoint_provider.rb +96 -213
  129. data/lib/aws-sdk-sts/endpoints.rb +1 -0
  130. data/lib/aws-sdk-sts/plugins/endpoints.rb +4 -2
  131. data/lib/aws-sdk-sts/presigner.rb +1 -1
  132. data/lib/aws-sdk-sts/types.rb +128 -197
  133. data/lib/aws-sdk-sts.rb +1 -1
  134. data/lib/seahorse/client/async_base.rb +1 -1
  135. data/lib/seahorse/client/async_response.rb +19 -0
  136. data/lib/seahorse/client/base.rb +18 -7
  137. data/lib/seahorse/client/configuration.rb +0 -4
  138. data/lib/seahorse/client/h2/connection.rb +12 -11
  139. data/lib/seahorse/client/h2/handler.rb +1 -0
  140. data/lib/seahorse/client/handler.rb +1 -1
  141. data/lib/seahorse/client/net_http/connection_pool.rb +3 -9
  142. data/lib/seahorse/client/net_http/patches.rb +1 -4
  143. data/lib/seahorse/client/plugin.rb +9 -0
  144. data/lib/seahorse/client/plugins/endpoint.rb +0 -1
  145. data/lib/seahorse/client/plugins/h2.rb +3 -3
  146. data/lib/seahorse/client/plugins/net_http.rb +48 -16
  147. data/lib/seahorse/client/plugins/request_callback.rb +31 -0
  148. data/lib/seahorse/client/response.rb +6 -0
  149. data/lib/seahorse/model/operation.rb +3 -0
  150. data/lib/seahorse/model/shapes.rb +2 -2
  151. data/sig/aws-sdk-core/client_stubs.rbs +10 -0
  152. data/sig/aws-sdk-core/errors.rbs +22 -0
  153. data/sig/aws-sdk-core/resources/collection.rbs +21 -0
  154. data/sig/aws-sdk-core/structure.rbs +4 -0
  155. data/sig/aws-sdk-core/waiters/errors.rbs +20 -0
  156. data/sig/aws-sdk-core.rbs +7 -0
  157. data/sig/seahorse/client/base.rbs +25 -0
  158. data/sig/seahorse/client/handler_builder.rbs +16 -0
  159. data/sig/seahorse/client/response.rbs +61 -0
  160. metadata +44 -17
  161. /data/lib/aws-sdk-core/xml/parser/{engines/libxml.rb → libxml_engine.rb} +0 -0
  162. /data/lib/aws-sdk-core/xml/parser/{engines/nokogiri.rb → nokogiri_engine.rb} +0 -0
  163. /data/lib/aws-sdk-core/xml/parser/{engines/ox.rb → ox_engine.rb} +0 -0
  164. /data/lib/aws-sdk-core/xml/parser/{engines/rexml.rb → rexml_engine.rb} +0 -0
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module Plugins
5
+ module Protocols
6
+ class RpcV2 < Seahorse::Client::Plugin
7
+
8
+ option(:protocol, 'smithy-rpc-v2-cbor')
9
+
10
+ handler(Aws::RpcV2::Handler)
11
+ handler(Aws::RpcV2::ContentTypeHandler, priority: 30)
12
+ handler(Aws::RpcV2::ErrorHandler, step: :sign)
13
+
14
+ end
15
+ end
16
+ end
17
+ end
@@ -24,6 +24,21 @@ a default `:region` is searched for in the following locations:
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|
@@ -47,50 +62,35 @@ 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
78
  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
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
+ region_set = client.config.sigv4a_signing_region_set
87
+ return if region_set.nil?
88
+ raise Errors::InvalidRegionSetError unless region_set.is_a?(Array)
77
89
 
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
88
- end
90
+ region_set = region_set.compact.reject(&:empty?)
91
+ raise Errors::InvalidRegionSetError if region_set.empty?
89
92
 
90
- def after_initialize(client)
91
- if client.config.region.nil? || client.config.region == ''
92
- raise Errors::MissingRegionError
93
- end
93
+ client.config.sigv4a_signing_region_set = region_set
94
94
  end
95
95
 
96
96
  class << self
@@ -104,6 +104,12 @@ to test or custom endpoints. This should be a valid HTTP(S) URI.
104
104
  env_region || cfg_region
105
105
  end
106
106
 
107
+ def resolve_sigv4a_signing_region_set(cfg)
108
+ value = ENV['AWS_SIGV4A_SIGNING_REGION_SET']
109
+ value ||= Aws.shared_config.sigv4a_signing_region_set(profile: cfg.profile)
110
+ value.split(',') if value
111
+ end
112
+
107
113
  def resolve_use_dualstack_endpoint(cfg)
108
114
  value = ENV['AWS_USE_DUALSTACK_ENDPOINT']
109
115
  value ||= Aws.shared_config.use_dualstack_endpoint(
@@ -117,6 +123,105 @@ to test or custom endpoints. This should be a valid HTTP(S) URI.
117
123
  value ||= Aws.shared_config.use_fips_endpoint(profile: cfg.profile)
118
124
  Aws::Util.str_2_bool(value) || false
119
125
  end
126
+
127
+ def resolve_ignore_configured_endpoint_urls(cfg)
128
+ value = ENV['AWS_IGNORE_CONFIGURED_ENDPOINT_URLS']
129
+ value ||= Aws.shared_config.ignore_configured_endpoint_urls(profile: cfg.profile)
130
+ Aws::Util.str_2_bool(value&.downcase) || false
131
+ end
132
+
133
+ # NOTE: with Endpoints 2.0, some of this logic is deprecated
134
+ # but because new old service gems may depend on new core versions
135
+ # we must preserve that behavior.
136
+ # Additional behavior controls the setting of the custom SDK::Endpoint
137
+ # parameter.
138
+ # When the `regional_endpoint` config is set to true - this indicates to
139
+ # Endpoints2.0 that a custom endpoint has NOT been configured by the user.
140
+ def resolve_endpoint(cfg)
141
+ endpoint = resolve_custom_config_endpoint(cfg)
142
+ endpoint_prefix = cfg.api.metadata['endpointPrefix']
143
+
144
+ return endpoint unless endpoint.nil? && cfg.region && endpoint_prefix
145
+
146
+ validate_region!(cfg.region)
147
+ handle_legacy_pseudo_regions(cfg)
148
+
149
+ # set regional_endpoint flag - this indicates to Endpoints 2.0
150
+ # that a custom endpoint has NOT been configured by the user
151
+ cfg.override_config(:regional_endpoint, true)
152
+
153
+ resolve_legacy_endpoint(cfg)
154
+ end
155
+
156
+ # get a custom configured endpoint from ENV or configuration
157
+ def resolve_custom_config_endpoint(cfg)
158
+ return if cfg.ignore_configured_endpoint_urls
159
+
160
+
161
+ env_service_endpoint(cfg) || env_global_endpoint(cfg) || shared_config_endpoint(cfg)
162
+ end
163
+
164
+ def env_service_endpoint(cfg)
165
+ service_id = cfg.api.metadata['serviceId'] || cfg.api.metadata['endpointPrefix']
166
+ env_service_id = service_id.gsub(" ", "_").upcase
167
+ return unless endpoint = ENV["AWS_ENDPOINT_URL_#{env_service_id}"]
168
+
169
+ cfg.logger&.debug(
170
+ "Endpoint configured from ENV['AWS_ENDPOINT_URL_#{env_service_id}']: #{endpoint}\n")
171
+ endpoint
172
+ end
173
+
174
+ def env_global_endpoint(cfg)
175
+ return unless endpoint = ENV['AWS_ENDPOINT_URL']
176
+
177
+ cfg.logger&.debug(
178
+ "Endpoint configured from ENV['AWS_ENDPOINT_URL']: #{endpoint}\n")
179
+ endpoint
180
+ end
181
+
182
+ def shared_config_endpoint(cfg)
183
+ service_id = cfg.api.metadata['serviceId'] || cfg.api.metadata['endpointPrefix']
184
+ return unless endpoint = Aws.shared_config.configured_endpoint(profile: cfg.profile, service_id: service_id)
185
+
186
+ cfg.logger&.debug(
187
+ "Endpoint configured from shared config(profile: #{cfg.profile}): #{endpoint}\n")
188
+ endpoint
189
+ end
190
+
191
+ # check region is a valid RFC host label
192
+ def validate_region!(region)
193
+ unless Seahorse::Util.host_label?(region)
194
+ raise Errors::InvalidRegionError
195
+ end
196
+ end
197
+
198
+ def handle_legacy_pseudo_regions(cfg)
199
+ region = cfg.region
200
+ new_region = region.gsub('fips-', '').gsub('-fips', '')
201
+ if region != new_region
202
+ warn("Legacy region #{region} was transformed to #{new_region}."\
203
+ '`use_fips_endpoint` config was set to true.')
204
+ cfg.override_config(:use_fips_endpoint, true)
205
+ cfg.override_config(:region, new_region)
206
+ end
207
+ end
208
+ # set a default endpoint in config using legacy (endpoints.json) resolver
209
+ def resolve_legacy_endpoint(cfg)
210
+ endpoint_prefix = cfg.api.metadata['endpointPrefix']
211
+ if cfg.respond_to?(:sts_regional_endpoints)
212
+ sts_regional = cfg.sts_regional_endpoints
213
+ end
214
+
215
+ Aws::Partitions::EndpointProvider.resolve(
216
+ cfg.region,
217
+ endpoint_prefix,
218
+ sts_regional,
219
+ {
220
+ dualstack: cfg.use_dualstack_endpoint,
221
+ fips: cfg.use_fips_endpoint
222
+ }
223
+ )
224
+ end
120
225
  end
121
226
  end
122
227
  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
@@ -39,7 +39,8 @@ module Aws
39
39
 
40
40
  CHECKSUM_ERRORS = Set.new(
41
41
  [
42
- 'CRC32CheckFailed' # dynamodb
42
+ 'CRC32CheckFailed', # dynamodb
43
+ 'BadDigest' # s3
43
44
  ]
44
45
  )
45
46
 
@@ -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)
@@ -13,7 +13,7 @@ module Aws
13
13
  option(:sigv4_region)
14
14
  option(:unsigned_operations, default: [])
15
15
 
16
- supported_auth_types = %w[sigv4 bearer none]
16
+ supported_auth_types = %w[sigv4 bearer sigv4-s3express none]
17
17
  supported_auth_types += ['sigv4a'] if Aws::Sigv4::Signer.use_crt?
18
18
  SUPPORTED_AUTH_TYPES = supported_auth_types.freeze
19
19
 
@@ -24,10 +24,14 @@ module Aws
24
24
 
25
25
  # @api private
26
26
  # Return a signer with the `sign(context)` method
27
- def self.signer_for(auth_scheme, config, region_override = nil)
27
+ def self.signer_for(auth_scheme, config, sigv4_region_override = nil, sigv4_credentials_override = nil)
28
28
  case auth_scheme['name']
29
- when 'sigv4', 'sigv4a'
30
- SignatureV4.new(auth_scheme, config, region_override)
29
+ when 'sigv4', 'sigv4a', 'sigv4-s3express'
30
+ sigv4_overrides = {
31
+ region: sigv4_region_override,
32
+ credentials: sigv4_credentials_override
33
+ }
34
+ SignatureV4.new(auth_scheme, config, sigv4_overrides)
31
35
  when 'bearer'
32
36
  Bearer.new
33
37
  else
@@ -37,15 +41,26 @@ module Aws
37
41
 
38
42
  class Handler < Seahorse::Client::Handler
39
43
  def call(context)
40
- signer = Sign.signer_for(
41
- context[:auth_scheme],
42
- context.config,
43
- context[:sigv4_region]
44
- )
45
-
46
- signer.sign(context)
44
+ # Skip signing if using sigv2 signing from s3_signer in S3
45
+ unless v2_signing?(context.config)
46
+ signer = Sign.signer_for(
47
+ context[:auth_scheme],
48
+ context.config,
49
+ context[:sigv4_region],
50
+ context[:sigv4_credentials]
51
+ )
52
+ signer.sign(context)
53
+ end
47
54
  @handler.call(context)
48
55
  end
56
+
57
+ private
58
+
59
+ def v2_signing?(config)
60
+ # 's3' is legacy signing, 'v4' is default
61
+ config.respond_to?(:signature_version) &&
62
+ config.signature_version == 's3'
63
+ end
49
64
  end
50
65
 
51
66
  # @api private
@@ -78,26 +93,27 @@ module Aws
78
93
 
79
94
  # @api private
80
95
  class SignatureV4
81
- def initialize(auth_scheme, config, region_override = nil)
96
+ def initialize(auth_scheme, config, sigv4_overrides = {})
82
97
  scheme_name = auth_scheme['name']
83
98
 
84
- unless %w[sigv4 sigv4a].include?(scheme_name)
99
+ unless %w[sigv4 sigv4a sigv4-s3express].include?(scheme_name)
85
100
  raise ArgumentError,
86
- "Expected sigv4 or sigv4a auth scheme, got #{scheme_name}"
101
+ "Expected sigv4, sigv4a, or sigv4-s3express auth scheme, got #{scheme_name}"
87
102
  end
88
103
 
89
104
  region = if scheme_name == 'sigv4a'
90
- auth_scheme['signingRegionSet'].first
105
+ auth_scheme['signingRegionSet'].join(',')
91
106
  else
92
107
  auth_scheme['signingRegion']
93
108
  end
94
109
  begin
95
110
  @signer = Aws::Sigv4::Signer.new(
96
111
  service: config.sigv4_name || auth_scheme['signingName'],
97
- region: region_override || config.sigv4_region || region,
98
- credentials_provider: config.credentials,
112
+ region: sigv4_overrides[:region] || config.sigv4_region || region,
113
+ credentials_provider: sigv4_overrides[:credentials] || config.credentials,
99
114
  signing_algorithm: scheme_name.to_sym,
100
115
  uri_escape_path: !!!auth_scheme['disableDoubleEncoding'],
116
+ normalize_path: !!!auth_scheme['disableNormalizePath'],
101
117
  unsigned_headers: %w[content-length user-agent x-amzn-trace-id]
102
118
  )
103
119
  rescue Aws::Sigv4::Errors::MissingCredentialsError
@@ -143,12 +159,20 @@ module Aws
143
159
  private
144
160
 
145
161
  def apply_authtype(context, req)
146
- if context.operation['authtype'].eql?('v4-unsigned-body') &&
147
- req.endpoint.scheme.eql?('https')
162
+ # only used for event streaming at input
163
+ if context[:input_event_emitter]
164
+ req.headers['X-Amz-Content-Sha256'] = 'STREAMING-AWS4-HMAC-SHA256-EVENTS'
165
+ elsif unsigned_payload?(context, req)
148
166
  req.headers['X-Amz-Content-Sha256'] ||= 'UNSIGNED-PAYLOAD'
149
167
  end
150
168
  end
151
169
 
170
+ def unsigned_payload?(context, req)
171
+ (context.operation['unsignedPayload'] ||
172
+ context.operation['authtype'] == 'v4-unsigned-body') &&
173
+ req.endpoint.scheme == 'https'
174
+ end
175
+
152
176
  def reset_signature(req)
153
177
  # in case this request is being re-signed
154
178
  req.headers.delete('Authorization')
@@ -3,7 +3,8 @@
3
3
  module Aws
4
4
  module Plugins
5
5
  # @api private
6
- # Necessary to keep after Endpoints 2.0
6
+ # Deprecated - does not look at new traits like `auth` and `unsignedPayload`
7
+ # Necessary to exist after endpoints 2.0 for old service clients + new core
7
8
  class SignatureV2 < Seahorse::Client::Plugin
8
9
 
9
10
  option(:v2_signer) do |cfg|
@@ -5,7 +5,8 @@ require 'aws-sigv4'
5
5
  module Aws
6
6
  module Plugins
7
7
  # @api private
8
- # Necessary to exist after endpoints 2.0
8
+ # Deprecated - does not look at new traits like `auth` and `unsignedPayload`
9
+ # Necessary to exist after endpoints 2.0 for old service clients + new core
9
10
  class SignatureV4 < Seahorse::Client::Plugin
10
11
 
11
12
  V4_AUTH = %w[v4 v4-unsigned-payload v4-unsigned-body]
@@ -8,6 +8,7 @@ module Aws
8
8
  option(:stub_responses,
9
9
  default: false,
10
10
  doc_type: 'Boolean',
11
+ rbs_type: 'untyped',
11
12
  docstring: <<-DOCS)
12
13
  Causes the client to return stubbed responses. By default
13
14
  fake responses are generated and returned. You can specify