httpx 0.17.0 → 0.18.0

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.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/doc/release_notes/0_18_0.md +69 -0
  3. data/lib/httpx/adapters/datadog.rb +1 -1
  4. data/lib/httpx/adapters/faraday.rb +5 -3
  5. data/lib/httpx/adapters/webmock.rb +7 -1
  6. data/lib/httpx/altsvc.rb +2 -2
  7. data/lib/httpx/chainable.rb +3 -3
  8. data/lib/httpx/connection/http1.rb +3 -3
  9. data/lib/httpx/connection/http2.rb +6 -4
  10. data/lib/httpx/connection.rb +67 -70
  11. data/lib/httpx/domain_name.rb +1 -1
  12. data/lib/httpx/extensions.rb +50 -4
  13. data/lib/httpx/io/ssl.rb +1 -1
  14. data/lib/httpx/io/tls.rb +7 -7
  15. data/lib/httpx/loggable.rb +5 -5
  16. data/lib/httpx/options.rb +7 -7
  17. data/lib/httpx/plugins/aws_sdk_authentication.rb +42 -18
  18. data/lib/httpx/plugins/aws_sigv4.rb +9 -11
  19. data/lib/httpx/plugins/compression.rb +5 -3
  20. data/lib/httpx/plugins/cookies/jar.rb +1 -1
  21. data/lib/httpx/plugins/expect.rb +7 -3
  22. data/lib/httpx/plugins/grpc/message.rb +2 -2
  23. data/lib/httpx/plugins/grpc.rb +3 -3
  24. data/lib/httpx/plugins/internal_telemetry.rb +8 -8
  25. data/lib/httpx/plugins/multipart.rb +2 -2
  26. data/lib/httpx/plugins/response_cache/store.rb +55 -0
  27. data/lib/httpx/plugins/response_cache.rb +88 -0
  28. data/lib/httpx/plugins/retries.rb +22 -3
  29. data/lib/httpx/plugins/stream.rb +1 -1
  30. data/lib/httpx/pool.rb +39 -13
  31. data/lib/httpx/request.rb +6 -6
  32. data/lib/httpx/resolver/https.rb +5 -7
  33. data/lib/httpx/resolver/native.rb +4 -2
  34. data/lib/httpx/resolver/system.rb +2 -0
  35. data/lib/httpx/resolver.rb +2 -2
  36. data/lib/httpx/response.rb +23 -14
  37. data/lib/httpx/selector.rb +5 -17
  38. data/lib/httpx/session.rb +7 -2
  39. data/lib/httpx/session2.rb +1 -1
  40. data/lib/httpx/timers.rb +84 -0
  41. data/lib/httpx/transcoder/body.rb +2 -1
  42. data/lib/httpx/transcoder/form.rb +1 -1
  43. data/lib/httpx/transcoder/json.rb +1 -1
  44. data/lib/httpx/utils.rb +8 -0
  45. data/lib/httpx/version.rb +1 -1
  46. data/lib/httpx.rb +1 -0
  47. data/sig/chainable.rbs +1 -0
  48. data/sig/connection.rbs +12 -6
  49. data/sig/plugins/aws_sdk_authentication.rbs +22 -4
  50. data/sig/plugins/response_cache.rbs +35 -0
  51. data/sig/plugins/retries.rbs +3 -0
  52. data/sig/pool.rbs +6 -0
  53. data/sig/resolver/native.rbs +3 -4
  54. data/sig/resolver/system.rbs +2 -0
  55. data/sig/response.rbs +3 -2
  56. data/sig/timers.rbs +32 -0
  57. data/sig/utils.rbs +4 -0
  58. metadata +10 -17
@@ -24,7 +24,9 @@ module HTTPX
24
24
  record_types: RECORD_TYPES.keys,
25
25
  }.freeze
26
26
 
27
- def_delegators :@resolver_connection, :connecting?, :to_io, :call, :close
27
+ def_delegators :@resolver_connection, :state, :connecting?, :to_io, :call, :close
28
+
29
+ attr_writer :pool
28
30
 
