aws-sdk-core 3.46.2 → 3.126.2
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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +1258 -0
- data/LICENSE.txt +202 -0
- data/VERSION +1 -1
- data/lib/aws-defaults/default_configuration.rb +153 -0
- data/lib/aws-defaults/defaults_mode_config_resolver.rb +107 -0
- data/lib/aws-defaults.rb +3 -0
- data/lib/aws-sdk-core/arn.rb +92 -0
- data/lib/aws-sdk-core/arn_parser.rb +40 -0
- data/lib/aws-sdk-core/assume_role_credentials.rb +20 -0
- data/lib/aws-sdk-core/assume_role_web_identity_credentials.rb +109 -0
- data/lib/aws-sdk-core/async_client_stubs.rb +82 -0
- data/lib/aws-sdk-core/binary/decode_handler.rb +11 -1
- data/lib/aws-sdk-core/binary/encode_handler.rb +34 -0
- data/lib/aws-sdk-core/binary/event_builder.rb +124 -0
- data/lib/aws-sdk-core/binary/event_parser.rb +50 -18
- data/lib/aws-sdk-core/binary/event_stream_decoder.rb +7 -2
- data/lib/aws-sdk-core/binary/event_stream_encoder.rb +55 -0
- data/lib/aws-sdk-core/binary.rb +5 -0
- data/lib/aws-sdk-core/client_side_monitoring/publisher.rb +11 -1
- data/lib/aws-sdk-core/client_side_monitoring/request_metrics.rb +2 -0
- data/lib/aws-sdk-core/client_stubs.rb +16 -13
- data/lib/aws-sdk-core/credential_provider.rb +1 -30
- data/lib/aws-sdk-core/credential_provider_chain.rb +102 -40
- data/lib/aws-sdk-core/credentials.rb +2 -0
- data/lib/aws-sdk-core/deprecations.rb +17 -11
- data/lib/aws-sdk-core/eager_loader.rb +2 -0
- data/lib/aws-sdk-core/ec2_metadata.rb +238 -0
- data/lib/aws-sdk-core/ecs_credentials.rb +18 -9
- data/lib/aws-sdk-core/endpoint_cache.rb +16 -11
- data/lib/aws-sdk-core/errors.rb +138 -15
- data/lib/aws-sdk-core/event_emitter.rb +44 -0
- data/lib/aws-sdk-core/ini_parser.rb +2 -0
- data/lib/aws-sdk-core/instance_profile_credentials.rb +179 -42
- data/lib/aws-sdk-core/json/builder.rb +2 -0
- data/lib/aws-sdk-core/json/error_handler.rb +21 -2
- data/lib/aws-sdk-core/json/handler.rb +21 -1
- data/lib/aws-sdk-core/json/json_engine.rb +12 -8
- data/lib/aws-sdk-core/json/oj_engine.rb +35 -6
- data/lib/aws-sdk-core/json/parser.rb +10 -0
- data/lib/aws-sdk-core/json.rb +11 -28
- data/lib/aws-sdk-core/log/formatter.rb +16 -4
- data/lib/aws-sdk-core/log/handler.rb +2 -0
- data/lib/aws-sdk-core/log/param_filter.rb +38 -13
- data/lib/aws-sdk-core/log/param_formatter.rb +2 -0
- data/lib/aws-sdk-core/pageable_response.rb +48 -24
- data/lib/aws-sdk-core/pager.rb +5 -0
- data/lib/aws-sdk-core/param_converter.rb +2 -0
- data/lib/aws-sdk-core/param_validator.rb +63 -7
- data/lib/aws-sdk-core/plugins/api_key.rb +5 -1
- data/lib/aws-sdk-core/plugins/apig_authorizer_token.rb +2 -0
- data/lib/aws-sdk-core/plugins/apig_credentials_configuration.rb +2 -0
- data/lib/aws-sdk-core/plugins/apig_user_agent.rb +2 -0
- data/lib/aws-sdk-core/plugins/client_metrics_plugin.rb +28 -1
- data/lib/aws-sdk-core/plugins/client_metrics_send_plugin.rb +2 -0
- data/lib/aws-sdk-core/plugins/credentials_configuration.rb +26 -7
- data/lib/aws-sdk-core/plugins/defaults_mode.rb +40 -0
- data/lib/aws-sdk-core/plugins/endpoint_discovery.rb +12 -4
- data/lib/aws-sdk-core/plugins/endpoint_pattern.rb +8 -6
- data/lib/aws-sdk-core/plugins/event_stream_configuration.rb +16 -0
- data/lib/aws-sdk-core/plugins/global_configuration.rb +2 -0
- data/lib/aws-sdk-core/plugins/helpful_socket_errors.rb +2 -0
- data/lib/aws-sdk-core/plugins/http_checksum.rb +57 -0
- data/lib/aws-sdk-core/plugins/idempotency_token.rb +2 -0
- data/lib/aws-sdk-core/plugins/invocation_id.rb +35 -0
- data/lib/aws-sdk-core/plugins/jsonvalue_converter.rb +2 -0
- data/lib/aws-sdk-core/plugins/logging.rb +2 -0
- data/lib/aws-sdk-core/plugins/param_converter.rb +2 -0
- data/lib/aws-sdk-core/plugins/param_validator.rb +2 -0
- data/lib/aws-sdk-core/plugins/protocols/api_gateway.rb +19 -0
- data/lib/aws-sdk-core/plugins/protocols/ec2.rb +2 -0
- data/lib/aws-sdk-core/plugins/protocols/json_rpc.rb +2 -0
- data/lib/aws-sdk-core/plugins/protocols/query.rb +2 -0
- data/lib/aws-sdk-core/plugins/protocols/rest_json.rb +18 -1
- data/lib/aws-sdk-core/plugins/protocols/rest_xml.rb +2 -0
- data/lib/aws-sdk-core/plugins/recursion_detection.rb +27 -0
- data/lib/aws-sdk-core/plugins/regional_endpoint.rb +74 -16
- data/lib/aws-sdk-core/plugins/response_paging.rb +2 -0
- data/lib/aws-sdk-core/plugins/retries/client_rate_limiter.rb +139 -0
- data/lib/aws-sdk-core/plugins/retries/clock_skew.rb +100 -0
- data/lib/aws-sdk-core/plugins/retries/error_inspector.rb +146 -0
- data/lib/aws-sdk-core/plugins/retries/retry_quota.rb +59 -0
- data/lib/aws-sdk-core/plugins/retry_errors.rb +295 -107
- data/lib/aws-sdk-core/plugins/signature_v2.rb +2 -0
- data/lib/aws-sdk-core/plugins/signature_v4.rb +28 -25
- data/lib/aws-sdk-core/plugins/stub_responses.rb +24 -7
- data/lib/aws-sdk-core/plugins/transfer_encoding.rb +53 -0
- data/lib/aws-sdk-core/plugins/user_agent.rb +6 -8
- data/lib/aws-sdk-core/process_credentials.rb +12 -5
- data/lib/aws-sdk-core/query/ec2_param_builder.rb +2 -0
- data/lib/aws-sdk-core/query/handler.rb +2 -0
- data/lib/aws-sdk-core/query/param.rb +2 -0
- data/lib/aws-sdk-core/query/param_builder.rb +2 -0
- data/lib/aws-sdk-core/query/param_list.rb +2 -0
- data/lib/aws-sdk-core/query.rb +2 -0
- data/lib/aws-sdk-core/refreshing_credentials.rb +15 -2
- data/lib/aws-sdk-core/resources/collection.rb +2 -0
- data/lib/aws-sdk-core/rest/handler.rb +2 -0
- data/lib/aws-sdk-core/rest/request/body.rb +21 -1
- data/lib/aws-sdk-core/rest/request/builder.rb +2 -0
- data/lib/aws-sdk-core/rest/request/endpoint.rb +10 -3
- data/lib/aws-sdk-core/rest/request/headers.rb +20 -6
- data/lib/aws-sdk-core/rest/request/querystring_builder.rb +4 -2
- data/lib/aws-sdk-core/rest/response/body.rb +2 -0
- data/lib/aws-sdk-core/rest/response/headers.rb +6 -3
- data/lib/aws-sdk-core/rest/response/parser.rb +2 -0
- data/lib/aws-sdk-core/rest/response/status_code.rb +2 -0
- data/lib/aws-sdk-core/rest.rb +2 -0
- data/lib/aws-sdk-core/shared_config.rb +153 -127
- data/lib/aws-sdk-core/shared_credentials.rb +9 -1
- data/lib/aws-sdk-core/sso_credentials.rb +136 -0
- data/lib/aws-sdk-core/structure.rb +14 -4
- data/lib/aws-sdk-core/stubbing/data_applicator.rb +2 -0
- data/lib/aws-sdk-core/stubbing/empty_stub.rb +2 -0
- data/lib/aws-sdk-core/stubbing/protocols/api_gateway.rb +2 -0
- data/lib/aws-sdk-core/stubbing/protocols/ec2.rb +2 -0
- data/lib/aws-sdk-core/stubbing/protocols/json.rb +3 -1
- data/lib/aws-sdk-core/stubbing/protocols/query.rb +4 -2
- data/lib/aws-sdk-core/stubbing/protocols/rest.rb +52 -7
- data/lib/aws-sdk-core/stubbing/protocols/rest_json.rb +3 -1
- data/lib/aws-sdk-core/stubbing/protocols/rest_xml.rb +2 -2
- data/lib/aws-sdk-core/stubbing/stub_data.rb +15 -4
- data/lib/aws-sdk-core/stubbing/xml_error.rb +2 -0
- data/lib/aws-sdk-core/type_builder.rb +2 -0
- data/lib/aws-sdk-core/util.rb +6 -0
- data/lib/aws-sdk-core/waiters/errors.rb +2 -0
- data/lib/aws-sdk-core/waiters/poller.rb +2 -0
- data/lib/aws-sdk-core/waiters/waiter.rb +4 -2
- data/lib/aws-sdk-core/waiters.rb +2 -0
- data/lib/aws-sdk-core/xml/builder.rb +5 -3
- data/lib/aws-sdk-core/xml/default_list.rb +2 -0
- data/lib/aws-sdk-core/xml/default_map.rb +2 -0
- data/lib/aws-sdk-core/xml/doc_builder.rb +15 -4
- data/lib/aws-sdk-core/xml/error_handler.rb +29 -4
- data/lib/aws-sdk-core/xml/parser/engines/libxml.rb +2 -0
- data/lib/aws-sdk-core/xml/parser/engines/nokogiri.rb +2 -0
- data/lib/aws-sdk-core/xml/parser/engines/oga.rb +2 -0
- data/lib/aws-sdk-core/xml/parser/engines/ox.rb +3 -1
- data/lib/aws-sdk-core/xml/parser/engines/rexml.rb +4 -1
- data/lib/aws-sdk-core/xml/parser/frame.rb +25 -0
- data/lib/aws-sdk-core/xml/parser/parsing_error.rb +2 -0
- data/lib/aws-sdk-core/xml/parser/stack.rb +2 -0
- data/lib/aws-sdk-core/xml/parser.rb +7 -0
- data/lib/aws-sdk-core/xml.rb +2 -0
- data/lib/aws-sdk-core.rb +23 -4
- data/lib/aws-sdk-sso/client.rb +568 -0
- data/lib/aws-sdk-sso/client_api.rb +190 -0
- data/lib/aws-sdk-sso/customizations.rb +1 -0
- data/lib/aws-sdk-sso/errors.rb +102 -0
- data/lib/aws-sdk-sso/resource.rb +26 -0
- data/lib/aws-sdk-sso/types.rb +352 -0
- data/lib/aws-sdk-sso.rb +55 -0
- data/lib/aws-sdk-sts/client.rb +1282 -531
- data/lib/aws-sdk-sts/client_api.rb +76 -1
- data/lib/aws-sdk-sts/customizations.rb +4 -0
- data/lib/aws-sdk-sts/errors.rb +153 -1
- data/lib/aws-sdk-sts/plugins/sts_regional_endpoints.rb +38 -0
- data/lib/aws-sdk-sts/presigner.rb +75 -0
- data/lib/aws-sdk-sts/resource.rb +4 -1
- data/lib/aws-sdk-sts/types.rb +958 -229
- data/lib/aws-sdk-sts.rb +16 -6
- data/lib/seahorse/client/async_base.rb +52 -0
- data/lib/seahorse/client/async_response.rb +64 -0
- data/lib/seahorse/client/base.rb +7 -2
- data/lib/seahorse/client/block_io.rb +6 -2
- data/lib/seahorse/client/configuration.rb +7 -1
- data/lib/seahorse/client/events.rb +3 -1
- data/lib/seahorse/client/h2/connection.rb +250 -0
- data/lib/seahorse/client/h2/handler.rb +152 -0
- data/lib/seahorse/client/handler.rb +2 -0
- data/lib/seahorse/client/handler_builder.rb +2 -0
- data/lib/seahorse/client/handler_list.rb +2 -0
- data/lib/seahorse/client/handler_list_entry.rb +6 -4
- data/lib/seahorse/client/http/async_response.rb +44 -0
- data/lib/seahorse/client/http/headers.rb +2 -0
- data/lib/seahorse/client/http/request.rb +5 -3
- data/lib/seahorse/client/http/response.rb +18 -11
- data/lib/seahorse/client/logging/formatter.rb +6 -2
- data/lib/seahorse/client/logging/handler.rb +2 -0
- data/lib/seahorse/client/managed_file.rb +2 -0
- data/lib/seahorse/client/net_http/connection_pool.rb +30 -23
- data/lib/seahorse/client/net_http/handler.rb +24 -7
- data/lib/seahorse/client/net_http/patches.rb +15 -84
- data/lib/seahorse/client/networking_error.rb +30 -0
- data/lib/seahorse/client/plugin.rb +10 -7
- data/lib/seahorse/client/plugin_list.rb +2 -0
- data/lib/seahorse/client/plugins/content_length.rb +14 -3
- data/lib/seahorse/client/plugins/endpoint.rb +4 -2
- data/lib/seahorse/client/plugins/h2.rb +69 -0
- data/lib/seahorse/client/plugins/logging.rb +2 -0
- data/lib/seahorse/client/plugins/net_http.rb +39 -3
- data/lib/seahorse/client/plugins/operation_methods.rb +2 -0
- data/lib/seahorse/client/plugins/raise_response_errors.rb +2 -0
- data/lib/seahorse/client/plugins/request_callback.rb +110 -0
- data/lib/seahorse/client/plugins/response_target.rb +23 -14
- data/lib/seahorse/client/request.rb +2 -0
- data/lib/seahorse/client/request_context.rb +2 -0
- data/lib/seahorse/client/response.rb +5 -5
- data/lib/seahorse/model/api.rb +10 -0
- data/lib/seahorse/model/authorizer.rb +2 -0
- data/lib/seahorse/model/operation.rb +9 -0
- data/lib/seahorse/model/shapes.rb +29 -2
- data/lib/seahorse/util.rb +8 -1
- data/lib/seahorse/version.rb +2 -0
- data/lib/seahorse.rb +12 -0
- metadata +64 -14
|
@@ -1,13 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'set'
|
|
4
|
+
require_relative 'retries/error_inspector'
|
|
5
|
+
require_relative 'retries/retry_quota'
|
|
6
|
+
require_relative 'retries/client_rate_limiter'
|
|
7
|
+
require_relative 'retries/clock_skew'
|
|
2
8
|
|
|
3
9
|
module Aws
|
|
4
10
|
module Plugins
|
|
5
11
|
# @api private
|
|
6
12
|
class RetryErrors < Seahorse::Client::Plugin
|
|
7
|
-
|
|
8
|
-
EQUAL_JITTER =
|
|
9
|
-
FULL_JITTER=
|
|
10
|
-
NO_JITTER =
|
|
13
|
+
# BEGIN LEGACY OPTIONS
|
|
14
|
+
EQUAL_JITTER = ->(delay) { (delay / 2) + Kernel.rand(0..(delay / 2)) }
|
|
15
|
+
FULL_JITTER = ->(delay) { Kernel.rand(0..delay) }
|
|
16
|
+
NO_JITTER = ->(delay) { delay }
|
|
11
17
|
|
|
12
18
|
JITTERS = {
|
|
13
19
|
none: NO_JITTER,
|
|
@@ -15,163 +21,349 @@ module Aws
|
|
|
15
21
|
full: FULL_JITTER
|
|
16
22
|
}
|
|
17
23
|
|
|
18
|
-
JITTERS.default_proc = lambda { |h,k|
|
|
19
|
-
raise KeyError,
|
|
24
|
+
JITTERS.default_proc = lambda { |h, k|
|
|
25
|
+
raise KeyError,
|
|
26
|
+
"#{k} is not a named jitter function. Must be one of #{h.keys}"
|
|
20
27
|
}
|
|
21
28
|
|
|
22
29
|
DEFAULT_BACKOFF = lambda do |c|
|
|
23
|
-
delay = 2
|
|
24
|
-
|
|
30
|
+
delay = 2**c.retries * c.config.retry_base_delay
|
|
31
|
+
if (c.config.retry_max_delay || 0) > 0
|
|
32
|
+
delay = [delay, c.config.retry_max_delay].min
|
|
33
|
+
end
|
|
25
34
|
jitter = c.config.retry_jitter
|
|
26
|
-
jitter = JITTERS[jitter] if Symbol
|
|
35
|
+
jitter = JITTERS[jitter] if jitter.is_a?(Symbol)
|
|
27
36
|
delay = jitter.call(delay) if jitter
|
|
28
37
|
Kernel.sleep(delay)
|
|
29
38
|
end
|
|
30
39
|
|
|
31
|
-
option(
|
|
40
|
+
option(
|
|
41
|
+
:retry_limit,
|
|
32
42
|
default: 3,
|
|
33
43
|
doc_type: Integer,
|
|
34
44
|
docstring: <<-DOCS)
|
|
35
45
|
The maximum number of times to retry failed requests. Only
|
|
36
46
|
~ 500 level server errors and certain ~ 400 level client errors
|
|
37
47
|
are retried. Generally, these are throttling errors, data
|
|
38
|
-
checksum errors, networking errors, timeout errors
|
|
39
|
-
errors from expired credentials.
|
|
48
|
+
checksum errors, networking errors, timeout errors, auth errors,
|
|
49
|
+
endpoint discovery, and errors from expired credentials.
|
|
50
|
+
This option is only used in the `legacy` retry mode.
|
|
40
51
|
DOCS
|
|
41
52
|
|
|
42
|
-
option(
|
|
53
|
+
option(
|
|
54
|
+
:retry_max_delay,
|
|
43
55
|
default: 0,
|
|
44
56
|
doc_type: Integer,
|
|
45
57
|
docstring: <<-DOCS)
|
|
46
|
-
The maximum number of seconds to delay between retries (0 for no limit)
|
|
58
|
+
The maximum number of seconds to delay between retries (0 for no limit)
|
|
59
|
+
used by the default backoff function. This option is only used in the
|
|
60
|
+
`legacy` retry mode.
|
|
47
61
|
DOCS
|
|
48
62
|
|
|
49
|
-
option(
|
|
63
|
+
option(
|
|
64
|
+
:retry_base_delay,
|
|
50
65
|
default: 0.3,
|
|
51
66
|
doc_type: Float,
|
|
52
67
|
docstring: <<-DOCS)
|
|
53
|
-
The base delay in seconds used by the default backoff function.
|
|
68
|
+
The base delay in seconds used by the default backoff function. This option
|
|
69
|
+
is only used in the `legacy` retry mode.
|
|
54
70
|
DOCS
|
|
55
71
|
|
|
56
|
-
option(
|
|
72
|
+
option(
|
|
73
|
+
:retry_jitter,
|
|
57
74
|
default: :none,
|
|
58
75
|
doc_type: Symbol,
|
|
59
76
|
docstring: <<-DOCS)
|
|
60
|
-
A delay randomiser function used by the default backoff function.
|
|
77
|
+
A delay randomiser function used by the default backoff function.
|
|
78
|
+
Some predefined functions can be referenced by name - :none, :equal, :full,
|
|
79
|
+
otherwise a Proc that takes and returns a number. This option is only used
|
|
80
|
+
in the `legacy` retry mode.
|
|
61
81
|
|
|
62
82
|
@see https://www.awsarchitectureblog.com/2015/03/backoff.html
|
|
63
83
|
DOCS
|
|
64
84
|
|
|
65
|
-
option(
|
|
85
|
+
option(
|
|
86
|
+
:retry_backoff,
|
|
87
|
+
default: DEFAULT_BACKOFF,
|
|
88
|
+
doc_type: Proc,
|
|
89
|
+
docstring: <<-DOCS)
|
|
90
|
+
A proc or lambda used for backoff. Defaults to 2**retries * retry_base_delay.
|
|
91
|
+
This option is only used in the `legacy` retry mode.
|
|
92
|
+
DOCS
|
|
66
93
|
|
|
67
|
-
#
|
|
68
|
-
class ErrorInspector
|
|
94
|
+
# END LEGACY OPTIONS
|
|
69
95
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
96
|
+
option(
|
|
97
|
+
:retry_mode,
|
|
98
|
+
default: 'legacy',
|
|
99
|
+
doc_type: String,
|
|
100
|
+
docstring: <<-DOCS) do |cfg|
|
|
101
|
+
Specifies which retry algorithm to use. Values are:
|
|
76
102
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
'ThrottlingException', # json services
|
|
80
|
-
'RequestThrottled', # sqs
|
|
81
|
-
'RequestThrottledException',
|
|
82
|
-
'ProvisionedThroughputExceededException', # dynamodb
|
|
83
|
-
'TransactionInProgressException', # dynamodb
|
|
84
|
-
'RequestLimitExceeded', # ec2
|
|
85
|
-
'BandwidthLimitExceeded', # cloud search
|
|
86
|
-
'LimitExceededException', # kinesis
|
|
87
|
-
'TooManyRequestsException', # batch
|
|
88
|
-
])
|
|
103
|
+
* `legacy` - The pre-existing retry behavior. This is default value if
|
|
104
|
+
no retry mode is provided.
|
|
89
105
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
106
|
+
* `standard` - A standardized set of retry rules across the AWS SDKs.
|
|
107
|
+
This includes support for retry quotas, which limit the number of
|
|
108
|
+
unsuccessful retries a client can make.
|
|
93
109
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
110
|
+
* `adaptive` - An experimental retry mode that includes all the
|
|
111
|
+
functionality of `standard` mode along with automatic client side
|
|
112
|
+
throttling. This is a provisional mode that may change behavior
|
|
113
|
+
in the future.
|
|
97
114
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
115
|
+
DOCS
|
|
116
|
+
resolve_retry_mode(cfg)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
option(
|
|
120
|
+
:max_attempts,
|
|
121
|
+
default: 3,
|
|
122
|
+
doc_type: Integer,
|
|
123
|
+
docstring: <<-DOCS) do |cfg|
|
|
124
|
+
An integer representing the maximum number attempts that will be made for
|
|
125
|
+
a single request, including the initial attempt. For example,
|
|
126
|
+
setting this value to 5 will result in a request being retried up to
|
|
127
|
+
4 times. Used in `standard` and `adaptive` retry modes.
|
|
128
|
+
DOCS
|
|
129
|
+
resolve_max_attempts(cfg)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
option(
|
|
133
|
+
:adaptive_retry_wait_to_fill,
|
|
134
|
+
default: true,
|
|
135
|
+
doc_type: 'Boolean',
|
|
136
|
+
docstring: <<-DOCS) do |cfg|
|
|
137
|
+
Used only in `adaptive` retry mode. When true, the request will sleep
|
|
138
|
+
until there is sufficent client side capacity to retry the request.
|
|
139
|
+
When false, the request will raise a `RetryCapacityNotAvailableError` and will
|
|
140
|
+
not retry instead of sleeping.
|
|
141
|
+
DOCS
|
|
142
|
+
resolve_adaptive_retry_wait_to_fill(cfg)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
option(
|
|
146
|
+
:correct_clock_skew,
|
|
147
|
+
default: true,
|
|
148
|
+
doc_type: 'Boolean',
|
|
149
|
+
docstring: <<-DOCS) do |cfg|
|
|
150
|
+
Used only in `standard` and adaptive retry modes. Specifies whether to apply
|
|
151
|
+
a clock skew correction and retry requests with skewed client clocks.
|
|
152
|
+
DOCS
|
|
153
|
+
resolve_correct_clock_skew(cfg)
|
|
154
|
+
end
|
|
103
155
|
|
|
104
|
-
|
|
105
|
-
|
|
156
|
+
# @api private undocumented
|
|
157
|
+
option(:client_rate_limiter) { Retries::ClientRateLimiter.new }
|
|
158
|
+
|
|
159
|
+
# @api private undocumented
|
|
160
|
+
option(:retry_quota) { Retries::RetryQuota.new }
|
|
161
|
+
|
|
162
|
+
# @api private undocumented
|
|
163
|
+
option(:clock_skew) { Retries::ClockSkew.new }
|
|
164
|
+
|
|
165
|
+
def self.resolve_retry_mode(cfg)
|
|
166
|
+
default_mode_value =
|
|
167
|
+
if cfg.respond_to?(:defaults_mode_config_resolver)
|
|
168
|
+
cfg.defaults_mode_config_resolver.resolve(:retry_mode)
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
value = ENV['AWS_RETRY_MODE'] ||
|
|
172
|
+
Aws.shared_config.retry_mode(profile: cfg.profile) ||
|
|
173
|
+
default_mode_value ||
|
|
174
|
+
'legacy'
|
|
175
|
+
# Raise if provided value is not one of the retry modes
|
|
176
|
+
if value != 'legacy' && value != 'standard' && value != 'adaptive'
|
|
177
|
+
raise ArgumentError,
|
|
178
|
+
'Must provide either `legacy`, `standard`, or `adaptive` for '\
|
|
179
|
+
'retry_mode profile option or for ENV[\'AWS_RETRY_MODE\']'
|
|
106
180
|
end
|
|
181
|
+
value
|
|
182
|
+
end
|
|
107
183
|
|
|
108
|
-
|
|
109
|
-
|
|
184
|
+
def self.resolve_max_attempts(cfg)
|
|
185
|
+
value = (ENV['AWS_MAX_ATTEMPTS']) ||
|
|
186
|
+
Aws.shared_config.max_attempts(profile: cfg.profile) ||
|
|
187
|
+
'3'
|
|
188
|
+
value = value.to_i
|
|
189
|
+
# Raise if provided value is not a positive integer
|
|
190
|
+
if value <= 0
|
|
191
|
+
raise ArgumentError,
|
|
192
|
+
'Must provide a positive integer for max_attempts profile '\
|
|
193
|
+
'option or for ENV[\'AWS_MAX_ATTEMPTS\']'
|
|
110
194
|
end
|
|
195
|
+
value
|
|
196
|
+
end
|
|
111
197
|
|
|
112
|
-
|
|
113
|
-
|
|
198
|
+
def self.resolve_adaptive_retry_wait_to_fill(cfg)
|
|
199
|
+
value = ENV['AWS_ADAPTIVE_RETRY_WAIT_TO_FILL'] ||
|
|
200
|
+
Aws.shared_config.adaptive_retry_wait_to_fill(profile: cfg.profile) ||
|
|
201
|
+
'true'
|
|
202
|
+
# Raise if provided value is not true or false
|
|
203
|
+
if value != 'true' && value != 'false'
|
|
204
|
+
raise ArgumentError,
|
|
205
|
+
'Must provide either `true` or `false` for '\
|
|
206
|
+
'adaptive_retry_wait_to_fill profile option or for '\
|
|
207
|
+
'ENV[\'AWS_ADAPTIVE_RETRY_WAIT_TO_FILL\']'
|
|
114
208
|
end
|
|
209
|
+
value == 'true'
|
|
210
|
+
end
|
|
115
211
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
212
|
+
def self.resolve_correct_clock_skew(cfg)
|
|
213
|
+
value = ENV['AWS_CORRECT_CLOCK_SKEW'] ||
|
|
214
|
+
Aws.shared_config.correct_clock_skew(profile: cfg.profile) ||
|
|
215
|
+
'true'
|
|
216
|
+
# Raise if provided value is not true or false
|
|
217
|
+
if value != 'true' && value != 'false'
|
|
218
|
+
raise ArgumentError,
|
|
219
|
+
'Must provide either `true` or `false` for '\
|
|
220
|
+
'correct_clock_skew profile option or for '\
|
|
221
|
+
'ENV[\'AWS_CORRECT_CLOCK_SKEW\']'
|
|
119
222
|
end
|
|
223
|
+
value == 'true'
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
class Handler < Seahorse::Client::Handler
|
|
227
|
+
# Max backoff (in seconds)
|
|
228
|
+
MAX_BACKOFF = 20
|
|
229
|
+
|
|
230
|
+
def call(context)
|
|
231
|
+
context.metadata[:retries] ||= {}
|
|
232
|
+
config = context.config
|
|
233
|
+
|
|
234
|
+
get_send_token(config)
|
|
235
|
+
add_retry_headers(context)
|
|
236
|
+
response = @handler.call(context)
|
|
237
|
+
error_inspector = Retries::ErrorInspector.new(
|
|
238
|
+
response.error, response.context.http_response.status_code
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
request_bookkeeping(context, response, error_inspector)
|
|
242
|
+
|
|
243
|
+
if error_inspector.endpoint_discovery?(context)
|
|
244
|
+
key = config.endpoint_cache.extract_key(context)
|
|
245
|
+
config.endpoint_cache.delete(key)
|
|
246
|
+
end
|
|
120
247
|
|
|
121
|
-
|
|
122
|
-
|
|
248
|
+
# Clock correction needs to be updated from the response even when
|
|
249
|
+
# the request is not retryable but should only be updated
|
|
250
|
+
# in the case of clock skew errors
|
|
251
|
+
if error_inspector.clock_skew?(context)
|
|
252
|
+
config.clock_skew.update_clock_correction(context)
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
# Estimated skew needs to be updated on every request
|
|
256
|
+
config.clock_skew.update_estimated_skew(context)
|
|
257
|
+
|
|
258
|
+
return response unless retryable?(context, response, error_inspector)
|
|
259
|
+
|
|
260
|
+
return response if context.retries >= config.max_attempts - 1
|
|
261
|
+
|
|
262
|
+
context.metadata[:retries][:capacity_amount] =
|
|
263
|
+
config.retry_quota.checkout_capacity(error_inspector)
|
|
264
|
+
return response unless context.metadata[:retries][:capacity_amount] > 0
|
|
265
|
+
|
|
266
|
+
delay = exponential_backoff(context.retries)
|
|
267
|
+
Kernel.sleep(delay)
|
|
268
|
+
retry_request(context, error_inspector)
|
|
123
269
|
end
|
|
124
270
|
|
|
125
|
-
|
|
126
|
-
return false unless context.operation.endpoint_discovery
|
|
271
|
+
private
|
|
127
272
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
273
|
+
def get_send_token(config)
|
|
274
|
+
# either fail fast or block until a token becomes available
|
|
275
|
+
# must be configurable
|
|
276
|
+
# need a maximum rate at which we can send requests (max_send_rate)
|
|
277
|
+
# is unset until a throttle is seen
|
|
278
|
+
if config.retry_mode == 'adaptive'
|
|
279
|
+
config.client_rate_limiter.token_bucket_acquire(
|
|
280
|
+
1,
|
|
281
|
+
config.adaptive_retry_wait_to_fill
|
|
282
|
+
)
|
|
131
283
|
end
|
|
284
|
+
end
|
|
132
285
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
286
|
+
# maxsendrate is updated if on adaptive mode and based on response
|
|
287
|
+
# retry quota is updated if the request is successful (both modes)
|
|
288
|
+
def request_bookkeeping(context, response, error_inspector)
|
|
289
|
+
config = context.config
|
|
290
|
+
if response.successful?
|
|
291
|
+
config.retry_quota.release(
|
|
292
|
+
context.metadata[:retries][:capacity_amount]
|
|
293
|
+
)
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
if config.retry_mode == 'adaptive'
|
|
297
|
+
is_throttling_error = error_inspector.throttling_error?
|
|
298
|
+
config.client_rate_limiter.update_sending_rate(is_throttling_error)
|
|
141
299
|
end
|
|
142
300
|
end
|
|
143
|
-
|
|
144
|
-
def retryable?(context)
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
server? or
|
|
150
|
-
endpoint_discovery?(context)
|
|
301
|
+
|
|
302
|
+
def retryable?(context, response, error_inspector)
|
|
303
|
+
return false if response.successful?
|
|
304
|
+
|
|
305
|
+
error_inspector.retryable?(context) &&
|
|
306
|
+
context.http_response.body.respond_to?(:truncate)
|
|
151
307
|
end
|
|
152
308
|
|
|
153
|
-
|
|
309
|
+
def exponential_backoff(retries)
|
|
310
|
+
# for a transient error, use backoff
|
|
311
|
+
[Kernel.rand * 2**retries, MAX_BACKOFF].min
|
|
312
|
+
end
|
|
154
313
|
|
|
155
|
-
def
|
|
156
|
-
context.
|
|
314
|
+
def retry_request(context, error)
|
|
315
|
+
context.retries += 1
|
|
316
|
+
context.config.credentials.refresh! if error.expired_credentials?
|
|
317
|
+
context.http_request.body.rewind
|
|
318
|
+
context.http_response.reset
|
|
319
|
+
call(context)
|
|
157
320
|
end
|
|
158
321
|
|
|
159
|
-
def
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
322
|
+
def add_retry_headers(context)
|
|
323
|
+
request_pairs = {
|
|
324
|
+
'attempt' => context.retries,
|
|
325
|
+
'max' => context.config.max_attempts
|
|
326
|
+
}
|
|
327
|
+
if (ttl = compute_request_ttl(context))
|
|
328
|
+
request_pairs['ttl'] = ttl
|
|
164
329
|
end
|
|
330
|
+
|
|
331
|
+
# create the request header
|
|
332
|
+
formatted_header = request_pairs.map { |k, v| "#{k}=#{v}" }.join('; ')
|
|
333
|
+
context.http_request.headers['amz-sdk-request'] = formatted_header
|
|
165
334
|
end
|
|
166
335
|
|
|
336
|
+
def compute_request_ttl(context)
|
|
337
|
+
return if context.operation.async
|
|
338
|
+
|
|
339
|
+
endpoint = context.http_request.endpoint
|
|
340
|
+
estimated_skew = context.config.clock_skew.estimated_skew(endpoint)
|
|
341
|
+
if context.config.respond_to?(:http_read_timeout)
|
|
342
|
+
read_timeout = context.config.http_read_timeout
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
if estimated_skew && read_timeout
|
|
346
|
+
(Time.now.utc + read_timeout + estimated_skew)
|
|
347
|
+
.strftime('%Y%m%dT%H%M%SZ')
|
|
348
|
+
end
|
|
349
|
+
end
|
|
167
350
|
end
|
|
168
351
|
|
|
169
|
-
class
|
|
352
|
+
class LegacyHandler < Seahorse::Client::Handler
|
|
170
353
|
|
|
171
354
|
def call(context)
|
|
172
355
|
response = @handler.call(context)
|
|
173
356
|
if response.error
|
|
174
|
-
|
|
357
|
+
error_inspector = Retries::ErrorInspector.new(
|
|
358
|
+
response.error, response.context.http_response.status_code
|
|
359
|
+
)
|
|
360
|
+
|
|
361
|
+
if error_inspector.endpoint_discovery?(context)
|
|
362
|
+
key = context.config.endpoint_cache.extract_key(context)
|
|
363
|
+
context.config.endpoint_cache.delete(key)
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
retry_if_possible(response, error_inspector)
|
|
175
367
|
else
|
|
176
368
|
response
|
|
177
369
|
end
|
|
@@ -179,21 +371,15 @@ A delay randomiser function used by the default backoff function. Some predefine
|
|
|
179
371
|
|
|
180
372
|
private
|
|
181
373
|
|
|
182
|
-
def retry_if_possible(response)
|
|
374
|
+
def retry_if_possible(response, error_inspector)
|
|
183
375
|
context = response.context
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
retry_request(context, error)
|
|
376
|
+
if should_retry?(context, error_inspector)
|
|
377
|
+
retry_request(context, error_inspector)
|
|
187
378
|
else
|
|
188
379
|
response
|
|
189
380
|
end
|
|
190
381
|
end
|
|
191
382
|
|
|
192
|
-
def error_for(response)
|
|
193
|
-
status_code = response.context.http_response.status_code
|
|
194
|
-
ErrorInspector.new(response.error, status_code)
|
|
195
|
-
end
|
|
196
|
-
|
|
197
383
|
def retry_request(context, error)
|
|
198
384
|
delay_retry(context)
|
|
199
385
|
context.retries += 1
|
|
@@ -208,9 +394,9 @@ A delay randomiser function used by the default backoff function. Some predefine
|
|
|
208
394
|
end
|
|
209
395
|
|
|
210
396
|
def should_retry?(context, error)
|
|
211
|
-
error.retryable?(context)
|
|
212
|
-
|
|
213
|
-
|
|
397
|
+
error.retryable?(context) &&
|
|
398
|
+
context.retries < retry_limit(context) &&
|
|
399
|
+
response_truncatable?(context)
|
|
214
400
|
end
|
|
215
401
|
|
|
216
402
|
def retry_limit(context)
|
|
@@ -220,15 +406,17 @@ A delay randomiser function used by the default backoff function. Some predefine
|
|
|
220
406
|
def response_truncatable?(context)
|
|
221
407
|
context.http_response.body.respond_to?(:truncate)
|
|
222
408
|
end
|
|
223
|
-
|
|
224
409
|
end
|
|
225
410
|
|
|
226
411
|
def add_handlers(handlers, config)
|
|
227
|
-
if config.
|
|
412
|
+
if config.retry_mode == 'legacy'
|
|
413
|
+
if config.retry_limit > 0
|
|
414
|
+
handlers.add(LegacyHandler, step: :sign, priority: 99)
|
|
415
|
+
end
|
|
416
|
+
else
|
|
228
417
|
handlers.add(Handler, step: :sign, priority: 99)
|
|
229
418
|
end
|
|
230
419
|
end
|
|
231
|
-
|
|
232
420
|
end
|
|
233
421
|
end
|
|
234
422
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'aws-sigv4'
|
|
2
4
|
|
|
3
5
|
module Aws
|
|
@@ -10,39 +12,29 @@ module Aws
|
|
|
10
12
|
end
|
|
11
13
|
|
|
12
14
|
option(:sigv4_name) do |cfg|
|
|
13
|
-
|
|
15
|
+
signingName = if cfg.region
|
|
16
|
+
Aws::Partitions::EndpointProvider.signing_service(
|
|
17
|
+
cfg.region, cfg.api.metadata['endpointPrefix']
|
|
18
|
+
)
|
|
19
|
+
end
|
|
20
|
+
signingName || cfg.api.metadata['signingName'] || cfg.api.metadata['endpointPrefix']
|
|
14
21
|
end
|
|
15
22
|
|
|
16
23
|
option(:sigv4_region) do |cfg|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
# client for a region like "us-west-2", we will
|
|
25
|
-
# always use "route53.amazonaws.com". This endpoint
|
|
26
|
-
# is actually global to the entire partition,
|
|
27
|
-
# and must be signed as "us-east-1".
|
|
28
|
-
#
|
|
29
|
-
# * When the region is configured, but it is configured
|
|
30
|
-
# to a non region, such as "aws-global". This is similar
|
|
31
|
-
# to the previous case. We use the Aws::Partitions::EndpointProvider
|
|
32
|
-
# to resolve to the actual signing region.
|
|
33
|
-
#
|
|
34
|
-
prefix = cfg.api.metadata['endpointPrefix']
|
|
35
|
-
if prefix && cfg.endpoint.to_s.match(/#{prefix}\.amazonaws\.com/)
|
|
36
|
-
'us-east-1'
|
|
37
|
-
elsif cfg.region
|
|
38
|
-
Aws::Partitions::EndpointProvider.signing_region(cfg.region, cfg.sigv4_name)
|
|
24
|
+
if cfg.region
|
|
25
|
+
if cfg.respond_to?(:sts_regional_endpoints)
|
|
26
|
+
sts_regional = cfg.sts_regional_endpoints
|
|
27
|
+
end
|
|
28
|
+
Aws::Partitions::EndpointProvider.signing_region(
|
|
29
|
+
cfg.region, cfg.api.metadata['endpointPrefix'], sts_regional
|
|
30
|
+
)
|
|
39
31
|
end
|
|
40
32
|
end
|
|
41
33
|
|
|
42
34
|
option(:unsigned_operations) do |cfg|
|
|
43
35
|
cfg.api.operation_names.inject([]) do |unsigned, operation_name|
|
|
44
36
|
if cfg.api.operation(operation_name)['authtype'] == 'none' ||
|
|
45
|
-
|
|
37
|
+
cfg.api.operation(operation_name)['authtype'] == 'custom'
|
|
46
38
|
# Unsign requests that has custom apigateway authorizer as well
|
|
47
39
|
unsigned << operation_name
|
|
48
40
|
else
|
|
@@ -107,6 +99,17 @@ module Aws
|
|
|
107
99
|
req.headers.delete('X-Amz-Security-Token')
|
|
108
100
|
req.headers.delete('X-Amz-Date')
|
|
109
101
|
|
|
102
|
+
if context.config.respond_to?(:clock_skew) &&
|
|
103
|
+
context.config.clock_skew &&
|
|
104
|
+
context.config.correct_clock_skew
|
|
105
|
+
|
|
106
|
+
endpoint = context.http_request.endpoint
|
|
107
|
+
skew = context.config.clock_skew.clock_correction(endpoint)
|
|
108
|
+
if skew.abs > 0
|
|
109
|
+
req.headers['X-Amz-Date'] = (Time.now.utc + skew).strftime("%Y%m%dT%H%M%SZ")
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
110
113
|
# compute the signature
|
|
111
114
|
begin
|
|
112
115
|
signature = signer.sign_request(
|
|
@@ -130,7 +133,7 @@ module Aws
|
|
|
130
133
|
# @api private
|
|
131
134
|
def apply_authtype(context)
|
|
132
135
|
if context.operation['authtype'].eql?('v4-unsigned-body') &&
|
|
133
|
-
|
|
136
|
+
context.http_request.endpoint.scheme.eql?('https')
|
|
134
137
|
context.http_request.headers['X-Amz-Content-Sha256'] = 'UNSIGNED-PAYLOAD'
|
|
135
138
|
end
|
|
136
139
|
context
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Aws
|
|
2
4
|
module Plugins
|
|
3
5
|
# @api private
|
|
@@ -34,9 +36,12 @@ requests are made, and retries are disabled.
|
|
|
34
36
|
if client.config.stub_responses
|
|
35
37
|
client.setup_stubbing
|
|
36
38
|
client.handlers.remove(RetryErrors::Handler)
|
|
39
|
+
client.handlers.remove(RetryErrors::LegacyHandler)
|
|
37
40
|
client.handlers.remove(ClientMetricsPlugin::Handler)
|
|
38
41
|
client.handlers.remove(ClientMetricsSendPlugin::LatencyHandler)
|
|
39
42
|
client.handlers.remove(ClientMetricsSendPlugin::AttemptHandler)
|
|
43
|
+
client.handlers.remove(Seahorse::Client::Plugins::RequestCallback::OptionHandler)
|
|
44
|
+
client.handlers.remove(Seahorse::Client::Plugins::RequestCallback::ReadCallbackHandler)
|
|
40
45
|
end
|
|
41
46
|
end
|
|
42
47
|
|
|
@@ -45,15 +50,18 @@ requests are made, and retries are disabled.
|
|
|
45
50
|
def call(context)
|
|
46
51
|
stub = context.client.next_stub(context)
|
|
47
52
|
resp = Seahorse::Client::Response.new(context: context)
|
|
48
|
-
|
|
49
|
-
resp
|
|
53
|
+
async_mode = context.client.is_a? Seahorse::Client::AsyncBase
|
|
54
|
+
apply_stub(stub, resp, async_mode)
|
|
55
|
+
|
|
56
|
+
async_mode ? Seahorse::Client::AsyncResponse.new(
|
|
57
|
+
context: context, stream: context[:input_event_stream_handler].event_emitter.stream, sync_queue: Queue.new) : resp
|
|
50
58
|
end
|
|
51
59
|
|
|
52
|
-
def apply_stub(stub, response)
|
|
60
|
+
def apply_stub(stub, response, async_mode = false)
|
|
53
61
|
http_resp = response.context.http_response
|
|
54
62
|
case
|
|
55
63
|
when stub[:error] then signal_error(stub[:error], http_resp)
|
|
56
|
-
when stub[:http] then signal_http(stub[:http], http_resp)
|
|
64
|
+
when stub[:http] then signal_http(stub[:http], http_resp, async_mode)
|
|
57
65
|
when stub[:data] then response.data = stub[:data]
|
|
58
66
|
end
|
|
59
67
|
end
|
|
@@ -67,9 +75,18 @@ requests are made, and retries are disabled.
|
|
|
67
75
|
end
|
|
68
76
|
|
|
69
77
|
# @param [Seahorse::Client::Http::Response] stub
|
|
70
|
-
# @param [Seahorse::Client::Http::Response] http_resp
|
|
71
|
-
|
|
72
|
-
|
|
78
|
+
# @param [Seahorse::Client::Http::Response | Seahorse::Client::Http::AsyncResponse] http_resp
|
|
79
|
+
# @param [Boolean] async_mode
|
|
80
|
+
def signal_http(stub, http_resp, async_mode = false)
|
|
81
|
+
if async_mode
|
|
82
|
+
h2_headers = stub.headers.to_h.inject([]) do |arr, (k, v)|
|
|
83
|
+
arr << [k, v]
|
|
84
|
+
end
|
|
85
|
+
h2_headers << [":status", stub.status_code]
|
|
86
|
+
http_resp.signal_headers(h2_headers)
|
|
87
|
+
else
|
|
88
|
+
http_resp.signal_headers(stub.status_code, stub.headers.to_h)
|
|
89
|
+
end
|
|
73
90
|
while chunk = stub.body.read(1024 * 1024)
|
|
74
91
|
http_resp.signal_data(chunk)
|
|
75
92
|
end
|