httpx 0.20.5 → 0.21.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/doc/release_notes/0_13_0.md +1 -1
  3. data/doc/release_notes/0_21_0.md +94 -0
  4. data/lib/httpx/connection/http1.rb +2 -1
  5. data/lib/httpx/connection.rb +41 -2
  6. data/lib/httpx/errors.rb +18 -0
  7. data/lib/httpx/extensions.rb +8 -4
  8. data/lib/httpx/io/unix.rb +1 -1
  9. data/lib/httpx/options.rb +7 -3
  10. data/lib/httpx/plugins/circuit_breaker/circuit.rb +76 -0
  11. data/lib/httpx/plugins/circuit_breaker/circuit_store.rb +44 -0
  12. data/lib/httpx/plugins/circuit_breaker.rb +115 -0
  13. data/lib/httpx/plugins/cookies.rb +1 -1
  14. data/lib/httpx/plugins/expect.rb +1 -1
  15. data/lib/httpx/plugins/multipart/decoder.rb +1 -1
  16. data/lib/httpx/plugins/proxy.rb +7 -1
  17. data/lib/httpx/plugins/retries.rb +1 -1
  18. data/lib/httpx/plugins/webdav.rb +78 -0
  19. data/lib/httpx/request.rb +15 -25
  20. data/lib/httpx/resolver/https.rb +2 -7
  21. data/lib/httpx/resolver/native.rb +2 -1
  22. data/lib/httpx/response.rb +27 -9
  23. data/lib/httpx/timers.rb +3 -0
  24. data/lib/httpx/transcoder/form.rb +1 -1
  25. data/lib/httpx/transcoder/json.rb +19 -3
  26. data/lib/httpx/transcoder/xml.rb +57 -0
  27. data/lib/httpx/transcoder.rb +1 -0
  28. data/lib/httpx/version.rb +1 -1
  29. data/sig/buffer.rbs +1 -1
  30. data/sig/chainable.rbs +1 -0
  31. data/sig/connection.rbs +12 -4
  32. data/sig/errors.rbs +13 -0
  33. data/sig/io.rbs +6 -0
  34. data/sig/options.rbs +4 -1
  35. data/sig/plugins/circuit_breaker.rbs +61 -0
  36. data/sig/plugins/compression/brotli.rbs +1 -1
  37. data/sig/plugins/compression/deflate.rbs +1 -1
  38. data/sig/plugins/compression/gzip.rbs +3 -3
  39. data/sig/plugins/compression.rbs +1 -1
  40. data/sig/plugins/multipart.rbs +1 -1
  41. data/sig/plugins/proxy/socks5.rbs +3 -2
  42. data/sig/plugins/proxy.rbs +1 -1
  43. data/sig/registry.rbs +5 -4
  44. data/sig/request.rbs +7 -1
  45. data/sig/resolver/native.rbs +5 -2
  46. data/sig/response.rbs +3 -1
  47. data/sig/timers.rbs +1 -1
  48. data/sig/transcoder/json.rbs +4 -1
  49. data/sig/transcoder/xml.rbs +21 -0
  50. data/sig/transcoder.rbs +2 -2
  51. data/sig/utils.rbs +2 -2
  52. metadata +12 -2
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HTTPX
4
+ module Plugins
5
+ #
6
+ # This plugin implements convenience methods for performing WEBDAV requests.
7
+ #
8
+ # https://gitlab.com/honeyryderchuck/httpx/wikis/WEBDAV
9
+ #
10
+ module WebDav
11
+ module InstanceMethods
12
+ def copy(src, dest)
13
+ request(:copy, src, headers: { "destination" => @options.origin.merge(dest) })
14
+ end
15
+
16
+ def move(src, dest)
17
+ request(:move, src, headers: { "destination" => @options.origin.merge(dest) })
18
+ end
19
+
20
+ def lock(path, timeout: nil, &blk)
21
+ headers = {}
22
+ headers["timeout"] = if timeout && timeout.positive?
23
+ "Second-#{timeout}"
24
+ else
25
+ "Infinite, Second-4100000000"
26
+ end
27
+ xml = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" \
28
+ "<D:lockinfo xmlns:D=\"DAV:\">" \
29
+ "<D:lockscope><D:exclusive/></D:lockscope>" \
30
+ "<D:locktype><D:write/></D:locktype>" \
31
+ "<D:owner>null</D:owner>" \
32
+ "</D:lockinfo>"
33
+ response = request(:lock, path, headers: headers, xml: xml)
34
+
35
+ return response unless blk && response.status == 200
36
+
37
+ lock_token = response.headers["lock-token"]
38
+
39
+ begin
40
+ blk.call(response)
41
+ ensure
42
+ unlock(path, lock_token)
43
+ end
44
+ end
45
+
46
+ def unlock(path, lock_token)
47
+ request(:unlock, path, headers: { "lock-token" => lock_token })
48
+ end
49
+
50
+ def mkcol(dir)
51
+ request(:mkcol, dir)
52
+ end
53
+
54
+ def propfind(path, xml = nil)
55
+ body = case xml
56
+ when :acl
57
+ '<?xml version="1.0" encoding="utf-8" ?><D:propfind xmlns:D="DAV:"><D:prop><D:owner/>' \
58
+ "<D:supported-privilege-set/><D:current-user-privilege-set/><D:acl/></D:prop></D:propfind>"
59
+ when nil
60
+ '<?xml version="1.0" encoding="utf-8"?><DAV:propfind xmlns:DAV="DAV:"><DAV:allprop/></DAV:propfind>'
61
+ else
62
+ xml
63
+ end
64
+
65
+ request(:propfind, path, headers: { "depth" => "1" }, xml: body)
66
+ end
67
+
68
+ def proppatch(path, xml)
69
+ body = "<?xml version=\"1.0\"?>" \
70
+ "<D:propertyupdate xmlns:D=\"DAV:\" xmlns:Z=\"http://ns.example.com/standards/z39.50/\">#{xml}</D:propertyupdate>"
71
+ request(:proppatch, path, xml: body)
72
+ end
73
+ # %i[ orderpatch acl report search]
74
+ end
75
+ end
76
+ register_plugin(:webdav, WebDav)
77
+ end
78
+ end
data/lib/httpx/request.rb CHANGED
@@ -9,29 +9,6 @@ module HTTPX
9
9
  include Callbacks