29
31
  def initialize(options)
30
32
  @options = Options.new(options)
@@ -63,15 +65,11 @@ module HTTPX
63
65
 
64
66
  private
65
67
 
66
- def pool
67
- Thread.current[:httpx_connection_pool] ||= Pool.new
68
- end
69
-
70
68
  def resolver_connection
71
- @resolver_connection ||= pool.find_connection(@uri, @options) || begin
69
+ @resolver_connection ||= @pool.find_connection(@uri, @options) || begin
72
70
  @building_connection = true
73
71
  connection = @options.connection_class.new("ssl", @uri, @options.merge(ssl: { alpn_protocols: %w[h2] }))
74
- pool.init_connection(connection, @options)
72
+ @pool.init_connection(connection, @options)
75
73
  emit_addresses(connection, @uri_addresses)
76
74
  @building_connection = false
77
75
  connection
@@ -47,6 +47,8 @@ module HTTPX
47
47
 
48
48
  def_delegator :@connections, :empty?
49
49
 
50
+ attr_reader :state
51
+
50
52
  def initialize(options)
51
53
  @options = Options.new(options)
52
54
  @ns_index = 0
@@ -120,7 +122,7 @@ module HTTPX
120
122
  def timeout
121
123
  return if @connections.empty?
122
124
 
123
- @start_timeout = Process.clock_gettime(Process::CLOCK_MONOTONIC)
125
+ @start_timeout = Utils.now
124
126
  hosts = @queries.keys
125
127
  @timeouts.values_at(*hosts).reject(&:empty?).map(&:first).min
126
128
  end
@@ -140,7 +142,7 @@ module HTTPX
140
142
  def do_retry
141
143
  return if @queries.empty?
142
144
 
143
- loop_time = Process.clock_gettime(Process::CLOCK_MONOTONIC) - @start_timeout
145
+ loop_time = Utils.elapsed_time(@start_timeout)
144
146
  connections = []
145
147
  queries = {}
146
148
  while (query = @queries.shift)
@@ -12,6 +12,8 @@ module HTTPX
12
12
  Resolv::DNS::EncodeError,
13
13
  Resolv::DNS::DecodeError].freeze
14
14
 
15
+ attr_reader :state
16
+
15
17
  def initialize(options)
16
18
  @options = Options.new(options)
17
19
  @resolver_options = @options.resolver_options
@@ -26,14 +26,14 @@ module HTTPX
26
26
  module_function
27
27
 
28
28
  def cached_lookup(hostname)
29
- now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
29
+ now = Utils.now
30
30
  @lookup_mutex.synchronize do
31
31
  lookup(hostname, now)
32
32
  end
33
33
  end
34
34
 
35
35
  def cached_lookup_set(hostname, entries)
36
- now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
36
+ now = Utils.now
37
37
  entries.each do |entry|
38
38
  entry["TTL"] += now
39
39
  end
@@ -57,17 +57,23 @@ module HTTPX
57
57
  # :nocov:
58
58
  def inspect
59
59
  "#<Response:#{object_id} "\
60
- "HTTP/#{version} " \
61
- "@status=#{@status} " \
62
- "@headers=#{@headers} " \
63
- "@body=#{@body.bytesize}>"
60
+ "HTTP/#{version} " \
61
+ "@status=#{@status} " \
62
+ "@headers=#{@headers} " \
63
+ "@body=#{@body.bytesize}>"
64
64
  end
65
65
  # :nocov:
66
66
 
67
- def raise_for_status
67
+ def error
68
68
  return if @status < 400
69
69
 
70
- raise HTTPError, self
70
+ HTTPError.new(self)
71
+ end
72
+
73
+ def raise_for_status
74
+ return self unless (err = error)
75
+
76
+ raise err
71
77
  end
72
78
 
73
79
  def json(options = nil)
