hearth 1.0.0.pre1 → 1.0.0.pre3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (176) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -4
  3. data/VERSION +1 -1
  4. data/lib/hearth/anonymous_auth_resolver.rb +11 -0
  5. data/lib/hearth/api_error.rb +15 -1
  6. data/lib/hearth/auth_option.rb +21 -0
  7. data/lib/hearth/auth_schemes/anonymous.rb +21 -0
  8. data/lib/hearth/auth_schemes/http_api_key.rb +16 -0
  9. data/lib/hearth/auth_schemes/http_basic.rb +16 -0
  10. data/lib/hearth/auth_schemes/http_bearer.rb +16 -0
  11. data/lib/hearth/auth_schemes/http_digest.rb +16 -0
  12. data/lib/hearth/auth_schemes.rb +32 -0
  13. data/lib/hearth/checksums.rb +31 -0
  14. data/lib/hearth/client.rb +66 -0
  15. data/lib/hearth/client_stubs.rb +128 -0
  16. data/lib/hearth/config/env_provider.rb +53 -0
  17. data/lib/hearth/config/resolver.rb +53 -0
  18. data/lib/hearth/configuration.rb +15 -0
  19. data/lib/hearth/connection_pool.rb +77 -0
  20. data/lib/hearth/context.rb +29 -4
  21. data/lib/hearth/dns/host_address.rb +27 -0
  22. data/lib/hearth/dns/host_resolver.rb +92 -0
  23. data/lib/hearth/dns.rb +48 -0
  24. data/lib/hearth/endpoint_rules.rb +154 -0
  25. data/lib/hearth/http/api_error.rb +4 -8
  26. data/lib/hearth/http/client.rb +206 -59
  27. data/lib/hearth/http/error_inspector.rb +85 -0
  28. data/lib/hearth/http/error_parser.rb +18 -20
  29. data/lib/hearth/http/field.rb +49 -0
  30. data/lib/hearth/http/fields.rb +117 -0
  31. data/lib/hearth/http/header_list_builder.rb +42 -0
  32. data/lib/hearth/http/header_list_parser.rb +92 -0
  33. data/lib/hearth/http/middleware/content_length.rb +7 -4
  34. data/lib/hearth/http/middleware/content_md5.rb +30 -0
  35. data/lib/hearth/http/middleware/request_compression.rb +154 -0
  36. data/lib/hearth/http/middleware.rb +12 -0
  37. data/lib/hearth/http/networking_error.rb +1 -14
  38. data/lib/hearth/http/request.rb +83 -56
  39. data/lib/hearth/http/response.rb +42 -13
  40. data/lib/hearth/http.rb +16 -5
  41. data/lib/hearth/identities/anonymous.rb +8 -0
  42. data/lib/hearth/identities/http_api_key.rb +16 -0
  43. data/lib/hearth/identities/http_bearer.rb +16 -0
  44. data/lib/hearth/identities/http_login.rb +20 -0
  45. data/lib/hearth/identities.rb +21 -0
  46. data/lib/hearth/identity_provider.rb +17 -0
  47. data/lib/hearth/interceptor.rb +506 -0
  48. data/lib/hearth/interceptor_context.rb +40 -0
  49. data/lib/hearth/interceptor_list.rb +48 -0
  50. data/lib/hearth/interceptors.rb +76 -0
  51. data/lib/hearth/json.rb +4 -4
  52. data/lib/hearth/middleware/auth.rb +103 -0
  53. data/lib/hearth/middleware/build.rb +32 -1
  54. data/lib/hearth/middleware/endpoint.rb +79 -0
  55. data/lib/hearth/middleware/host_prefix.rb +11 -8
  56. data/lib/hearth/middleware/initialize.rb +57 -0
  57. data/lib/hearth/middleware/parse.rb +45 -7
  58. data/lib/hearth/middleware/retry.rb +105 -24
  59. data/lib/hearth/middleware/send.rb +137 -26
  60. data/lib/hearth/middleware/sign.rb +65 -0
  61. data/lib/hearth/middleware/validate.rb +11 -1
  62. data/lib/hearth/middleware.rb +20 -8
  63. data/lib/hearth/middleware_stack.rb +2 -44
  64. data/lib/hearth/networking_error.rb +18 -0
  65. data/lib/hearth/number_helper.rb +3 -3
  66. data/lib/hearth/output.rb +8 -4
  67. data/lib/hearth/plugin_list.rb +53 -0
  68. data/lib/hearth/query/param.rb +56 -0
  69. data/lib/hearth/query/param_list.rb +54 -0
  70. data/lib/hearth/query/param_matcher.rb +31 -0
  71. data/lib/hearth/refreshing_identity_provider.rb +63 -0
  72. data/lib/hearth/request.rb +22 -0
  73. data/lib/hearth/response.rb +36 -0
  74. data/lib/hearth/retry/adaptive.rb +60 -0
  75. data/lib/hearth/retry/capacity_not_available_error.rb +9 -0
  76. data/lib/hearth/retry/client_rate_limiter.rb +145 -0
  77. data/lib/hearth/retry/exponential_backoff.rb +15 -0
  78. data/lib/hearth/retry/retry_quota.rb +56 -0
  79. data/lib/hearth/retry/standard.rb +46 -0
  80. data/lib/hearth/retry.rb +29 -0
  81. data/lib/hearth/signers/anonymous.rb +16 -0
  82. data/lib/hearth/signers/http_api_key.rb +29 -0
  83. data/lib/hearth/signers/http_basic.rb +23 -0
  84. data/lib/hearth/signers/http_bearer.rb +19 -0
  85. data/lib/hearth/signers/http_digest.rb +19 -0
  86. data/lib/hearth/signers.rb +23 -0
  87. data/lib/hearth/structure.rb +7 -3
  88. data/lib/hearth/stubs.rb +38 -0
  89. data/lib/hearth/time_helper.rb +6 -5
  90. data/lib/hearth/validator.rb +60 -5
  91. data/lib/hearth/waiters/poller.rb +10 -9
  92. data/lib/hearth/waiters/waiter.rb +23 -9
  93. data/lib/hearth/xml/formatter.rb +11 -2
  94. data/lib/hearth/xml/node.rb +2 -3
  95. data/lib/hearth/xml/node_matcher.rb +0 -1
  96. data/lib/hearth.rb +37 -6
  97. data/sig/lib/hearth/aliases.rbs +6 -0
  98. data/sig/lib/hearth/anonymous_auth_resolver.rbs +5 -0
  99. data/sig/lib/hearth/api_error.rbs +13 -0
  100. data/sig/lib/hearth/auth_option.rbs +11 -0
  101. data/sig/lib/hearth/auth_schemes/anonymous.rbs +7 -0
  102. data/sig/lib/hearth/auth_schemes/http_api_key.rbs +7 -0
  103. data/sig/lib/hearth/auth_schemes/http_basic.rbs +7 -0
  104. data/sig/lib/hearth/auth_schemes/http_bearer.rbs +7 -0
  105. data/sig/lib/hearth/auth_schemes/http_digest.rbs +7 -0
  106. data/sig/lib/hearth/auth_schemes.rbs +13 -0
  107. data/sig/lib/hearth/block_io.rbs +9 -0
  108. data/sig/lib/hearth/client.rbs +9 -0
  109. data/sig/lib/hearth/client_stubs.rbs +5 -0
  110. data/sig/lib/hearth/configuration.rbs +7 -0
  111. data/sig/lib/hearth/dns/host_address.rbs +11 -0
  112. data/sig/lib/hearth/dns/host_resolver.rbs +19 -0
  113. data/sig/lib/hearth/endpoint_rules.rbs +17 -0
  114. data/sig/lib/hearth/http/api_error.rbs +13 -0
  115. data/sig/lib/hearth/http/client.rbs +9 -0
  116. data/sig/lib/hearth/http/field.rbs +19 -0
  117. data/sig/lib/hearth/http/fields.rbs +43 -0
  118. data/sig/lib/hearth/http/header_list_builder.rbs +15 -0
  119. data/sig/lib/hearth/http/header_list_parser.rbs +19 -0
  120. data/sig/lib/hearth/http/networking_error.rbs +6 -0
  121. data/sig/lib/hearth/http/request.rbs +25 -0
  122. data/sig/lib/hearth/http/response.rbs +21 -0
  123. data/sig/lib/hearth/identities/anonymous.rbs +6 -0
  124. data/sig/lib/hearth/identities/http_api_key.rbs +9 -0
  125. data/sig/lib/hearth/identities/http_bearer.rbs +9 -0
  126. data/sig/lib/hearth/identities/http_login.rbs +11 -0
  127. data/sig/lib/hearth/identities.rbs +9 -0
  128. data/sig/lib/hearth/identity_provider.rbs +7 -0
  129. data/sig/lib/hearth/interceptor.rbs +9 -0
  130. data/sig/lib/hearth/interceptor_context.rbs +17 -0
  131. data/sig/lib/hearth/interceptor_list.rbs +16 -0
  132. data/sig/lib/hearth/interfaces.rbs +87 -0
  133. data/sig/lib/hearth/json/parse_error.rbs +9 -0
  134. data/sig/lib/hearth/networking_error.rbs +7 -0
  135. data/sig/lib/hearth/output.rbs +11 -0
  136. data/sig/lib/hearth/plugin_list.rbs +13 -0
  137. data/sig/lib/hearth/query/param.rbs +17 -0
  138. data/sig/lib/hearth/query/param_list.rbs +25 -0
  139. data/sig/lib/hearth/refreshing_identity_provider.rbs +10 -0
  140. data/sig/lib/hearth/request.rbs +9 -0
  141. data/sig/lib/hearth/response.rbs +11 -0
  142. data/sig/lib/hearth/retry/adaptive.rbs +13 -0
  143. data/sig/lib/hearth/retry/exponential_backoff.rbs +7 -0
  144. data/sig/lib/hearth/retry/standard.rbs +13 -0
  145. data/sig/lib/hearth/retry/strategy.rbs +11 -0
  146. data/sig/lib/hearth/retry.rbs +9 -0
  147. data/sig/lib/hearth/signers/anonymous.rbs +9 -0
  148. data/sig/lib/hearth/signers/http_api_key.rbs +9 -0
  149. data/sig/lib/hearth/signers/http_basic.rbs +9 -0
  150. data/sig/lib/hearth/signers/http_bearer.rbs +9 -0
  151. data/sig/lib/hearth/signers/http_digest.rbs +9 -0
  152. data/sig/lib/hearth/signers.rbs +9 -0
  153. data/sig/lib/hearth/structure.rbs +6 -0
  154. data/sig/lib/hearth/stubs.rbs +9 -0
  155. data/sig/lib/hearth/union.rbs +5 -0
  156. data/sig/lib/hearth/waiters/waiter.rbs +17 -0
  157. data/sig/lib/hearth/xml/parse_error.rbs +9 -0
  158. metadata +151 -25
  159. data/lib/hearth/http/headers.rb +0 -70
  160. data/lib/hearth/middleware/around_handler.rb +0 -24
  161. data/lib/hearth/middleware/request_handler.rb +0 -24
  162. data/lib/hearth/middleware/response_handler.rb +0 -25
  163. data/lib/hearth/middleware_builder.rb +0 -246
  164. data/lib/hearth/stubbing/client_stubs.rb +0 -115
  165. data/lib/hearth/stubbing/stubs.rb +0 -32
  166. data/lib/hearth/waiters/errors.rb +0 -15
  167. data/sig/lib/seahorse/api_error.rbs +0 -10
  168. data/sig/lib/seahorse/document.rbs +0 -2
  169. data/sig/lib/seahorse/http/api_error.rbs +0 -21
  170. data/sig/lib/seahorse/http/headers.rbs +0 -47
  171. data/sig/lib/seahorse/http/response.rbs +0 -21
  172. data/sig/lib/seahorse/simple_delegator.rbs +0 -3
  173. data/sig/lib/seahorse/structure.rbs +0 -18
  174. data/sig/lib/seahorse/stubbing/client_stubs.rbs +0 -103
  175. data/sig/lib/seahorse/stubbing/stubs.rbs +0 -14
  176. data/sig/lib/seahorse/union.rbs +0 -6