10
10
  using URIExtensions
11
11
 
12
- METHODS = [
13
- # RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1
14
- :options, :get, :head, :post, :put, :delete, :trace, :connect,
15
-
16
- # RFC 2518: HTTP Extensions for Distributed Authoring -- WEBDAV
17
- :propfind, :proppatch, :mkcol, :copy, :move, :lock, :unlock,
18
-
19
- # RFC 3648: WebDAV Ordered Collections Protocol
20
- :orderpatch,
21
-
22
- # RFC 3744: WebDAV Access Control Protocol
23
- :acl,
24
-
25
- # RFC 6352: vCard Extensions to WebDAV -- CardDAV
26
- :report,
27
-
28
- # RFC 5789: PATCH Method for HTTP
29
- :patch,
30
-
31
- # draft-reschke-webdav-search: WebDAV Search
32
- :search
33
- ].freeze
34
-
35
12
  USER_AGENT = "httpx.rb/#{VERSION}"
36
13
 
37
14
  attr_reader :verb, :uri, :headers, :body, :state, :options, :response
@@ -54,8 +31,6 @@ module HTTPX
54
31
  @uri = origin.merge("#{base_path}#{@uri}")
55
32
  end
56
33
 
57
- raise(Error, "unknown method: #{verb}") unless METHODS.include?(@verb)
58
-
59
34
  @headers = @options.headers_class.new(@options.headers)
60
35
  @headers["user-agent"] ||= USER_AGENT
61
36
  @headers["accept"] ||= "*/*"
@@ -64,6 +39,18 @@ module HTTPX
64
39
  @state = :idle
65
40
  end
66
41
 