@@ -211,18 +217,20 @@ module HTTPX
211
217
  end
212
218
 
213
219
  def ==(other)
214
- if other.respond_to?(:read)
215
- _with_same_buffer_pos { FileUtils.compare_stream(@buffer, other) }
216
- else
217
- to_s == other.to_s
220
+ object_id == other.object_id || begin
221
+ if other.respond_to?(:read)
222
+ _with_same_buffer_pos { FileUtils.compare_stream(@buffer, other) }
223
+ else
224
+ to_s == other.to_s
225
+ end
218
226
  end
219
227
  end
220
228
 
221
229
  # :nocov:
222
230
  def inspect
223
231
  "#<HTTPX::Response::Body:#{object_id} " \
224
- "@state=#{@state} " \
225
- "@length=#{@length}>"
232
+ "@state=#{@state} " \
233
+ "@length=#{@length}>"
226
234
  end
227
235
  # :nocov:
228
236
 
@@ -311,17 +319,18 @@ module HTTPX
311
319
  end
312
320
 
313
321
  def status
322
+ warn ":#{__method__} is deprecated, use :error.message instead"
314
323
  @error.message
315
324
  end
316
325
 
317
326
  if Exception.method_defined?(:full_message)
318
327
  def to_s
319
- @error.full_message
328
+ @error.full_message(highlight: false)
320
329
  end
321
330
  else
322
331
  def to_s
323
332
  "#{@error.message} (#{@error.class})\n" \
324
- "#{@error.backtrace.join("\n") if @error.backtrace}"
333
+ "#{@error.backtrace.join("\n") if @error.backtrace}"
325
334
  end
326
335
  end
327
336
 
@@ -2,20 +2,6 @@
2
2
 
3
3
  require "io/wait"
4
4
 
5
- module IOExtensions
6
- refine IO do
7
- # provides a fallback for rubies where IO#wait isn't implemented,
8
- # but IO#wait_readable and IO#wait_writable are.
9
- def wait(timeout = nil, _mode = :read_write)
10
- r, w = IO.select([self], [self], nil, timeout)
11
-
12
- return unless r || w
13
-
14
- self
15
- end
16
- end
17
- end
18
-
19
5
  class HTTPX::Selector
20
6
  READABLE = %i[rw r].freeze
21
7
  WRITABLE = %i[rw w].freeze
@@ -23,7 +9,7 @@ class HTTPX::Selector
23
9
  private_constant :READABLE
24
10
  private_constant :WRITABLE
25
11
 
26
- using IOExtensions unless IO.method_defined?(:wait) && IO.instance_method(:wait).arity == 2
12
+ using HTTPX::IOExtensions
27
13
 
28
14
  def initialize
29
15
  @selectables = []
@@ -58,11 +44,13 @@ class HTTPX::Selector
58
44
  selectables = @selectables
59
45
  @selectables = []
60
46
 
61
- selectables.each do |io|
47
+ selectables.delete_if do |io|
62
48
  interests = io.interests
63
49
 
64
50
  (r ||= []) << io if READABLE.include?(interests)
65
51
  (w ||= []) << io if WRITABLE.include?(interests)
52
+
53
+ io.state == :closed
66
54
  end
67
55
 
68
56
  if @selectables.empty?
@@ -70,7 +58,7 @@ class HTTPX::Selector
70
58
 
71
59
  # do not run event loop if there's nothing to wait on.
72
60
  # this might happen if connect failed and connection was unregistered.
73
- return if (!r || r.empty?) && (!w || w.empty?)
61
+ return if (!r || r.empty?) && (!w || w.empty?) && !selectables.empty?
74
62
 
75
63
  break
76
64
  else
data/lib/httpx/session.rb CHANGED
@@ -11,7 +11,7 @@ module HTTPX
11
11
  @options = self.class.default_options.merge(options)
12
12
  @responses = {}
13
13
  @persistent = @options.persistent
14
- wrap(&blk) if block_given?
14
+ wrap(&blk) if blk
15
15
  end