@@ -1,19 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'securerandom'
4
+
3
5
  module Hearth
4
6
  # Stores request and response objects, and other useful things used by
5
7
  # multiple Middleware.
8
+ # @api private
6
9
  class Context
7
10
  def initialize(options = {})
11
+ @invocation_id = SecureRandom.uuid
8
12
  @operation_name = options[:operation_name]
9
13
  @request = options[:request]
10
14
  @response = options[:response]
11
15
  @logger = options[:logger]
12
- @params = options[:params]
16
+ @interceptors = options[:interceptors] || InterceptorList.new
17
+ @auth = options[:auth]
13
18
  @metadata = options[:metadata] || {}
14
19
  end
15
20
 
16
- # @return [Symbol] Name of the API operation called.
21
+ # @return [String] The invocation ID for the request.
22
+ attr_reader :invocation_id
23
+
24
+ # @return [Symbol] The name of the API operation called.
17
25
  attr_reader :operation_name
18
26
 
19
27
  # @return [Hearth::HTTP::Request]
@@ -25,10 +33,27 @@ module Hearth
25
33
  # @return [Logger] An instance of the logger configured for the Client.
26
34
  attr_reader :logger
27
35
 
28
- # @return [Hash] The hash of the original request parameters.
29
- attr_reader :params
36
+ # @return [Array] An ordered list of interceptors
37
+ attr_reader :interceptors
38
+
39
+ # @return [ResolvedAuth, nil] The resolved auth for the request.
40
+ attr_accessor :auth
30
41
 