42
+ def read_timeout
43
+ @options.timeout[:read_timeout]
44
+ end
45
+
46
+ def write_timeout
47
+ @options.timeout[:write_timeout]
48
+ end
49
+
50
+ def request_timeout
51
+ @options.timeout[:request_timeout]
52
+ end
53
+
67
54
  def trailers?
68
55
  defined?(@trailers)
69
56
  end
@@ -108,6 +95,7 @@ module HTTPX
108
95
 
109
96
  def path
110
97
  path = uri.path.dup
98
+ path = +"" if path.nil?
111
99
  path << "/" if path.empty?
112
100
  path << "?#{query}" unless query.empty?
113
101
  path
@@ -174,6 +162,8 @@ module HTTPX
174
162
  Transcoder.registry("form").encode(options.form)
175
163
  elsif options.json
176
164
  Transcoder.registry("json").encode(options.json)
165
+ elsif options.xml
166
+ Transcoder.registry("xml").encode(options.xml)
177
167
  end
178
168
  return if @body.nil?
179
169
 
@@ -102,7 +102,7 @@ module HTTPX
102
102
  @requests[request] = hostname
103
103
  resolver_connection.send(request)
104
104
  @connections << connection
105
- rescue ResolveError, Resolv::DNS::EncodeError, JSON::JSONError => e
105
+ rescue ResolveError, Resolv::DNS::EncodeError => e
106
106
  @queries.delete(hostname)
107
107
  emit_resolve_error(connection, connection.origin.host, e)
108
108
  end
@@ -129,7 +129,7 @@ module HTTPX
129
129
  def parse(request, response)
130
130
  begin
131
131
  answers = decode_response_body(response)
132
- rescue Resolv::DNS::DecodeError, JSON::JSONError => e
132
+ rescue Resolv::DNS::DecodeError => e
133
133
  host, connection = @queries.first
134
134
  @queries.delete(host)
135
135
  emit_resolve_error(connection, connection.origin.host, e)
@@ -203,11 +203,6 @@ module HTTPX
203
203
 
204
204
  def decode_response_body(response)
205
205
  case response.headers["content-type"]
206
- when "application/dns-json",
207
- "application/json",
208
- %r{^application/x-javascript} # because google...
209
- payload = JSON.parse(response.to_s)
210
- payload["Answer"]
211
206
  when "application/dns-udpwireformat",
212
207
  "application/dns-message"
213
208
  Resolver.decode_dns_answer(response.to_s)
@@ -77,7 +77,8 @@ module HTTPX
77
77
  nil
78
78
  rescue Errno::EHOSTUNREACH => e
79
79
  @ns_index += 1
80
- if @ns_index < @nameserver.size
80
+ nameserver = @nameserver
81
+ if nameserver && @ns_index < nameserver.size
81
82
  log { "resolver: failed resolving on nameserver #{@nameserver[@ns_index - 1]} (#{e.message})" }
82
83
  transition(:idle)
83
84
  else
@@ -31,6 +31,7 @@ module HTTPX
31
31
  @status = Integer(status)
32
32
  @headers = @options.headers_class.new(headers)
33
33
  @body = @options.response_body_class.new(self, @options)
34
+ @finished = complete?
34
35
  end
35
36
 
36
37
  def merge_headers(h)
@@ -41,15 +42,24 @@ module HTTPX
41
42
  @body.write(data)
42
43
  end
43
44
 
45
+ def content_type
46
+ @content_type ||= ContentType.new(@headers["content-type"])
47
+ end
48
+
49
+ def finished?
50
+ @finished
51
+ end
52
+
53
+ def finish!
54
+ @finished = true
55
+ @headers.freeze
56
+ end
57
+
44
58
  def bodyless?
45
59
  @request.verb == :head ||
46
60
  no_data?
47
61
  end
48
62
 
49
- def content_type
50
- @content_type ||= ContentType.new(@headers["content-type"])
51
- end
52
-
53
63
  def complete?
54
64
  bodyless? || (@request.verb == :connect && @status == 200)
55
65
  end
@@ -76,17 +86,21 @@ module HTTPX
76
86
  raise err
77
87
  end