16
16
 
17
17
  def wrap
@@ -21,6 +21,7 @@ module HTTPX
21
21
  yield self
22
22
  ensure
23
23
  @persistent = prev_persistent
24
+ close unless @persistent
24
25
  end
25
26
  end
26
27
 
@@ -226,7 +227,11 @@ module HTTPX
226
227
  end
227
228
  responses
228
229
  ensure
229
- close(connections) unless @persistent
230
+ if @persistent
231
+ pool.deactivate(connections)
232
+ else
233
+ close(connections)
234
+ end
230
235
  end
231
236
  end
232
237
 
@@ -7,7 +7,7 @@ module HTTPX
7
7
  @options = self.class.default_options.merge(options)
8
8
  @responses = {}
9
9
  @persistent = @options.persistent
10
- wrap(&blk) if block_given?
10
+ wrap(&blk) if blk
11
11
  end
12
12
 
13
13
  def wrap
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HTTPX
4
+ class Timers
5
+ def initialize
6
+ @intervals = []
7
+ end
8
+
9
+ def after(interval_in_secs, &blk)
10
+ return unless interval_in_secs
11
+
12
+ # I'm assuming here that most requests will have the same
13
+ # request timeout, as in most cases they share common set of
14
+ # options. A user setting different request timeouts for 100s of
15
+ # requests will already have a hard time dealing with that.
16
+ unless (interval = @intervals.find { |t| t == interval_in_secs })
17
+ interval = Interval.new(interval_in_secs)
18
+ @intervals << interval
19
+ @intervals.sort!
20
+ end
21
+
22
+ interval << blk
23
+ end
24
+
25
+ def wait_interval
26
+ return if @intervals.empty?
27
+
28
+ @next_interval_at = Utils.now
29
+
30
+ @intervals.first.interval
31
+ end
32
+
33
+ def fire(error = nil)
34
+ raise error if error && error.timeout != @intervals.first
35
+ return if @intervals.empty? || !@next_interval_at
36
+
37
+ elapsed_time = Utils.elapsed_time(@next_interval_at)
38
+
39
+ @intervals.delete_if { |interval| interval.elapse(elapsed_time) <= 0 }
40
+ end
41
+
42
+ def cancel
43
+ @intervals.clear
44
+ end
45
+
46
+ class Interval
47
+ include Comparable
48
+
49
+ attr_reader :interval
50
+
51
+ def initialize(interval)
52
+ @interval = interval
53
+ @callbacks = []
54
+ end
55
+
56
+ def <=>(other)
57
+ @interval <=> other.interval
58
+ end
59
+
60
+ def ==(other)
61
+ return @interval == other if other.is_a?(Numeric)
62
+
63
+ @interval == other.to_f # rubocop:disable Lint/FloatComparison
64
+ end
65
+
66
+ def to_f
67
+ @interval
68
+ end
69
+
70
+ def <<(callback)
71
+ @callbacks << callback
72
+ end
73
+
74
+ def elapse(elapsed)
75
+ @interval -= elapsed
76
+
77
+ @callbacks.each(&:call) if @interval <= 0
78
+
79
+ @interval
80
+ end
81
+ end
82
+ private_constant :Interval
83
+ end
84
+ end
@@ -9,6 +9,7 @@ module HTTPX::Transcoder
9
9
  module_function
10
10
 
11
11
  class Encoder
12
+ using HTTPX::ArrayExtensions
12
13
  extend Forwardable
13
14
 
14
15
  def_delegator :@raw, :to_s
@@ -21,7 +22,7 @@ module HTTPX::Transcoder
21
22
  if @raw.respond_to?(:bytesize)
22
23
  @raw.bytesize
23
24
  elsif @raw.respond_to?(:to_ary)
24
- @raw.map(&:bytesize).reduce(0, :+)
25
+ @raw.sum(&:bytesize)
25
26
  elsif @raw.respond_to?(:size)
