aws-sdk-core 3.0.0 → 3.129.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (209) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +1287 -0
  3. data/LICENSE.txt +202 -0
  4. data/VERSION +1 -1
  5. data/ca-bundle.crt +3615 -3541
  6. data/lib/aws-defaults/default_configuration.rb +153 -0
  7. data/lib/aws-defaults/defaults_mode_config_resolver.rb +107 -0
  8. data/lib/aws-defaults.rb +3 -0
  9. data/lib/aws-sdk-core/arn.rb +92 -0
  10. data/lib/aws-sdk-core/arn_parser.rb +40 -0
  11. data/lib/aws-sdk-core/assume_role_credentials.rb +20 -0
  12. data/lib/aws-sdk-core/assume_role_web_identity_credentials.rb +109 -0
  13. data/lib/aws-sdk-core/async_client_stubs.rb +82 -0
  14. data/lib/aws-sdk-core/binary/decode_handler.rb +58 -0
  15. data/lib/aws-sdk-core/binary/encode_handler.rb +34 -0
  16. data/lib/aws-sdk-core/binary/event_builder.rb +124 -0
  17. data/lib/aws-sdk-core/binary/event_parser.rb +136 -0
  18. data/lib/aws-sdk-core/binary/event_stream_decoder.rb +64 -0
  19. data/lib/aws-sdk-core/binary/event_stream_encoder.rb +55 -0
  20. data/lib/aws-sdk-core/binary.rb +8 -0
  21. data/lib/aws-sdk-core/client_side_monitoring/publisher.rb +51 -0
  22. data/lib/aws-sdk-core/client_side_monitoring/request_metrics.rb +199 -0
  23. data/lib/aws-sdk-core/client_stubs.rb +55 -10
  24. data/lib/aws-sdk-core/credential_provider.rb +1 -30
  25. data/lib/aws-sdk-core/credential_provider_chain.rb +111 -33
  26. data/lib/aws-sdk-core/credentials.rb +2 -0
  27. data/lib/aws-sdk-core/deprecations.rb +17 -11
  28. data/lib/aws-sdk-core/eager_loader.rb +2 -0
  29. data/lib/aws-sdk-core/ec2_metadata.rb +238 -0
  30. data/lib/aws-sdk-core/ecs_credentials.rb +20 -11
  31. data/lib/aws-sdk-core/endpoint_cache.rb +193 -0
  32. data/lib/aws-sdk-core/errors.rb +210 -12
  33. data/lib/aws-sdk-core/event_emitter.rb +64 -0
  34. data/lib/aws-sdk-core/ini_parser.rb +2 -0
  35. data/lib/aws-sdk-core/instance_profile_credentials.rb +237 -45
  36. data/lib/aws-sdk-core/json/builder.rb +6 -2
  37. data/lib/aws-sdk-core/json/error_handler.rb +21 -2
  38. data/lib/aws-sdk-core/json/handler.rb +21 -1
  39. data/lib/aws-sdk-core/json/json_engine.rb +12 -8
  40. data/lib/aws-sdk-core/json/oj_engine.rb +35 -6
  41. data/lib/aws-sdk-core/json/parser.rb +10 -0
  42. data/lib/aws-sdk-core/json.rb +11 -28
  43. data/lib/aws-sdk-core/log/formatter.rb +16 -4
  44. data/lib/aws-sdk-core/log/handler.rb +2 -0
  45. data/lib/aws-sdk-core/log/param_filter.rb +38 -13
  46. data/lib/aws-sdk-core/log/param_formatter.rb +2 -0
  47. data/lib/aws-sdk-core/pageable_response.rb +111 -47
  48. data/lib/aws-sdk-core/pager.rb +5 -0
  49. data/lib/aws-sdk-core/param_converter.rb +2 -0
  50. data/lib/aws-sdk-core/param_validator.rb +99 -22
  51. data/lib/aws-sdk-core/plugins/api_key.rb +56 -0
  52. data/lib/aws-sdk-core/plugins/apig_authorizer_token.rb +32 -0
  53. data/lib/aws-sdk-core/plugins/apig_credentials_configuration.rb +36 -0
  54. data/lib/aws-sdk-core/plugins/apig_user_agent.rb +39 -0
  55. data/lib/aws-sdk-core/plugins/checksum_algorithm.rb +340 -0
  56. data/lib/aws-sdk-core/plugins/client_metrics_plugin.rb +283 -0
  57. data/lib/aws-sdk-core/plugins/client_metrics_send_plugin.rb +86 -0
  58. data/lib/aws-sdk-core/plugins/credentials_configuration.rb +26 -7
  59. data/lib/aws-sdk-core/plugins/defaults_mode.rb +40 -0
  60. data/lib/aws-sdk-core/plugins/endpoint_discovery.rb +168 -0
  61. data/lib/aws-sdk-core/plugins/endpoint_pattern.rb +65 -0
  62. data/lib/aws-sdk-core/plugins/event_stream_configuration.rb +32 -0
  63. data/lib/aws-sdk-core/plugins/global_configuration.rb +2 -0
  64. data/lib/aws-sdk-core/plugins/helpful_socket_errors.rb +2 -0
  65. data/lib/aws-sdk-core/plugins/http_checksum.rb +64 -0
  66. data/lib/aws-sdk-core/plugins/idempotency_token.rb +2 -0
  67. data/lib/aws-sdk-core/plugins/invocation_id.rb +35 -0
  68. data/lib/aws-sdk-core/plugins/jsonvalue_converter.rb +2 -0
  69. data/lib/aws-sdk-core/plugins/logging.rb +2 -0
  70. data/lib/aws-sdk-core/plugins/param_converter.rb +2 -0
  71. data/lib/aws-sdk-core/plugins/param_validator.rb +2 -0
  72. data/lib/aws-sdk-core/plugins/protocols/api_gateway.rb +29 -0
  73. data/lib/aws-sdk-core/plugins/protocols/ec2.rb +2 -0
  74. data/lib/aws-sdk-core/plugins/protocols/json_rpc.rb +2 -0
  75. data/lib/aws-sdk-core/plugins/protocols/query.rb +2 -0
  76. data/lib/aws-sdk-core/plugins/protocols/rest_json.rb +18 -1
  77. data/lib/aws-sdk-core/plugins/protocols/rest_xml.rb +2 -0
  78. data/lib/aws-sdk-core/plugins/recursion_detection.rb +27 -0
  79. data/lib/aws-sdk-core/plugins/regional_endpoint.rb +76 -16
  80. data/lib/aws-sdk-core/plugins/response_paging.rb +3 -1
  81. data/lib/aws-sdk-core/plugins/retries/client_rate_limiter.rb +139 -0
  82. data/lib/aws-sdk-core/plugins/retries/clock_skew.rb +100 -0
  83. data/lib/aws-sdk-core/plugins/retries/error_inspector.rb +146 -0
  84. data/lib/aws-sdk-core/plugins/retries/retry_quota.rb +59 -0
  85. data/lib/aws-sdk-core/plugins/retry_errors.rb +334 -78
  86. data/lib/aws-sdk-core/plugins/signature_v2.rb +2 -0
  87. data/lib/aws-sdk-core/plugins/signature_v4.rb +33 -28
  88. data/lib/aws-sdk-core/plugins/stub_responses.rb +31 -7
  89. data/lib/aws-sdk-core/plugins/transfer_encoding.rb +53 -0
  90. data/lib/aws-sdk-core/plugins/user_agent.rb +9 -5
  91. data/lib/aws-sdk-core/process_credentials.rb +81 -0
  92. data/lib/aws-sdk-core/query/ec2_param_builder.rb +11 -3
  93. data/lib/aws-sdk-core/query/handler.rb +8 -1
  94. data/lib/aws-sdk-core/query/param.rb +2 -0
  95. data/lib/aws-sdk-core/query/param_builder.rb +11 -3
  96. data/lib/aws-sdk-core/query/param_list.rb +2 -0
  97. data/lib/aws-sdk-core/query.rb +2 -0
  98. data/lib/aws-sdk-core/refreshing_credentials.rb +16 -3
  99. data/lib/aws-sdk-core/resources/collection.rb +7 -5
  100. data/lib/aws-sdk-core/rest/handler.rb +2 -0
  101. data/lib/aws-sdk-core/rest/request/body.rb +21 -1
  102. data/lib/aws-sdk-core/rest/request/builder.rb +4 -1
  103. data/lib/aws-sdk-core/rest/request/endpoint.rb +13 -6
  104. data/lib/aws-sdk-core/rest/request/headers.rb +30 -6
  105. data/lib/aws-sdk-core/rest/request/querystring_builder.rb +17 -2
  106. data/lib/aws-sdk-core/rest/response/body.rb +16 -1
  107. data/lib/aws-sdk-core/rest/response/headers.rb +8 -3
  108. data/lib/aws-sdk-core/rest/response/parser.rb +7 -1
  109. data/lib/aws-sdk-core/rest/response/status_code.rb +2 -0
  110. data/lib/aws-sdk-core/rest.rb +2 -0
  111. data/lib/aws-sdk-core/shared_config.rb +204 -68
  112. data/lib/aws-sdk-core/shared_credentials.rb +9 -1
  113. data/lib/aws-sdk-core/sso_credentials.rb +136 -0
  114. data/lib/aws-sdk-core/structure.rb +18 -3
  115. data/lib/aws-sdk-core/stubbing/data_applicator.rb +2 -0
  116. data/lib/aws-sdk-core/stubbing/empty_stub.rb +6 -1
  117. data/lib/aws-sdk-core/stubbing/protocols/api_gateway.rb +10 -0
  118. data/lib/aws-sdk-core/stubbing/protocols/ec2.rb +2 -0
  119. data/lib/aws-sdk-core/stubbing/protocols/json.rb +3 -1
  120. data/lib/aws-sdk-core/stubbing/protocols/query.rb +4 -2
  121. data/lib/aws-sdk-core/stubbing/protocols/rest.rb +120 -2
  122. data/lib/aws-sdk-core/stubbing/protocols/rest_json.rb +8 -2
  123. data/lib/aws-sdk-core/stubbing/protocols/rest_xml.rb +11 -7
  124. data/lib/aws-sdk-core/stubbing/stub_data.rb +15 -4
  125. data/lib/aws-sdk-core/stubbing/xml_error.rb +2 -0
  126. data/lib/aws-sdk-core/type_builder.rb +2 -0
  127. data/lib/aws-sdk-core/util.rb +34 -1
  128. data/lib/aws-sdk-core/waiters/errors.rb +2 -0
  129. data/lib/aws-sdk-core/waiters/poller.rb +2 -0
  130. data/lib/aws-sdk-core/waiters/waiter.rb +4 -2
  131. data/lib/aws-sdk-core/waiters.rb +2 -0
  132. data/lib/aws-sdk-core/xml/builder.rb +14 -6
  133. data/lib/aws-sdk-core/xml/default_list.rb +2 -0
  134. data/lib/aws-sdk-core/xml/default_map.rb +2 -0
  135. data/lib/aws-sdk-core/xml/doc_builder.rb +15 -4
  136. data/lib/aws-sdk-core/xml/error_handler.rb +29 -4
  137. data/lib/aws-sdk-core/xml/parser/engines/libxml.rb +2 -0
  138. data/lib/aws-sdk-core/xml/parser/engines/nokogiri.rb +2 -0
  139. data/lib/aws-sdk-core/xml/parser/engines/oga.rb +2 -0
  140. data/lib/aws-sdk-core/xml/parser/engines/ox.rb +3 -1
  141. data/lib/aws-sdk-core/xml/parser/engines/rexml.rb +4 -1
  142. data/lib/aws-sdk-core/xml/parser/frame.rb +30 -5
  143. data/lib/aws-sdk-core/xml/parser/parsing_error.rb +2 -0
  144. data/lib/aws-sdk-core/xml/parser/stack.rb +2 -0
  145. data/lib/aws-sdk-core/xml/parser.rb +7 -0
  146. data/lib/aws-sdk-core/xml.rb +2 -0
  147. data/lib/aws-sdk-core.rb +39 -5
  148. data/lib/aws-sdk-sso/client.rb +570 -0
  149. data/lib/aws-sdk-sso/client_api.rb +190 -0
  150. data/lib/aws-sdk-sso/customizations.rb +1 -0
  151. data/lib/aws-sdk-sso/errors.rb +102 -0
  152. data/lib/aws-sdk-sso/resource.rb +26 -0
  153. data/lib/aws-sdk-sso/types.rb +352 -0
  154. data/lib/aws-sdk-sso.rb +55 -0
  155. data/lib/aws-sdk-sts/client.rb +1474 -598
  156. data/lib/aws-sdk-sts/client_api.rb +81 -1
  157. data/lib/aws-sdk-sts/customizations.rb +4 -0
  158. data/lib/aws-sdk-sts/errors.rb +153 -1
  159. data/lib/aws-sdk-sts/plugins/sts_regional_endpoints.rb +38 -0
  160. data/lib/aws-sdk-sts/presigner.rb +75 -0
  161. data/lib/aws-sdk-sts/resource.rb +4 -1
  162. data/lib/aws-sdk-sts/types.rb +1005 -251
  163. data/lib/aws-sdk-sts.rb +16 -6
  164. data/lib/seahorse/client/async_base.rb +52 -0
  165. data/lib/seahorse/client/async_response.rb +64 -0
  166. data/lib/seahorse/client/base.rb +7 -2
  167. data/lib/seahorse/client/block_io.rb +6 -2
  168. data/lib/seahorse/client/configuration.rb +16 -2
  169. data/lib/seahorse/client/events.rb +3 -1
  170. data/lib/seahorse/client/h2/connection.rb +250 -0
  171. data/lib/seahorse/client/h2/handler.rb +152 -0
  172. data/lib/seahorse/client/handler.rb +2 -0
  173. data/lib/seahorse/client/handler_builder.rb +2 -0
  174. data/lib/seahorse/client/handler_list.rb +2 -0
  175. data/lib/seahorse/client/handler_list_entry.rb +6 -4
  176. data/lib/seahorse/client/http/async_response.rb +44 -0
  177. data/lib/seahorse/client/http/headers.rb +2 -0
  178. data/lib/seahorse/client/http/request.rb +5 -3
  179. data/lib/seahorse/client/http/response.rb +18 -11
  180. data/lib/seahorse/client/logging/formatter.rb +6 -2
  181. data/lib/seahorse/client/logging/handler.rb +2 -0
  182. data/lib/seahorse/client/managed_file.rb +2 -0
  183. data/lib/seahorse/client/net_http/connection_pool.rb +43 -27
  184. data/lib/seahorse/client/net_http/handler.rb +27 -7
  185. data/lib/seahorse/client/net_http/patches.rb +17 -79
  186. data/lib/seahorse/client/networking_error.rb +30 -0
  187. data/lib/seahorse/client/plugin.rb +10 -7
  188. data/lib/seahorse/client/plugin_list.rb +2 -0
  189. data/lib/seahorse/client/plugins/content_length.rb +14 -3
  190. data/lib/seahorse/client/plugins/endpoint.rb +4 -2
  191. data/lib/seahorse/client/plugins/h2.rb +69 -0
  192. data/lib/seahorse/client/plugins/logging.rb +2 -0
  193. data/lib/seahorse/client/plugins/net_http.rb +39 -3
  194. data/lib/seahorse/client/plugins/operation_methods.rb +2 -0
  195. data/lib/seahorse/client/plugins/raise_response_errors.rb +2 -0
  196. data/lib/seahorse/client/plugins/request_callback.rb +110 -0
  197. data/lib/seahorse/client/plugins/response_target.rb +26 -10
  198. data/lib/seahorse/client/request.rb +2 -0
  199. data/lib/seahorse/client/request_context.rb +7 -0
  200. data/lib/seahorse/client/response.rb +5 -5
  201. data/lib/seahorse/model/api.rb +39 -0
  202. data/lib/seahorse/model/authorizer.rb +23 -0
  203. data/lib/seahorse/model/operation.rb +28 -0
  204. data/lib/seahorse/model/shapes.rb +53 -0
  205. data/lib/seahorse/util.rb +9 -2
  206. data/lib/seahorse/version.rb +2 -0
  207. data/lib/seahorse.rb +13 -0
  208. metadata +99 -12
  209. data/lib/aws-sdk-core/version.rb +0 -3
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/master/CONTRIBUTING.md
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 all
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 service API errors
45
+ # # rescues all AWS Security Token Service API errors
36
46
  # end
37
47
  #
38
48
  # See {Errors} for more information.
39
49
  #
40
- # @service
50
+ # @!group service
41
51
  module Aws::STS
42
52
 
43
- GEM_VERSION = '3.0.0.rc20'
53
+ GEM_VERSION = '3.129.1'
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
@@ -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(method_name) do |*args, &block|
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(Proc.new) if block_given?
109
+ default = DynamicDefault.new(block) if block_given?
108
110
  @defaults[name.to_sym] << default
109
111
  self
110
112
  end
@@ -193,11 +195,23 @@ 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)
199
205
  value = @struct[opt_name]
200
- value.is_a?(Defaults) ? resolve_defaults(opt_name, value) : value
206
+ if value.is_a?(Defaults)
207
+ # this config value is used by endpoint discovery
208
+ if opt_name == :endpoint && @struct.members.include?(:regional_endpoint)
209
+ @struct[:regional_endpoint] = true
210
+ end
211
+ resolve_defaults(opt_name, value)
212
+ else
213
+ value
214
+ end
201
215
  end
202
216
 
203
217
  def resolve_defaults(opt_name, defaults)
@@ -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] << Proc.new
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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Seahorse
2
4
  module Client
3
5
  class Handler
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Seahorse
2
4
  module Client
3
5