78
88
 
79
- def json(options = nil)
80
- decode("json", options)
89
+ def json(*args)
90
+ decode("json", *args)
81
91
  end
82
92
 
83
93
  def form
84
94
  decode("form")
85
95
  end
86
96
 
97
+ def xml
98
+ decode("xml")
99
+ end
100
+
87
101
  private
88
102
 
89
- def decode(format, options = nil)
103
+ def decode(format, *args)
90
104
  # TODO: check if content-type is a valid format, i.e. "application/json" for json parsing
91
105
  transcoder = Transcoder.registry(format)
92
106
 
@@ -96,13 +110,13 @@ module HTTPX
96
110
 
97
111
  raise Error, "no decoder available for \"#{format}\"" unless decoder
98
112
 
99
- decoder.call(self, options)
113
+ decoder.call(self, *args)
100
114
  rescue Registry::Error
101
115
  raise Error, "no decoder available for \"#{format}\""
102
116
  end
103
117
 
104
118
  def no_data?
105
- @status < 200 ||
119
+ @status < 200 || # informational response
106
120
  @status == 204 ||
107
121
  @status == 205 ||
108
122
  @status == 304 || begin
@@ -339,6 +353,10 @@ module HTTPX
339
353
  end
340
354
  end
341
355
 
356
+ def finished?
357
+ true
358
+ end
359
+
342
360
  def raise_for_status
343
361
  raise @error
344
362
  end
data/lib/httpx/timers.rb CHANGED
@@ -37,9 +37,12 @@ module HTTPX
37
37
  elapsed_time = Utils.elapsed_time(@next_interval_at)
38
38
 
39
39
  @intervals.delete_if { |interval| interval.elapse(elapsed_time) <= 0 }
40
+
41
+ @next_interval_at = nil if @intervals.empty?
40
42
  end
41
43
 
42
44
  def cancel
45
+ @next_interval_at = nil
43
46
  @intervals.clear
44
47
  end
45
48
 
@@ -36,7 +36,7 @@ module HTTPX::Transcoder
36
36
  module Decoder
37
37
  module_function
38
38
 
39
- def call(response, _)
39
+ def call(response, *)
40
40
  URI.decode_www_form(response.to_s).each_with_object({}) do |(field, value), params|
41
41
  HTTPX::Transcoder.normalize_query(params, field, value, PARAM_DEPTH_LIMIT)
42
42
  end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "forwardable"
4
- require "json"
5
4
 
6
5
  module HTTPX::Transcoder
7
6
  module JSON
@@ -19,7 +18,7 @@ module HTTPX::Transcoder
19
18
  def_delegator :@raw, :bytesize
20
19
 
21
20
  def initialize(json)
22
- @raw = ::JSON.dump(json)
21
+ @raw = JSON.json_dump(json)
23
22
  @charset = @raw.encoding.name.downcase
24
23
  end
25
24
 
@@ -37,8 +36,25 @@ module HTTPX::Transcoder
37
36
 
38
37
  raise HTTPX::Error, "invalid json mime type (#{content_type})" unless JSON_REGEX.match?(content_type)
39
38
 
40
- ::JSON.method(:parse)
39
+ method(:json_load)
41
40
  end
41
+
42
+ # rubocop:disable Style/SingleLineMethods
43
+ if defined?(MultiJson)
44
+ def json_load(*args); MultiJson.load(*args); end
45
+ def json_dump(*args); MultiJson.dump(*args); end
46
+ elsif defined?(Oj)
47
+ def json_load(response, *args); Oj.load(response.to_s, *args); end
48
+ def json_dump(*args); Oj.dump(*args); end
49
+ elsif defined?(Yajl)
50
+ def json_load(response, *args); Yajl::Parser.new(*args).parse(response.to_s); end
51
+ def json_dump(*args); Yajl::Encoder.encode(*args); end
52
+ else
53
+ require "json"
54
+ def json_load(*args); ::JSON.parse(*args); end
55
+ def json_dump(*args); ::JSON.dump(*args); end
56
+ end
57
+ # rubocop:enable Style/SingleLineMethods
42
58
  end