26
27
  @raw.size || Float::INFINITY
27
28
  elsif @raw.respond_to?(:length)
@@ -50,7 +50,7 @@ module HTTPX::Transcoder
50
50
  def decode(response)
51
51
  content_type = response.content_type.mime_type
52
52
 
53
- raise Error, "invalid form mime type (#{content_type})" unless content_type == "application/x-www-form-urlencoded"
53
+ raise HTTPX::Error, "invalid form mime type (#{content_type})" unless content_type == "application/x-www-form-urlencoded"
54
54
 
55
55
  Decoder
56
56
  end
@@ -35,7 +35,7 @@ module HTTPX::Transcoder
35
35
  def decode(response)
36
36
  content_type = response.content_type.mime_type
37
37
 
38
- raise Error, "invalid json mime type (#{content_type})" unless JSON_REGEX.match?(content_type)
38
+ raise HTTPX::Error, "invalid json mime type (#{content_type})" unless JSON_REGEX.match?(content_type)
39
39
 
40
40
  ::JSON.method(:parse)
41
41
  end
data/lib/httpx/utils.rb CHANGED
@@ -6,6 +6,14 @@ module HTTPX
6
6
 
7
7
  module_function
8
8
 
9
+ def now
10
+ Process.clock_gettime(Process::CLOCK_MONOTONIC)
11
+ end
12
+
13
+ def elapsed_time(monotonic_timestamp)
14
+ Process.clock_gettime(Process::CLOCK_MONOTONIC) - monotonic_timestamp
15
+ end
16
+
9
17
  # The value of this field can be either an HTTP-date or a number of
10
18
  # seconds to delay after the response is received.
11
19
  def parse_retry_after(retry_after)
data/lib/httpx/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module HTTPX
4
- VERSION = "0.17.0"
4
+ VERSION = "0.18.0"
5
5
  end
data/lib/httpx.rb CHANGED
@@ -13,6 +13,7 @@ require "httpx/callbacks"
13
13
  require "httpx/loggable"
14
14
  require "httpx/registry"
15
15
  require "httpx/transcoder"
16
+ require "httpx/timers"
16
17
  require "httpx/pool"
17
18
  require "httpx/headers"
18
19
  require "httpx/request"
data/sig/chainable.rbs CHANGED
@@ -32,6 +32,7 @@ module HTTPX
32
32
  | (:stream, ?options) -> Plugins::sessionStream
33
33
  | (:aws_sigv4, ?options) -> Plugins::awsSigV4Session
34
34
  | (:grpc, ?options) -> Plugins::grpcSession
35
+ | (:response_cache, ?options) -> Plugins::sessionResponseCache
35
36
  | (Symbol | Module, ?options) { (Class) -> void } -> Session
36
37
  | (Symbol | Module, ?options) -> Session
37
38
 
data/sig/connection.rbs CHANGED
@@ -25,7 +25,15 @@ module HTTPX
25
25
  attr_reader state: Symbol
26
26
  attr_reader pending: Array[Request]
27
27
  attr_reader options: Options
28
- attr_writer timers: untyped # Timers::Timer
28
+ attr_writer timers: Timers
29
+
30
+ @origins: Array[URI::Generic]
31
+ @window_size: Integer
32
+ @read_buffer: Buffer
33
+ @write_buffer: Buffer
34
+ @inflight: Integer
35
+ @keep_alive_timeout: Numeric?
36
+ @total_timeout: Numeric?
29
37
 
30
38
  def addresses: () -> Array[ipaddr]?
31
39
 
@@ -62,6 +70,7 @@ module HTTPX
62
70
 
63
71
  def timeout: () -> Numeric?
64
72
 
73
+ def deactivate: () -> void
65
74
  private
66
75
 
67
76
  def initialize: (String, URI::Generic, options) -> untyped
@@ -76,6 +85,8 @@ module HTTPX
76
85
 
77
86
  def parser: () -> _Parser
78
87
 
