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
data/lib/aws-sdk-sts.rb
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
# WARNING ABOUT GENERATED CODE
|
|
2
4
|
#
|
|
3
5
|
# This file is generated. See the contributing guide for more information:
|
|
4
|
-
# https://github.com/aws/aws-sdk-ruby/blob/
|
|
6
|
+
# https://github.com/aws/aws-sdk-ruby/blob/version-3/CONTRIBUTING.md
|
|
5
7
|
#
|
|
6
8
|
# WARNING ABOUT GENERATED CODE
|
|
7
9
|
|
|
8
10
|
|
|
11
|
+
unless Module.const_defined?(:Aws)
|
|
12
|
+
require 'aws-sdk-core'
|
|
13
|
+
require 'aws-sigv4'
|
|
14
|
+
end
|
|
15
|
+
|
|
9
16
|
require_relative 'aws-sdk-sts/types'
|
|
10
17
|
require_relative 'aws-sdk-sts/client_api'
|
|
11
18
|
require_relative 'aws-sdk-sts/client'
|
|
@@ -22,24 +29,27 @@ require_relative 'aws-sdk-sts/customizations'
|
|
|
22
29
|
# methods each accept a hash of request parameters and return a response
|
|
23
30
|
# structure.
|
|
24
31
|
#
|
|
32
|
+
# sts = Aws::STS::Client.new
|
|
33
|
+
# resp = sts.assume_role(params)
|
|
34
|
+
#
|
|
25
35
|
# See {Client} for more information.
|
|
26
36
|
#
|
|
27
37
|
# # Errors
|
|
28
38
|
#
|
|
29
|
-
# Errors returned from AWS Security Token Service
|
|
30
|
-
# extend {Errors::ServiceError}.
|
|
39
|
+
# Errors returned from AWS Security Token Service are defined in the
|
|
40
|
+
# {Errors} module and all extend {Errors::ServiceError}.
|
|
31
41
|
#
|
|
32
42
|
# begin
|
|
33
43
|
# # do stuff
|
|
34
44
|
# rescue Aws::STS::Errors::ServiceError
|
|
35
|
-
# # rescues all
|
|
45
|
+
# # rescues all AWS Security Token Service API errors
|
|
36
46
|
# end
|
|
37
47
|
#
|
|
38
48
|
# See {Errors} for more information.
|
|
39
49
|
#
|
|
40
|
-
#
|
|
50
|
+
# @!group service
|
|
41
51
|
module Aws::STS
|
|
42
52
|
|
|
43
|
-
GEM_VERSION = '3.
|
|
53
|
+
GEM_VERSION = '3.126.2'
|
|
44
54
|
|
|
45
55
|
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Seahorse
|
|
4
|
+
module Client
|
|
5
|
+
class AsyncBase < Seahorse::Client::Base
|
|
6
|
+
|
|
7
|
+
# default H2 plugins
|
|
8
|
+
@plugins = PluginList.new([
|
|
9
|
+
Plugins::Endpoint,
|
|
10
|
+
Plugins::H2,
|
|
11
|
+
Plugins::ResponseTarget
|
|
12
|
+
])
|
|
13
|
+
|
|
14
|
+
def initialize(plugins, options)
|
|
15
|
+
super
|
|
16
|
+
@connection = H2::Connection.new(options)
|
|
17
|
+
@options = options
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# @return [H2::Connection]
|
|
21
|
+
attr_reader :connection
|
|
22
|
+
|
|
23
|
+
# @return [Array<Symbol>] Returns a list of valid async request
|
|
24
|
+
# operation names.
|
|
25
|
+
def operation_names
|
|
26
|
+
self.class.api.async_operation_names
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Closes the underlying HTTP2 Connection for the client
|
|
30
|
+
# @return [Symbol] Returns the status of the connection (:closed)
|
|
31
|
+
def close_connection
|
|
32
|
+
@connection.close!
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Creates a new HTTP2 Connection for the client
|
|
36
|
+
# @return [Seahorse::Client::H2::Connection]
|
|
37
|
+
def new_connection
|
|
38
|
+
if @connection.closed?
|
|
39
|
+
@connection = H2::Connection.new(@options)
|
|
40
|
+
else
|
|
41
|
+
@connection
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def connection_errors
|
|
46
|
+
@connection.errors
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Seahorse
|
|
4
|
+
module Client
|
|
5
|
+
class AsyncResponse
|
|
6
|
+
|
|
7
|
+
def initialize(options = {})
|
|
8
|
+
@response = Response.new(context: options[:context])
|
|
9
|
+
@stream = options[:stream]
|
|
10
|
+
@stream_mutex = options[:stream_mutex]
|
|
11
|
+
@close_condition = options[:close_condition]
|
|
12
|
+
@sync_queue = options[:sync_queue]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def context
|
|
16
|
+
@response.context
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def error
|
|
20
|
+
@response.error
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def on(range, &block)
|
|
24
|
+
@response.on(range, &block)
|
|
25
|
+
self
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def on_complete(&block)
|
|
29
|
+
@response.on_complete(&block)
|
|
30
|
+
self
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def wait
|
|
34
|
+
if error && context.config.raise_response_errors
|
|
35
|
+
raise error
|
|
36
|
+
elsif @stream
|
|
37
|
+
# have a sync signal that #signal can be blocked on
|
|
38
|
+
# else, if #signal is called before #wait
|
|
39
|
+
# will be waiting for a signal never arrives
|
|
40
|
+
@sync_queue << "sync_signal"
|
|
41
|
+
# now #signal is unlocked for
|
|
42
|
+
# signaling close condition when ready
|
|
43
|
+
@stream_mutex.synchronize {
|
|
44
|
+
@close_condition.wait(@stream_mutex)
|
|
45
|
+
}
|
|
46
|
+
@response
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def join!
|
|
51
|
+
if error && context.config.raise_response_errors
|
|
52
|
+
raise error
|
|
53
|
+
elsif @stream
|
|
54
|
+
# close callback is waiting
|
|
55
|
+
# for the "sync_signal"
|
|
56
|
+
@sync_queue << "sync_signal"
|
|
57
|
+
@stream.close
|
|
58
|
+
@response
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
data/lib/seahorse/client/base.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'thread'
|
|
2
4
|
|
|
3
5
|
module Seahorse
|
|
@@ -12,6 +14,7 @@ module Seahorse
|
|
|
12
14
|
Plugins::NetHttp,
|
|
13
15
|
Plugins::RaiseResponseErrors,
|
|
14
16
|
Plugins::ResponseTarget,
|
|
17
|
+
Plugins::RequestCallback
|
|
15
18
|
])
|
|
16
19
|
|
|
17
20
|
# @api private
|
|
@@ -46,7 +49,7 @@ module Seahorse
|
|
|
46
49
|
# names. These are valid arguments to {#build_request} and are also
|
|
47
50
|
# valid methods.
|
|
48
51
|
def operation_names
|
|
49
|
-
self.class.api.operation_names
|
|
52
|
+
self.class.api.operation_names - self.class.api.async_operation_names
|
|
50
53
|
end
|
|
51
54
|
|
|
52
55
|
private
|
|
@@ -194,13 +197,15 @@ module Seahorse
|
|
|
194
197
|
private
|
|
195
198
|
|
|
196
199
|
def define_operation_methods
|
|
200
|
+
operations_module = Module.new
|
|
197
201
|
@api.operation_names.each do |method_name|
|
|
198
|
-
define_method
|
|
202
|
+
operations_module.send(:define_method, method_name) do |*args, &block|
|
|
199
203
|
params = args[0] || {}
|
|
200
204
|
options = args[1] || {}
|
|
201
205
|
build_request(method_name, params).send_request(options, &block)
|
|
202
206
|
end
|
|
203
207
|
end
|
|
208
|
+
include(operations_module)
|
|
204
209
|
end
|
|
205
210
|
|
|
206
211
|
def build_plugins
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Seahorse
|
|
2
4
|
module Client
|
|
3
5
|
class BlockIO
|
|
4
6
|
|
|
5
|
-
def initialize(&block)
|
|
7
|
+
def initialize(headers = nil, &block)
|
|
8
|
+
@headers = headers
|
|
6
9
|
@block = block
|
|
7
10
|
@size = 0
|
|
8
11
|
end
|
|
@@ -10,7 +13,8 @@ module Seahorse
|
|
|
10
13
|
# @param [String] chunk
|
|
11
14
|
# @return [Integer]
|
|
12
15
|
def write(chunk)
|
|
13
|
-
@block.call(chunk)
|
|
16
|
+
@block.call(chunk, @headers)
|
|
17
|
+
ensure
|
|
14
18
|
chunk.bytesize.tap { |chunk_size| @size += chunk_size }
|
|
15
19
|
end
|
|
16
20
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'set'
|
|
2
4
|
|
|
3
5
|
module Seahorse
|
|
@@ -104,7 +106,7 @@ module Seahorse
|
|
|
104
106
|
#
|
|
105
107
|
# @return [self]
|
|
106
108
|
def add_option(name, default = nil, &block)
|
|
107
|
-
default = DynamicDefault.new(
|
|
109
|
+
default = DynamicDefault.new(block) if block_given?
|
|
108
110
|
@defaults[name.to_sym] << default
|
|
109
111
|
self
|
|
110
112
|
end
|
|
@@ -193,6 +195,10 @@ module Seahorse
|
|
|
193
195
|
@members.include?(method_name) or super
|
|
194
196
|
end
|
|
195
197
|
|
|
198
|
+
def override_config(k, v)
|
|
199
|
+
@struct[k] = v
|
|
200
|
+
end
|
|
201
|
+
|
|
196
202
|
private
|
|
197
203
|
|
|
198
204
|
def value_at(opt_name)
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Seahorse
|
|
2
4
|
module Client
|
|
3
5
|
module EventEmitter
|
|
@@ -9,7 +11,7 @@ module Seahorse
|
|
|
9
11
|
|
|
10
12
|
def emit(event_name, *args, &block)
|
|
11
13
|
@listeners[event_name] ||= []
|
|
12
|
-
@listeners[event_name] <<
|
|
14
|
+
@listeners[event_name] << block if block_given?
|
|
13
15
|
end
|
|
14
16
|
|
|
15
17
|
def signal(event, *args)
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
begin
|
|
4
|
+
require 'http/2'
|
|
5
|
+
rescue LoadError; end
|
|
6
|
+
require 'openssl'
|
|
7
|
+
require 'socket'
|
|
8
|
+
|
|
9
|
+
module Seahorse
|
|
10
|
+
module Client
|
|
11
|
+
# @api private
|
|
12
|
+
module H2
|
|
13
|
+
|
|
14
|
+
# H2 Connection build on top of `http/2` gem
|
|
15
|
+
# (requires Ruby >= 2.1)
|
|
16
|
+
# with TLS layer plus ALPN, requires:
|
|
17
|
+
# Ruby >= 2.3 and OpenSSL >= 1.0.2
|
|
18
|
+
class Connection
|
|
19
|
+
|
|
20
|
+
OPTIONS = {
|
|
21
|
+
max_concurrent_streams: 100,
|
|
22
|
+
connection_timeout: 60,
|
|
23
|
+
connection_read_timeout: 60,
|
|
24
|
+
http_wire_trace: false,
|
|
25
|
+
logger: nil,
|
|
26
|
+
ssl_verify_peer: true,
|
|
27
|
+
ssl_ca_bundle: nil,
|
|
28
|
+
ssl_ca_directory: nil,
|
|
29
|
+
ssl_ca_store: nil,
|
|
30
|
+
enable_alpn: false
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
# chunk read size at socket
|
|
34
|
+
CHUNKSIZE = 1024
|
|
35
|
+
|
|
36
|
+
SOCKET_FAMILY = ::Socket::AF_INET
|
|
37
|
+
|
|
38
|
+
def initialize(options = {})
|
|
39
|
+
OPTIONS.each_pair do |opt_name, default_value|
|
|
40
|
+
value = options[opt_name].nil? ? default_value : options[opt_name]
|
|
41
|
+
instance_variable_set("@#{opt_name}", value)
|
|
42
|
+
end
|
|
43
|
+
@h2_client = HTTP2::Client.new(
|
|
44
|
+
settings_max_concurrent_streams: max_concurrent_streams
|
|
45
|
+
)
|
|
46
|
+
@logger = options[:logger] || Logger.new($stdout) if @http_wire_trace
|
|
47
|
+
@chunk_size = options[:read_chunk_size] || CHUNKSIZE
|
|
48
|
+
@errors = []
|
|
49
|
+
@status = :ready
|
|
50
|
+
@mutex = Mutex.new # connection can be shared across requests
|
|
51
|
+
@socket = nil
|
|
52
|
+
@socket_thread = nil
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
OPTIONS.keys.each do |attr_name|
|
|
56
|
+
attr_reader(attr_name)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
alias ssl_verify_peer? ssl_verify_peer
|
|
60
|
+
|
|
61
|
+
attr_reader :errors
|
|
62
|
+
|
|
63
|
+
attr_accessor :input_signal_thread
|
|
64
|
+
|
|
65
|
+
def new_stream
|
|
66
|
+
begin
|
|
67
|
+
@h2_client.new_stream
|
|
68
|
+
rescue => error
|
|
69
|
+
raise Http2StreamInitializeError.new(error)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def connect(endpoint)
|
|
74
|
+
@mutex.synchronize {
|
|
75
|
+
if @status == :ready
|
|
76
|
+
tcp, addr = _tcp_socket(endpoint)
|
|
77
|
+
debug_output("opening connection to #{endpoint.host}:#{endpoint.port} ...")
|
|
78
|
+
_nonblocking_connect(tcp, addr)
|
|
79
|
+
debug_output('opened')
|
|
80
|
+
|
|
81
|
+
if endpoint.scheme == 'https'
|
|
82
|
+
@socket = OpenSSL::SSL::SSLSocket.new(tcp, _tls_context)
|
|
83
|
+
@socket.sync_close = true
|
|
84
|
+
@socket.hostname = endpoint.host
|
|
85
|
+
|
|
86
|
+
debug_output("starting TLS for #{endpoint.host}:#{endpoint.port} ...")
|
|
87
|
+
@socket.connect
|
|
88
|
+
debug_output('TLS established')
|
|
89
|
+
else
|
|
90
|
+
@socket = tcp
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
_register_h2_callbacks
|
|
94
|
+
@status = :active
|
|
95
|
+
elsif @status == :closed
|
|
96
|
+
msg = 'Async Client HTTP2 Connection is closed, you may'\
|
|
97
|
+
' use #new_connection to create a new HTTP2 Connection for this client'
|
|
98
|
+
raise Http2ConnectionClosedError.new(msg)
|
|
99
|
+
end
|
|
100
|
+
}
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def start(stream)
|
|
104
|
+
@mutex.synchronize {
|
|
105
|
+
return if @socket_thread
|
|
106
|
+
@socket_thread = Thread.new do
|
|
107
|
+
while !@socket.closed?
|
|
108
|
+
begin
|
|
109
|
+
data = @socket.read_nonblock(@chunk_size)
|
|
110
|
+
@h2_client << data
|
|
111
|
+
rescue IO::WaitReadable
|
|
112
|
+
begin
|
|
113
|
+
unless IO.select([@socket], nil, nil, connection_read_timeout)
|
|
114
|
+
self.debug_output('socket connection read time out')
|
|
115
|
+
self.close!
|
|
116
|
+
else
|
|
117
|
+
# available, retry to start reading
|
|
118
|
+
retry
|
|
119
|
+
end
|
|
120
|
+
rescue
|
|
121
|
+
# error can happen when closing the socket
|
|
122
|
+
# while it's waiting for read
|
|
123
|
+
self.close!
|
|
124
|
+
end
|
|
125
|
+
rescue EOFError
|
|
126
|
+
self.close!
|
|
127
|
+
rescue => error
|
|
128
|
+
self.debug_output(error.inspect)
|
|
129
|
+
@errors << error
|
|
130
|
+
self.close!
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
@socket_thread.abort_on_exception = true
|
|
135
|
+
}
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def close!
|
|
139
|
+
@mutex.synchronize {
|
|
140
|
+
self.debug_output('closing connection ...')
|
|
141
|
+
if @socket
|
|
142
|
+
@socket.close
|
|
143
|
+
@socket = nil
|
|
144
|
+
end
|
|
145
|
+
if @socket_thread
|
|
146
|
+
Thread.kill(@socket_thread)
|
|
147
|
+
@socket_thread = nil
|
|
148
|
+
end
|
|
149
|
+
@status = :closed
|
|
150
|
+
}
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def closed?
|
|
154
|
+
@status == :closed
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def debug_output(msg, type = nil)
|
|
158
|
+
prefix = case type
|
|
159
|
+
when :send then '-> '
|
|
160
|
+
when :receive then '<- '
|
|
161
|
+
else
|
|
162
|
+
''
|
|
163
|
+
end
|
|
164
|
+
return unless @logger
|
|
165
|
+
_debug_entry(prefix + msg)
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
private
|
|
169
|
+
|
|
170
|
+
def _debug_entry(str)
|
|
171
|
+
@logger << str
|
|
172
|
+
@logger << "\n"
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def _register_h2_callbacks
|
|
176
|
+
@h2_client.on(:frame) do |bytes|
|
|
177
|
+
if @socket.nil?
|
|
178
|
+
msg = 'Connection is closed due to errors, '\
|
|
179
|
+
'you can find errors at async_client.connection.errors'
|
|
180
|
+
raise Http2ConnectionClosedError.new(msg)
|
|
181
|
+
else
|
|
182
|
+
@socket.print(bytes)
|
|
183
|
+
@socket.flush
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
@h2_client.on(:frame_sent) do |frame|
|
|
187
|
+
debug_output("frame: #{frame.inspect}", :send)
|
|
188
|
+
end
|
|
189
|
+
@h2_client.on(:frame_received) do |frame|
|
|
190
|
+
debug_output("frame: #{frame.inspect}", :receive)
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def _tcp_socket(endpoint)
|
|
195
|
+
tcp = ::Socket.new(SOCKET_FAMILY, ::Socket::SOCK_STREAM, 0)
|
|
196
|
+
tcp.setsockopt(::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY, 1)
|
|
197
|
+
|
|
198
|
+
address = ::Socket.getaddrinfo(endpoint.host, nil, SOCKET_FAMILY).first[3]
|
|
199
|
+
sockaddr = ::Socket.sockaddr_in(endpoint.port, address)
|
|
200
|
+
|
|
201
|
+
[tcp, sockaddr]
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def _nonblocking_connect(tcp, addr)
|
|
205
|
+
begin
|
|
206
|
+
tcp.connect_nonblock(addr)
|
|
207
|
+
rescue IO::WaitWritable
|
|
208
|
+
unless IO.select(nil, [tcp], nil, connection_timeout)
|
|
209
|
+
tcp.close
|
|
210
|
+
raise
|
|
211
|
+
end
|
|
212
|
+
begin
|
|
213
|
+
tcp.connect_nonblock(addr)
|
|
214
|
+
rescue Errno::EISCONN
|
|
215
|
+
# tcp socket connected, continue
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
def _tls_context
|
|
221
|
+
ssl_ctx = OpenSSL::SSL::SSLContext.new(:TLSv1_2)
|
|
222
|
+
if ssl_verify_peer?
|
|
223
|
+
ssl_ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
|
224
|
+
ssl_ctx.ca_file = ssl_ca_bundle ? ssl_ca_bundle : _default_ca_bundle
|
|
225
|
+
ssl_ctx.ca_path = ssl_ca_directory ? ssl_ca_directory : _default_ca_directory
|
|
226
|
+
ssl_ctx.cert_store = ssl_ca_store if ssl_ca_store
|
|
227
|
+
else
|
|
228
|
+
ssl_ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
|
229
|
+
end
|
|
230
|
+
if enable_alpn
|
|
231
|
+
debug_output('enabling ALPN for TLS ...')
|
|
232
|
+
ssl_ctx.alpn_protocols = ['h2']
|
|
233
|
+
end
|
|
234
|
+
ssl_ctx
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
def _default_ca_bundle
|
|
238
|
+
File.exist?(OpenSSL::X509::DEFAULT_CERT_FILE) ?
|
|
239
|
+
OpenSSL::X509::DEFAULT_CERT_FILE : nil
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
def _default_ca_directory
|
|
243
|
+
Dir.exist?(OpenSSL::X509::DEFAULT_CERT_DIR) ?
|
|
244
|
+
OpenSSL::X509::DEFAULT_CERT_DIR : nil
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
end
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
begin
|
|
4
|
+
require 'http/2'
|
|
5
|
+
rescue LoadError; end
|
|
6
|
+
|
|
7
|
+
require 'securerandom'
|
|
8
|
+
|
|
9
|
+
module Seahorse
|
|
10
|
+
module Client
|
|
11
|
+
# @api private
|
|
12
|
+
module H2
|
|
13
|
+
|
|
14
|
+
NETWORK_ERRORS = [
|
|
15
|
+
SocketError, EOFError, IOError, Timeout::Error,
|
|
16
|
+
Errno::ECONNABORTED, Errno::ECONNRESET, Errno::EPIPE,
|
|
17
|
+
Errno::EINVAL, Errno::ETIMEDOUT, OpenSSL::SSL::SSLError,
|
|
18
|
+
Errno::EHOSTUNREACH, Errno::ECONNREFUSED,# OpenSSL::SSL::SSLErrorWaitReadable
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
# @api private
|
|
22
|
+
DNS_ERROR_MESSAGES = [
|
|
23
|
+
'getaddrinfo: nodename nor servname provided, or not known', # MacOS
|
|
24
|
+
'getaddrinfo: Name or service not known' # GNU
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
class Handler < Client::Handler
|
|
28
|
+
|
|
29
|
+
def call(context)
|
|
30
|
+
stream = nil
|
|
31
|
+
begin
|
|
32
|
+
conn = context.client.connection
|
|
33
|
+
stream = conn.new_stream
|
|
34
|
+
|
|
35
|
+
stream_mutex = Mutex.new
|
|
36
|
+
close_condition = ConditionVariable.new
|
|
37
|
+
sync_queue = Queue.new
|
|
38
|
+
|
|
39
|
+
conn.connect(context.http_request.endpoint)
|
|
40
|
+
_register_callbacks(
|
|
41
|
+
context.http_response,
|
|
42
|
+
stream,
|
|
43
|
+
stream_mutex,
|
|
44
|
+
close_condition,
|
|
45
|
+
sync_queue
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
conn.debug_output("sending initial request ...")
|
|
49
|
+
if input_emitter = context[:input_event_emitter]
|
|
50
|
+
_send_initial_headers(context.http_request, stream)
|
|
51
|
+
|
|
52
|
+
# prepare for sending events later
|
|
53
|
+
input_emitter.stream = stream
|
|
54
|
+
# request sigv4 serves as the initial #prior_signature
|
|
55
|
+
input_emitter.encoder.prior_signature =
|
|
56
|
+
context.http_request.headers['authorization'].split('Signature=').last
|
|
57
|
+
input_emitter.validate_event = context.config.validate_params
|
|
58
|
+
else
|
|
59
|
+
_send_initial_headers(context.http_request, stream)
|
|
60
|
+
_send_initial_data(context.http_request, stream)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
conn.start(stream)
|
|
64
|
+
rescue *NETWORK_ERRORS => error
|
|
65
|
+
error = NetworkingError.new(
|
|
66
|
+
error, error_message(context.http_request, error))
|
|
67
|
+
context.http_response.signal_error(error)
|
|
68
|
+
rescue => error
|
|
69
|
+
conn.debug_output(error.inspect)
|
|
70
|
+
# not retryable
|
|
71
|
+
context.http_response.signal_error(error)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
AsyncResponse.new(
|
|
75
|
+
context: context,
|
|
76
|
+
stream: stream,
|
|
77
|
+
stream_mutex: stream_mutex,
|
|
78
|
+
close_condition: close_condition,
|
|
79
|
+
sync_queue: sync_queue
|
|
80
|
+
)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
private
|
|
84
|
+
|
|
85
|
+
def _register_callbacks(resp, stream, stream_mutex, close_condition, sync_queue)
|
|
86
|
+
stream.on(:headers) do |headers|
|
|
87
|
+
resp.signal_headers(headers)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
stream.on(:data) do |data|
|
|
91
|
+
resp.signal_data(data)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
stream.on(:close) do
|
|
95
|
+
resp.signal_done
|
|
96
|
+
# block until #wait is ready for signal
|
|
97
|
+
# else deadlock may happen because #signal happened
|
|
98
|
+
# eariler than #wait (see AsyncResponse#wait)
|
|
99
|
+
sync_queue.pop
|
|
100
|
+
stream_mutex.synchronize {
|
|
101
|
+
close_condition.signal
|
|
102
|
+
}
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def _send_initial_headers(req, stream)
|
|
107
|
+
begin
|
|
108
|
+
headers = _h2_headers(req)
|
|
109
|
+
stream.headers(headers, end_stream: false)
|
|
110
|
+
rescue => e
|
|
111
|
+
raise Http2InitialRequestError.new(e)
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def _send_initial_data(req, stream)
|
|
116
|
+
begin
|
|
117
|
+
data = req.body.read
|
|
118
|
+
stream.data(data, end_stream: true)
|
|
119
|
+
rescue => e
|
|
120
|
+
raise Http2InitialRequestError.new(e)
|
|
121
|
+
end
|
|
122
|
+
data
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# H2 pseudo headers
|
|
126
|
+
# https://http2.github.io/http2-spec/#rfc.section.8.1.2.3
|
|
127
|
+
def _h2_headers(req)
|
|
128
|
+
headers = {}
|
|
129
|
+
headers[':method'] = req.http_method.upcase
|
|
130
|
+
headers[':scheme'] = req.endpoint.scheme
|
|
131
|
+
headers[':path'] = req.endpoint.path.empty? ? '/' : req.endpoint.path
|
|
132
|
+
if req.endpoint.query && !req.endpoint.query.empty?
|
|
133
|
+
headers[':path'] += "?#{req.endpoint.query}"
|
|
134
|
+
end
|
|
135
|
+
req.headers.each {|k, v| headers[k.downcase] = v }
|
|
136
|
+
headers
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def error_message(req, error)
|
|
140
|
+
if error.is_a?(SocketError) && DNS_ERROR_MESSAGES.include?(error.message)
|
|
141
|
+
host = req.endpoint.host
|
|
142
|
+
"unable to connect to `#{host}`; SocketError: #{error.message}"
|
|
143
|
+
else
|
|
144
|
+
error.message
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|