43
59
  register "json", JSON
44
60
  end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "delegate"
4
+ require "forwardable"
5
+ require "uri"
6
+
7
+ module HTTPX::Transcoder
8
+ module Xml
9
+ using HTTPX::RegexpExtensions
10
+
11
+ module_function
12
+
13
+ MIME_TYPES = %r{\b(application|text)/(.+\+)?xml\b}.freeze
14
+
15
+ class Encoder
16
+ def initialize(xml)
17
+ @raw = xml
18
+ end
19
+
20
+ def content_type
21
+ charset = @raw.respond_to?(:encoding) ? @raw.encoding.to_s.downcase : "utf-8"
22
+ "application/xml; charset=#{charset}"
23
+ end
24
+
25
+ def bytesize
26
+ @raw.to_s.bytesize
27
+ end
28
+
29
+ def to_s
30
+ @raw.to_s
31
+ end
32
+ end
33
+
34
+ def encode(xml)
35
+ Encoder.new(xml)
36
+ end
37
+
38
+ begin
39
+ require "nokogiri"
40
+
41
+ # rubocop:disable Lint/DuplicateMethods
42
+ def decode(response)
43
+ content_type = response.content_type.mime_type
44
+
45
+ raise HTTPX::Error, "invalid form mime type (#{content_type})" unless MIME_TYPES.match?(content_type)
46
+
47
+ Nokogiri::XML.method(:parse)
48
+ end
49
+ rescue LoadError
50
+ def decode(_response)
51
+ raise HTTPX::Error, "\"nokogiri\" is required in order to decode XML"
52
+ end
53
+ end
54
+ # rubocop:enable Lint/DuplicateMethods
55
+ end
56
+ register "xml", Xml
57
+ end
@@ -90,4 +90,5 @@ end
90
90
  require "httpx/transcoder/body"
91
91
  require "httpx/transcoder/form"
92
92
  require "httpx/transcoder/json"
93
+ require "httpx/transcoder/xml"
93
94
  require "httpx/transcoder/chunker"
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.20.5"
4
+ VERSION = "0.21.0"
5
5
  end
data/sig/buffer.rbs CHANGED
@@ -15,7 +15,7 @@ module HTTPX
15
15
  # delegated
16
16
  def <<: (string data) -> String
17
17
  def empty?: () -> bool
18
- def bytesize: () -> Integer
18
+ def bytesize: () -> (Integer | Float)
19
19
  def clear: () -> void
20
20
  def replace: (string) -> void
21
21
 
data/sig/chainable.rbs CHANGED
@@ -33,6 +33,7 @@ module HTTPX
33
33
  | (:aws_sigv4, ?options) -> Plugins::awsSigV4Session
34
34
  | (:grpc, ?options) -> Plugins::grpcSession
35
35
  | (:response_cache, ?options) -> Plugins::sessionResponseCache
36
+ | (:circuit_breaker, ?options) -> Plugins::sessionCircuitBreaker
36
37
  | (Symbol | Module, ?options) { (Class) -> void } -> Session
37
38
  | (Symbol | Module, ?options) -> Session
38
39
 
data/sig/connection.rbs CHANGED
@@ -28,7 +28,7 @@ module HTTPX
28
28
  attr_reader options: Options
29
29
  attr_writer timers: Timers
30
30
 
31
- @origins: Array[URI::Generic]
31
+ @type: io_type
32
32
  @window_size: Integer
33
33
  @read_buffer: Buffer
34
34
  @write_buffer: Buffer
@@ -40,7 +40,7 @@ module HTTPX
40
40
 
41
41
  def addresses=: (Array[ipaddr]) -> void
42
42
 
43
- def match?: (URI::Generic, options) -> bool
43
+ def match?: (URI::Generic uri, Options options) -> bool
44
44
 
45
45
  def mergeable?: (Connection) -> bool
46
46
 
@@ -54,13 +54,15 @@ module HTTPX
54
54
 
55
55
  def match_altsvcs?: (URI::Generic uri) -> bool