88
+ def send_request_to_parser: (Request request) -> void
89
+
79
90
  def build_parser: () -> _Parser
80
91
  | (String) -> _Parser
81
92
 
@@ -83,15 +94,10 @@ module HTTPX
83
94
 
84
95
  def transition: (Symbol) -> void
85
96
 
86
- def handle_response: () -> void
87
-
88
97
  def on_error: (HTTPX::TimeoutError | Error | StandardError) -> void
89
98
 
90
99
  def handle_error: (StandardError) -> void
91
100
 
92
- def total_timeout: () -> untyped?
93
- # def total_timeout: () -> Timers::Timer?
94
- #
95
101
  def purge_after_closed: () -> void
96
102
  end
97
103
  end
@@ -1,25 +1,43 @@
1
1
  module HTTPX
2
2
  module Plugins
3
3
  module AwsSdkAuthentication
4
+ class Configuration
5
+ attr_reader profile: String?
6
+
7
+ private
8
+
9
+ def initialize: (String? profile) -> void
10
+ end
11
+
4
12
  class Credentials
13
+ @aws_credentials: untyped
14
+
5
15
  include _SigV4Credentials
6
16
 
7
17
  private
8
-
18
+
9
19
  def initialize: (untyped aws_credentials) -> untyped
10
20
  end
11
21
 
22
+ interface _AwsSdkOptions
23
+ def aws_profile: () -> String?
24
+ end
25
+
12
26
  def self.load_dependencies: (singleton(Session)) -> void
13
27
 
14
28
  def self.configure: (singleton(Session)) -> void
15
29
 
16
- def self.extra_options: (Options) -> (Options)
30
+ def self.extra_options: (Options) -> (Options & _AwsSdkOptions)
31
+
32
+ def self.credentials: (String? profile) -> Credentials
33
+
34
+ def self.region: (String? profile) -> String
17
35
 
18
36
  module InstanceMethods
19
- def aws_sdk_authentication: (**untyped) -> instance
37
+ def aws_sdk_authentication: (?credentials: Credentials, ?region: String, **untyped) -> instance
20
38
  end
21
39
  end
22
40
 
23
- type sessionAwsSdkAuthentication = Session & AwsSdkAuthentication::InstanceMethods
41
+ type sessionAwsSdkAuthentication = awsSigV4Session & AwsSdkAuthentication::InstanceMethods
24
42
  end
25
43
  end
@@ -0,0 +1,35 @@
1
+ module HTTPX
2
+ module Plugins
3
+ module ResponseCache
4
+ CACHEABLE_VERBS: Array[Symbol]
5
+
6
+ def self?.cacheable_request?: (Request request) -> bool
7
+ def self?.cacheable_response?: (response response) -> bool
8
+ def self?.cached_response?: (response response) -> bool
9
+
10
+ class Store
11
+ @store: Hash[URI::Generic, Response]
12
+
13
+ def lookup: (URI::Generic uri) -> Response?
14
+
15
+ def cached?: (URI::Generic uri) -> bool
16
+
17
+ def cache: (URI::Generic uri, Response response) -> void
18
+
19
+ def prepare: (Request request) -> void
20
+ end
21
+
22
+ module InstanceMethods
23
+ @response_cache: Store
24
+
25
+ def clear_response_cache: () -> void
26
+ end
27
+
28
+ module ResponseMethods
29
+ def copy_from_cached: (Response other) -> void
30
+ end
31
+ end
32
+
33
+ type sessionResponseCache = Session & ResponseCache::InstanceMethods
34
+ end
35
+ end
@@ -4,6 +4,7 @@ module HTTPX
4
4
  MAX_RETRIES: Integer
5
5
  IDEMPOTENT_METHODS: Array[verb]
6
6
  RETRYABLE_ERRORS: Array[singleton(StandardError)]
7
+ DEFAULT_JITTER: ^(Numeric) -> Numeric
7
8
 
8
9
  interface _RetryCallback
9
10
  def call: (response) -> bool?