31
42
  # @return [Hash]
32
43
  attr_reader :metadata
44
+
45
+ # Returns the metadata for the given `key`.
46
+ # @param [Symbol] key
47
+ # @return [Object]
48
+ def [](key)
49
+ @metadata[key]
50
+ end
51
+
52
+ # Sets metadata for the given `key`.
53
+ # @param [Symbol] key
54
+ # @param [Object] value
55
+ def []=(key, value)
56
+ @metadata[key] = value
57
+ end
33
58
  end
34
59
  end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hearth
4
+ module DNS
5
+ # Address results from a DNS lookup in {HostResolver}.
6
+ # @!method initialize(*args)
7
+ # @option args [Symbol] :address_type The type of address. For example,
8
+ # :A or :AAAA.
9
+ # @option args [String] :address The IP address.
10
+ # @option args [String] :hostname The hostname that was resolved.
11
+ # @!attribute address_type
12
+ # The type of address. For example, :A or :AAAA.
13
+ # @return [Symbol]
14
+ # @!attribute address
15
+ # The IP address.
16
+ # @return [String]
17
+ # @!attribute hostname
18
+ # The hostname that was resolved.
19
+ # @return [String]
20
+ HostAddress = Struct.new(
21
+ :address_type,
22
+ :address,
23
+ :hostname,
24
+ keyword_init: true
25
+ )
26
+ end
27
+ end
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hearth
4
+ module DNS
5
+ # Resolves a host name and service to an IP address. Can be used with the
6
+ # {HTTP::Client} host_resolver option. This implementation uses
7
+ # Addrinfo.getaddrinfo to resolve the host name.
8
+ #
9
+ # @see https://ruby-doc.org/stdlib-3.0.2/libdoc/socket/rdoc/Addrinfo.html
10
+ class HostResolver
11
+ # @param [Integer] service (443)
12
+ # @param [Integer] family (nil)
13
+ # @param [Symbol] socktype (:SOCK_STREAM)
14
+ # @param [Integer] protocol (nil)
15
+ # @param [Integer] flags (nil)
16
+ def initialize(service: 443, family: nil, socktype: :SOCK_STREAM,
17
+ protocol: nil, flags: nil)
18
+ @service = service
19
+ @family = family
20
+ @socktype = socktype
21
+ @protocol = protocol
22
+ @flags = flags
23
+ end
24
+
25
+ # @return [Integer]
26
+ attr_reader :service
27
+
28
+ # @return [Integer]
29
+ attr_reader :family
30
+
31
+ # @return [Symbol]
32
+ attr_reader :socktype
33
+
34
+ # @return [Integer]
35
+ attr_reader :protocol
36
+
37
+ # @return [Integer]
38
+ attr_reader :flags
39
+
40
+ # @param [String] nodename
41
+ # @param (see Hearth::DNS::HostResolver#initialize)
42
+ def resolve_address(nodename:, **kwargs)
43
+ options = kwargs.merge(nodename: nodename)
44
+ addrinfo_list = addrinfo(options)
45
+ ipv6 = ipv6_addr(addrinfo_list, options) if use_ipv6?
46
+ ipv4 = ipv4_addr(addrinfo_list, options)
47
+ [ipv6, ipv4]
48
+ end
49
+
50
+ private
51
+
52
+ def addrinfo(options)
53
+ Addrinfo.getaddrinfo(
54
+ options[:nodename],
55
+ options.fetch(:service, @service),
56
+ options.fetch(:family, @family),
57
+ options.fetch(:socktype, @socktype),
58
+ options.fetch(:protocol, @protocol),
59
+ options.fetch(:flags, @flags)
60
+ )
61
+ end
62
+
63
+ def ipv4_addr(addrinfo_list, options)
64
+ addr = addrinfo_list.find(&:ipv4?)
65
+ return unless addr
66
+
67
+ HostAddress.new(
68
+ address_type: :A,
69
+ address: addr.ip_address,
70
+ hostname: options[:nodename]
71
+ )
72
+ end
73
+
74
+ def ipv6_addr(addrinfo_list, options)
75
+ addr = addrinfo_list.find(&:ipv6?)
76
+ return unless addr
77
+
78
+ HostAddress.new(
79
+ address_type: :AAAA,
80
+ address: addr.ip_address,
81
+ hostname: options[:nodename]
82
+ )
83
+ end
84
+
85
+ def use_ipv6?
86
+ Socket.ip_address_list.any? do |a|
87
+ a.ipv6? && !a.ipv6_loopback? && !a.ipv6_linklocal?
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
data/lib/hearth/dns.rb ADDED
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'socket'
4
+
5
+ require_relative 'dns/host_address'
6
+ require_relative 'dns/host_resolver'
7
+
8
+ # These patches are based on resolv-replace
9
+ # https://github.com/ruby/ruby/blob/master/lib/resolv-replace.rb
10
+ # We cannot require resolv-replace because it would change DNS resolution
11
+ # globally. When opening an HTTP request, we will set a thread local variable
12
+ # to enable custom DNS resolution, and then disable it after the request is
13
+ # complete. When the thread local variable is not set, we will use the default
14
+ # Ruby DNS resolution, which may be Resolv or the system resolver.
15
+
16
+ # Patch IPSocket
17
+ # @api private
18
+ class << IPSocket
19
+ alias original_hearth_getaddress getaddress
20
+
21
+ def getaddress(host)
22
+ unless (resolver = Thread.current[:net_http_hearth_dns_resolver])
23
+ return original_hearth_getaddress(host)
24
+ end
25
+
26
+ ipv6, ipv4 = resolver.resolve_address(nodename: host)
27
+ return ipv6.address if ipv6
28
+
29
+ ipv4.address
30
+ end
31
+ end
32
+
33
+ # Patch TCPSocket
34
+ # @api private
35
+ class TCPSocket < IPSocket
36
+ alias original_hearth_initialize initialize
37
+
38
+ # rubocop:disable Lint/MissingSuper
39
+ def initialize(host, serv, *rest)
40
+ if Thread.current[:net_http_hearth_dns_resolver]
41
+ rest[0] = IPSocket.getaddress(rest[0]) if rest[0]
42
+ original_hearth_initialize(IPSocket.getaddress(host), serv, *rest)
43
+ else
44
+ original_hearth_initialize(host, serv, *rest)
45
+ end
46
+ end
47
+ # rubocop:enable Lint/MissingSuper
48
+ end
@@ -0,0 +1,154 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cgi'
4
+ require 'ipaddr'
5
+ require 'uri'
6
+
7
+ module Hearth
8
+ # Functions in the Smithy rules engine are named routines that
9
+ # operate on a finite set of specified inputs, returning an output.
10
+ # The rules engine has a set of included functions that can be
11
+ # invoked without additional dependencies, called the standard library.
12
+ module EndpointRules
13
+ # An Authentication Scheme supported by an Endpoint
14
+ # @!attribute scheme_id
15
+ # The identifier of the authentication scheme.
16
+ # @return [String]
17
+ # @!attribute properties
18
+ # Additional properties of the authentication scheme.
19
+ # @return [Hash]
20
+ AuthScheme = Struct.new(
21
+ :scheme_id,
22
+ :properties,
23
+ keyword_init: true
24
+ ) do
25
+ # @option args [String] :scheme_id
26
+ # @option args [Hash] :properties ({})
27
+ def initialize(*args)
28
+ super
29
+ self.properties ||= {}
30
+ end
31
+ end
32
+
33
+ # An Endpoint resolved by an EndpointProvider
34
+ # @!attribute uri
35
+ # The URI of the endpoint.
36
+ # @return [String]
37
+ # @!attribute auth_schemes
38
+ # The authentication schemes supported by the endpoint.
39
+ # @return [Array<AuthScheme>]
40
+ # @!attribute headers
41
+ # The headers to include in requests to the endpoint.
42
+ # @return [Hash]
43
+ Endpoint = Struct.new(
44
+ :uri,
45
+ :auth_schemes,
46
+ :headers,
47
+ keyword_init: true
48
+ ) do
49
+ # @option args [String] :uri
50
+ # @option args [Array<AuthScheme>] :auth_schemes ([])
51
+ # @option args [Hash] :headers ({})
52
+ def initialize(*args)
53
+ super
54
+ self.auth_schemes ||= []
55
+ self.headers ||= {}
56
+ end
57
+ end
58
+
59
+ # Evaluates whether the input string is a compliant RFC 1123 host segment.
60
+ # When allowSubDomains is true, evaluates whether the input string is
61
+ # composed of values that are each compliant RFC 1123 host segments
62
+ # joined by dot (.) characters.
63
+ # @api private
64
+ # rubocop:disable Style/OptionalBooleanParameter
65
+ def self.valid_host_label?(value, allow_sub_domains = false)
66
+ return false if value.empty?
67
+
68
+ if allow_sub_domains
69
+ labels = value.split('.', -1)
70
+ return labels.all? { |l| valid_host_label?(l, false) }
71
+ end
72
+
73
+ !!(value =~ /\A(?!-)[a-zA-Z0-9-]{1,63}(?<!-)\z/)
74
+ end
75
+ # rubocop:enable Style/OptionalBooleanParameter
76
+
77
+ # Computes a URL structure given an input string.
78
+ # @api private
79
+ def self.parse_url(value)
80
+ URL.new(value).as_json
81
+ rescue ArgumentError, URI::InvalidURIError
82
+ nil
83
+ end
84
+
85
+ # Computes a portion of a given string based on
86
+ # the provided start and end indices.
87
+ # @api private
88
+ def self.substring(input, start, stop, reverse)
89
+ return nil if start >= stop || input.size < stop
90
+
91
+ return nil if input.chars.any? { |c| c.ord > 127 }
92
+
93
+ return input[start...stop] unless reverse
94
+
95
+ r_start = input.size - stop
96
+ r_stop = input.size - start
97
+ input[r_start...r_stop]
98
+ end
99
+
100
+ # Performs RFC 3986#section-2.1 defined percent-encoding on the input value.
101
+ # @api private
102
+ def self.uri_encode(value)
103
+ CGI.escape(value.encode('UTF-8')).gsub('+', '%20').gsub('%7E', '~')
104
+ end
105
+
106
+ # @api private
107
+ class URL
108
+ def initialize(url)
109
+ uri = URI(url)
110
+ @scheme = uri.scheme
111
+ # only support http and https schemes
112
+ raise ArgumentError unless %w[https http].include?(@scheme)
113
+
114
+ # do not support query
115
+ raise ArgumentError if uri.query
116
+
117
+ @authority = _authority(url, uri)
118
+ @path = uri.path
119
+ @normalized_path = uri.path + (uri.path[-1] == '/' ? '' : '/')
120
+ @is_ip = _is_ip(uri.host)
121
+ end
122
+
123
+ attr_reader :scheme, :authority, :path, :normalized_path, :is_ip
124
+
125
+ def as_json(_options = {})
126
+ {
127
+ 'scheme' => scheme,
128
+ 'authority' => authority,
129
+ 'path' => path,
130
+ 'normalizedPath' => normalized_path,
131
+ 'isIp' => is_ip
132
+ }
133
+ end
134
+
135
+ private
136
+
137
+ def _authority(url, uri)
138
+ # don't include port if it's default and not parsed originally
139
+ if uri.default_port == uri.port && !url.include?(":#{uri.port}")
140
+ uri.host
141
+ else
142
+ "#{uri.host}:#{uri.port}"
143
+ end
144
+ end
145
+
146
+ def _is_ip(authority)
147
+ IPAddr.new(authority)
148
+ true
149
+ rescue IPAddr::InvalidAddressError
150
+ false
151
+ end
152
+ end
153
+ end
154
+ end
@@ -7,23 +7,19 @@ module Hearth
7
7
  class ApiError < Hearth::ApiError
8
8
  def initialize(http_resp:, **kwargs)
9
9
  @http_status = http_resp.status
10
- @http_headers = http_resp.headers
10
+ @http_fields = http_resp.fields
11
11
  @http_body = http_resp.body
12
- @request_id = http_resp.headers['x-request-id']
13
12
  super(**kwargs)
14
13
  end
15
14
 
16
15
  # @return [Integer]
17
16
  attr_reader :http_status
18
17
 
19
- # @return [Hash<String, String>]
20
- attr_reader :http_headers
18
+ # @return [Fields]
19
+ attr_reader :http_fields
21
20
 
22
- # @return [String]
21
+ # @return [IO]
23
22
  attr_reader :http_body
24
-
25
- # @return [String]
26
- attr_reader :request_id
27
23
  end
28
24
  end
29
25
  end