56
56
 
57
+ def match_altsvc_options?: (URI::Generic uri, Options options) -> bool
58
+
57
59
  def connecting?: () -> bool
58
60
 
59
61
  def inflight?: () -> boolish
60
62
 
61
63
  def interests: () -> io_interests?
62
64
 
63
- def to_io: () -> IO
65
+ def to_io: () -> ::IO
64
66
 
65
67
  def call: () -> void
66
68
 
@@ -77,7 +79,7 @@ module HTTPX
77
79
 
78
80
  private
79
81
 
80
- def initialize: (String, URI::Generic, options) -> untyped
82
+ def initialize: (io_type, URI::Generic, options) -> untyped
81
83
 
82
84
  def connect: () -> void
83
85
 
@@ -103,5 +105,11 @@ module HTTPX
103
105
  def handle_error: (StandardError) -> void
104
106
 
105
107
  def purge_after_closed: () -> void
108
+
109
+ def set_request_timeouts: (Request request) -> void
110
+
111
+ def write_timeout_callback: (Request request, Numeric write_timeout) -> void
112
+
113
+ def read_timeout_callback: (Request request, Numeric read_timeout, ?singleton(RequestTimeoutError) error_type) -> void
106
114
  end
107
115
  end
data/sig/errors.rbs CHANGED
@@ -23,6 +23,19 @@ module HTTPX
23
23
  class ResolveTimeoutError < TimeoutError
24
24
  end
25
25
 
26
+ class RequestTimeoutError < TimeoutError
27
+ attr_reader request: Request
28
+ attr_reader response: response?
29
+
30
+ def initialize: (Request request, response? response, Numeric timeout) -> void
31
+ end
32
+
33
+ class ReadTimeoutError < RequestTimeoutError
34
+ end
35
+
36
+ class WriteTimeoutError < RequestTimeoutError
37
+ end
38
+
26
39
  class ResolveError < Error
27
40
  end
28
41
 
data/sig/io.rbs ADDED
@@ -0,0 +1,6 @@
1
+ module HTTPX
2
+ type io_type = "udp" | "tcp" | "ssl" | "unix"
3
+
4
+ module IO
5
+ end
6
+ end
data/sig/options.rbs CHANGED
@@ -10,7 +10,7 @@ module HTTPX
10
10
  SETTINGS_TIMEOUT: Integer
11
11
  DEFAULT_OPTIONS: Hash[Symbol, untyped]
12
12
 
13
- type timeout_type = :connect_timeout | :settings_timeout | :operation_timeout | :keep_alive_timeout | :total_timeout
13
+ type timeout_type = :connect_timeout | :settings_timeout | :operation_timeout | :keep_alive_timeout | :total_timeout | :read_timeout | :write_timeout | :request_timeout
14
14
  type timeout = Hash[timeout_type, Numeric]
15
15
 
16
16
  def self.new: (?options) -> instance
@@ -65,6 +65,9 @@ module HTTPX
65
65
  # body
66
66
  attr_reader origin: URI::Generic?
67
67
 
68
+ # base_path
69
+ attr_reader base_path: String?
70
+
68
71
  # ssl
69
72
 
70
73
  # http2_settings