@@ -12,6 +13,8 @@ module HTTPX
12
13
  interface _RetriesOptions
13
14
  def retry_after: () -> Numeric?
14
15
 
16
+ def retry_jitter: () -> ^(Numeric) -> Numeric
17
+
15
18
  def max_retries: () -> Integer?
16
19
 
17
20
  def retry_change_requests: () -> boolish
data/sig/pool.rbs CHANGED
@@ -10,6 +10,8 @@ module HTTPX
10
10
 
11
11
  def find_connection: (generic_uri, Options) -> Connection?
12
12
 
13
+ def deactivate: (*Array[Connection]) -> void
14
+
13
15
  private
14
16
 
15
17
  def initialize: () -> untyped
@@ -26,6 +28,10 @@ module HTTPX
26
28
 
27
29
  def unregister_connection: (Connection) -> void
28
30
 
31
+ def select_connection: (resolver | Connection connection) -> void
32
+
33
+ def deselect_connection: (resolver | Connection connection) -> void
34
+
29
35
  def coalesce_connections: (Connection, Connection) -> void
30
36
 
31
37
  def next_timeout: () -> Numeric?
@@ -5,8 +5,6 @@ module HTTPX
5
5
  include ResolverMixin
6
6
  include _ToIO
7
7
 
8
- type state = :idle | :open | :closed
9
-
10
8
  DEFAULTS: Hash[Symbol, untyped]
11
9
  DNS_PORT: Integer
12
10
 
@@ -21,7 +19,8 @@ module HTTPX
21
19
  @queries: Hash[String, Connection]
22
20
  @read_buffer: String
23
21
  @write_buffer: Buffer
24
- @state: state
22
+
23
+ attr_reader state: Symbol
25
24
 
26
25
  def closed?: () -> bool
27
26
 
@@ -58,7 +57,7 @@ module HTTPX
58
57
 
59
58
  def build_socket: () -> void
60
59
 
61
- def transition: (state nextstate) -> void
60
+ def transition: (Symbol nextstate) -> void
62
61
 
63
62
  def handle_error: (NativeResolveError | StandardError) -> void
64
63
  end
@@ -5,6 +5,8 @@ module HTTPX
5
5
 
6
6
  RESOLV_ERRORS: Array[singleton(StandardError)] # ResolvError
7
7
 
8
+ attr_reader state: Symbol
9
+
8
10
  def closed?: () -> true
9
11
 
10
12
  def empty?: () -> true
data/sig/response.rbs CHANGED
@@ -1,6 +1,8 @@
1
1
  module HTTPX
2
2
  interface _Response
3
- def raise_for_status: () -> void
3
+ def raise_for_status: () -> self
4
+
5
+ def error: () -> StandardError?
4
6
  end
5
7
 
6
8
  class Response
@@ -89,7 +91,6 @@ module HTTPX
89
91
  @options: Options
90
92
 
91
93
  attr_reader request: Request
92
- attr_reader error: Exception
93
94
 
94
95
  def status: () -> (Integer | _ToS)
95
96
 
data/sig/timers.rbs ADDED
@@ -0,0 +1,32 @@
1
+ module HTTPX
2
+ class Timers
3
+ @interval: Array[Interval]
4
+
5
+ def after: (Numeric interval_in_secs) { () -> void } -> void
6
+
7
+ def wait_interval: () -> Numeric?
8
+
9
+ def fire: (?StandardError error) -> void
10
+
11
+ def cancel: () -> void
12
+
13
+ private
14
+
15
+ def initialize: () -> void
16
+
17
+ class Interval
18
+ include Comparable
19
+
20
+ attr_reader interval: Numeric
21
+
22
+ def to_f: () -> Float
23
+
24
+ def <<: (^() -> void) -> void
25
+
26
+ def elapse: (Numeric elapsed) -> Numeric
27
+ private
28
+
29
+ def initialize: (Numeric interval) -> void
30
+ end
31
+ end
32
+ end