@@ -0,0 +1,61 @@
1
+ module HTTPX
2
+ module Plugins
3
+ module CircuitBreaker
4
+
5
+ class CircuitStore
6
+ @circuits: Hash[String, Circuit]
7
+
8
+ def try_open: (generic_uri uri, response response) -> void
9
+
10
+ def try_respond: (Request request) -> response?
11
+
12
+ private
13
+
14
+ def get_circuit_for_uri: (generic_uri uri) -> Circuit
15
+
16
+ def initialize: (Options & _CircuitOptions options) -> void
17
+ end
18
+
19
+ class Circuit
20
+ @state: :closed | :open | :half_open
21
+ @max_attempts: Integer
22
+ @reset_attempts_in: Float
23
+ @break_in: Float
24
+ @circuit_breaker_half_open_drip_rate: Float
25
+ @attempts: Integer
26
+
27
+ @response: response?
28
+ @opened_at: Float?
29
+ @attempted_at: Float?
30
+
31
+ def respond: () -> response?
32
+
33
+ def try_open: (response) -> void
34
+
35
+ def try_close: () -> void
36
+
37
+ private
38
+
39
+ def initialize: (Integer max_attempts, Float reset_attempts_in, Float break_in, Float circuit_breaker_half_open_drip_rate) -> void
40
+ end
41
+
42
+ interface _CircuitOptions
43
+ def circuit_breaker_max_attempts: () -> Integer
44
+ def circuit_breaker_reset_attempts_in: () -> Float
45
+ def circuit_breaker_break_in: () -> Float
46
+ def circuit_breaker_half_open_drip_rate: () -> Float
47
+ def circuit_breaker_break_on: () -> (^(Response) -> boolish | nil)
48
+ end
49
+
50
+ def self.load_dependencies: (singleton(Session)) -> void
51
+ def self.extra_options: (Options) -> (Options & _CircuitOptions)
52
+
53
+ module InstanceMethods
54
+ @circuit_store: CircuitStore
55
+ end
56
+
57
+ end
58
+
59
+ type sessionCircuitBreaker = Session & CircuitBreaker::InstanceMethods
60
+ end
61
+ end
@@ -6,7 +6,7 @@ module HTTPX
6
6
  def self.configure: (singleton(Session)) -> void
7
7
 
8
8
  def self?.deflater: () -> _Deflater
9
- def self?.decoder: (Numeric bytesize) -> Inflater
9
+ def self?.decoder: (Integer | Float bytesize) -> Inflater
10
10
 
11
11
  module Deflater
12
12
  extend _Deflater
@@ -6,7 +6,7 @@ module HTTPX
6
6
  def self.configure: (singleton(Session)) -> void
7
7
 
8
8
  def self?.deflater: () -> _Deflater
9
- def self?.inflater: (Numeric bytesize) -> GZIP::Inflater
9
+ def self?.inflater: (Integer | Float bytesize) -> GZIP::Inflater
10
10
 
11
11
  module Deflater
12
12
  extend _Deflater
@@ -6,15 +6,15 @@ module HTTPX
6
6
  def self.configure: (singleton(Session)) -> void
7
7
 
8
8
  def self?.deflater: () -> _Deflater
9
- def self?.inflater: (Numeric bytesize) -> Inflater
9
+ def self?.inflater: (Integer | Float bytesize) -> Inflater
10
10
 
11
11
  class Deflater
12
12
  include _Deflater
13
13
 
14
14
  @compressed_chunk: String
15
-
15
+
16
16
  private
17
-
17
+
18
18
  def initialize: () -> untyped
19
19
  def write: (string) -> void
20
20
  def compressed_chunk: () -> String
@@ -13,7 +13,7 @@ module HTTPX
13
13
  interface _Inflater
14
14
  def inflate: (string) -> String
15
15
 
16
- def initialize: (Numeric bytesize) -> untyped
16
+ def initialize: (Integer | Float bytesize) -> untyped
17
17
  end
18
18
 
19
19
  def self.configure: (singleton(Session)) -> void
@@ -61,7 +61,7 @@ module HTTPX
61
61
  @boundary: String
62
62
  @intermediate_boundary: String
63
63
 
64
- def call: (Response response, untyped) -> Hash[String, untyped]
64
+ def call: (Response response, *untyped) -> Hash[String, untyped]
65
65
 
66
66
  private
67
67
 
@@ -4,14 +4,15 @@ module HTTPX
4
4
  module Plugins
5
5
  module Proxy
6
6
  module Socks5
7
-
7
+ VERSION: Integer
8
+
8
9
  module ConnectionMethods
9
10
  def __socks5_proxy_connect: () -> void
10
11
  def __socks5_on_packet: (String packet) -> void
11
12
  def __socks5_check_version: (int) -> void
12
13
  def __on_socks5_error: (string) -> void
13
14
  end
14
-
15
+
15
16
  class SocksParser
16
17
  include Callbacks
17
18