httpx 0.18.6 → 0.19.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +5 -1
- data/doc/release_notes/0_18_5.md +2 -2
- data/doc/release_notes/0_18_7.md +5 -0
- data/doc/release_notes/0_19_0.md +39 -0
- data/doc/release_notes/0_19_1.md +5 -0
- data/doc/release_notes/0_19_2.md +7 -0
- data/lib/httpx/adapters/faraday.rb +7 -3
- data/lib/httpx/connection/http1.rb +5 -5
- data/lib/httpx/connection/http2.rb +1 -5
- data/lib/httpx/connection.rb +22 -10
- data/lib/httpx/extensions.rb +16 -0
- data/lib/httpx/headers.rb +0 -2
- data/lib/httpx/io/tcp.rb +27 -6
- data/lib/httpx/options.rb +44 -11
- data/lib/httpx/plugins/cookies.rb +5 -7
- data/lib/httpx/plugins/internal_telemetry.rb +1 -1
- data/lib/httpx/plugins/multipart/mime_type_detector.rb +5 -1
- data/lib/httpx/plugins/proxy/http.rb +10 -23
- data/lib/httpx/plugins/proxy/socks4.rb +1 -1
- data/lib/httpx/plugins/proxy/socks5.rb +1 -1
- data/lib/httpx/plugins/proxy.rb +20 -12
- data/lib/httpx/plugins/retries.rb +1 -1
- data/lib/httpx/pool.rb +40 -20
- data/lib/httpx/resolver/https.rb +32 -42
- data/lib/httpx/resolver/multi.rb +79 -0
- data/lib/httpx/resolver/native.rb +28 -36
- data/lib/httpx/resolver/resolver.rb +93 -0
- data/lib/httpx/resolver/system.rb +175 -19
- data/lib/httpx/resolver.rb +37 -11
- data/lib/httpx/response.rb +4 -2
- data/lib/httpx/session.rb +1 -15
- data/lib/httpx/session_extensions.rb +26 -0
- data/lib/httpx/timers.rb +1 -1
- data/lib/httpx/transcoder/chunker.rb +0 -1
- data/lib/httpx/version.rb +1 -1
- data/lib/httpx.rb +3 -0
- data/sig/connection/http1.rbs +0 -2
- data/sig/connection/http2.rbs +2 -2
- data/sig/connection.rbs +1 -0
- data/sig/errors.rbs +8 -0
- data/sig/headers.rbs +0 -2
- data/sig/httpx.rbs +4 -0
- data/sig/options.rbs +10 -7
- data/sig/parser/http1.rbs +14 -5
- data/sig/pool.rbs +17 -9
- data/sig/registry.rbs +3 -0
- data/sig/request.rbs +11 -0
- data/sig/resolver/https.rbs +15 -27
- data/sig/resolver/multi.rbs +7 -0
- data/sig/resolver/native.rbs +3 -12
- data/sig/resolver/resolver.rbs +36 -0
- data/sig/resolver/system.rbs +3 -9
- data/sig/resolver.rbs +12 -10
- data/sig/response.rbs +15 -5
- data/sig/selector.rbs +3 -3
- data/sig/timers.rbs +5 -2
- data/sig/transcoder/chunker.rbs +16 -5
- data/sig/transcoder/json.rbs +5 -0
- data/sig/transcoder.rbs +3 -1
- metadata +15 -4
- data/lib/httpx/resolver/resolver_mixin.rb +0 -75
- data/sig/resolver/resolver_mixin.rbs +0 -26
@@ -0,0 +1,93 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "resolv"
|
4
|
+
require "ipaddr"
|
5
|
+
|
6
|
+
module HTTPX
|
7
|
+
class Resolver::Resolver
|
8
|
+
include Callbacks
|
9
|
+
include Loggable
|
10
|
+
|
11
|
+
RECORD_TYPES = {
|
12
|
+
Socket::AF_INET6 => Resolv::DNS::Resource::IN::AAAA,
|
13
|
+
Socket::AF_INET => Resolv::DNS::Resource::IN::A,
|
14
|
+
}.freeze
|
15
|
+
|
16
|
+
FAMILY_TYPES = {
|
17
|
+
Resolv::DNS::Resource::IN::AAAA => "AAAA",
|
18
|
+
Resolv::DNS::Resource::IN::A => "A",
|
19
|
+
}.freeze
|
20
|
+
|
21
|
+
class << self
|
22
|
+
def multi?
|
23
|
+
true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
attr_reader :family
|
28
|
+
|
29
|
+
attr_writer :pool
|
30
|
+
|
31
|
+
def initialize(family, options)
|
32
|
+
@family = family
|
33
|
+
@record_type = RECORD_TYPES[family]
|
34
|
+
@options = Options.new(options)
|
35
|
+
end
|
36
|
+
|
37
|
+
def close; end
|
38
|
+
|
39
|
+
def closed?
|
40
|
+
true
|
41
|
+
end
|
42
|
+
|
43
|
+
def empty?
|
44
|
+
true
|
45
|
+
end
|
46
|
+
|
47
|
+
def emit_addresses(connection, family, addresses)
|
48
|
+
addresses.map! do |address|
|
49
|
+
address.is_a?(IPAddr) ? address : IPAddr.new(address.to_s)
|
50
|
+
end
|
51
|
+
log { "resolver: answer #{connection.origin.host}: #{addresses.inspect}" }
|
52
|
+
if @pool && # if triggered by early resolve, pool may not be here yet
|
53
|
+
!connection.io &&
|
54
|
+
connection.options.ip_families.size > 1 &&
|
55
|
+
family == Socket::AF_INET &&
|
56
|
+
addresses.first.to_s != connection.origin.host.to_s
|
57
|
+
log { "resolver: A response, applying resolution delay..." }
|
58
|
+
@pool.after(0.05) do
|
59
|
+
connection.addresses = addresses
|
60
|
+
emit(:resolve, connection)
|
61
|
+
end
|
62
|
+
else
|
63
|
+
connection.addresses = addresses
|
64
|
+
emit(:resolve, connection)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def early_resolve(connection, hostname: connection.origin.host)
|
71
|
+
addresses = @resolver_options[:cache] && (connection.addresses || HTTPX::Resolver.nolookup_resolve(hostname))
|
72
|
+
|
73
|
+
return unless addresses
|
74
|
+
|
75
|
+
addresses.select! { |addr| addr.family == @family }
|
76
|
+
|
77
|
+
emit_addresses(connection, @family, addresses)
|
78
|
+
end
|
79
|
+
|
80
|
+
def emit_resolve_error(connection, hostname = connection.origin.host, ex = nil)
|
81
|
+
emit(:error, connection, resolve_error(hostname, ex))
|
82
|
+
end
|
83
|
+
|
84
|
+
def resolve_error(hostname, ex = nil)
|
85
|
+
return ex if ex.is_a?(ResolveError)
|
86
|
+
|
87
|
+
message = ex ? ex.message : "Can't resolve #{hostname}"
|
88
|
+
error = ResolveError.new(message)
|
89
|
+
error.set_backtrace(ex ? ex.backtrace : caller)
|
90
|
+
error
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -4,48 +4,204 @@ require "forwardable"
|
|
4
4
|
require "resolv"
|
5
5
|
|
6
6
|
module HTTPX
|
7
|
-
class Resolver::System
|
8
|
-
|
7
|
+
class Resolver::System < Resolver::Resolver
|
8
|
+
using URIExtensions
|
9
|
+
extend Forwardable
|
9
10
|
|
10
11
|
RESOLV_ERRORS = [Resolv::ResolvError,
|
11
12
|
Resolv::DNS::Requester::RequestError,
|
12
13
|
Resolv::DNS::EncodeError,
|
13
14
|
Resolv::DNS::DecodeError].freeze
|
14
15
|
|
16
|
+
DONE = 1
|
17
|
+
ERROR = 2
|
18
|
+
|
19
|
+
class << self
|
20
|
+
def multi?
|
21
|
+
false
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
15
25
|
attr_reader :state
|
16
26
|
|
27
|
+
def_delegator :@connections, :empty?
|
28
|
+
|
17
29
|
def initialize(options)
|
18
|
-
|
30
|
+
super(nil, options)
|
19
31
|
@resolver_options = @options.resolver_options
|
20
|
-
@state = :idle
|
21
32
|
resolv_options = @resolver_options.dup
|
22
|
-
timeouts = resolv_options.delete(:timeouts)
|
33
|
+
timeouts = resolv_options.delete(:timeouts) || Resolver::RESOLVE_TIMEOUT
|
34
|
+
@_timeouts = Array(timeouts)
|
35
|
+
@timeouts = Hash.new { |tims, host| tims[host] = @_timeouts.dup }
|
23
36
|
resolv_options.delete(:cache)
|
24
|
-
@
|
25
|
-
@
|
37
|
+
@connections = []
|
38
|
+
@queries = []
|
39
|
+
@ips = []
|
40
|
+
@pipe_mutex = Thread::Mutex.new
|
41
|
+
@state = :idle
|
42
|
+
end
|
43
|
+
|
44
|
+
def resolvers
|
45
|
+
return enum_for(__method__) unless block_given?
|
46
|
+
|
47
|
+
yield self
|
48
|
+
end
|
49
|
+
|
50
|
+
def connections
|
51
|
+
EMPTY
|
52
|
+
end
|
53
|
+
|
54
|
+
def close
|
55
|
+
transition(:closed)
|
26
56
|
end
|
27
57
|
|
28
58
|
def closed?
|
29
|
-
|
59
|
+
@state == :closed
|
60
|
+
end
|
61
|
+
|
62
|
+
def to_io
|
63
|
+
@pipe_read.to_io
|
64
|
+
end
|
65
|
+
|
66
|
+
def call
|
67
|
+
case @state
|
68
|
+
when :open
|
69
|
+
consume
|
70
|
+
end
|
71
|
+
nil
|
30
72
|
end
|
31
73
|
|
32
|
-
def
|
33
|
-
|
74
|
+
def interests
|
75
|
+
return if @queries.empty?
|
76
|
+
|
77
|
+
:r
|
78
|
+
end
|
79
|
+
|
80
|
+
def timeout
|
81
|
+
return unless @queries.empty?
|
82
|
+
|
83
|
+
_, connection = @queries.first
|
84
|
+
|
85
|
+
@timeouts[connection.origin.host].first
|
34
86
|
end
|
35
87
|
|
36
88
|
def <<(connection)
|
89
|
+
@connections << connection
|
90
|
+
resolve
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
def transition(nextstate)
|
96
|
+
case nextstate
|
97
|
+
when :idle
|
98
|
+
@timeouts.clear
|
99
|
+
when :open
|
100
|
+
return unless @state == :idle
|
101
|
+
|
102
|
+
@pipe_read, @pipe_write = ::IO.pipe
|
103
|
+
when :closed
|
104
|
+
return unless @state == :open
|
105
|
+
|
106
|
+
@pipe_write.close
|
107
|
+
@pipe_read.close
|
108
|
+
end
|
109
|
+
@state = nextstate
|
110
|
+
end
|
111
|
+
|
112
|
+
def consume
|
113
|
+
return if @connections.empty?
|
114
|
+
|
115
|
+
while @pipe_read.ready? && (event = @pipe_read.getbyte)
|
116
|
+
case event
|
117
|
+
when DONE
|
118
|
+
*pair, addrs = @pipe_mutex.synchronize { @ips.pop }
|
119
|
+
@queries.delete(pair)
|
120
|
+
|
121
|
+
family, connection = pair
|
122
|
+
emit_addresses(connection, family, addrs)
|
123
|
+
when ERROR
|
124
|
+
*pair, error = @pipe_mutex.synchronize { @ips.pop }
|
125
|
+
@queries.delete(pair)
|
126
|
+
|
127
|
+
family, connection = pair
|
128
|
+
emit_resolve_error(connection, connection.origin.host, error)
|
129
|
+
end
|
130
|
+
|
131
|
+
@connections.delete(connection) if @queries.empty?
|
132
|
+
end
|
133
|
+
|
134
|
+
return emit(:close, self) if @connections.empty?
|
135
|
+
|
136
|
+
resolve
|
137
|
+
end
|
138
|
+
|
139
|
+
def resolve(connection = @connections.first)
|
140
|
+
raise Error, "no URI to resolve" unless connection
|
141
|
+
return unless @queries.empty?
|
142
|
+
|
37
143
|
hostname = connection.origin.host
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
throw(:resolve_error, resolve_error(hostname)) if addresses.empty?
|
144
|
+
scheme = connection.origin.scheme
|
145
|
+
log { "resolver: resolve IDN #{connection.origin.non_ascii_hostname} as #{hostname}" } if connection.origin.non_ascii_hostname
|
146
|
+
|
147
|
+
transition(:open)
|
43
148
|
|
44
|
-
|
45
|
-
|
46
|
-
|
149
|
+
connection.options.ip_families.each do |family|
|
150
|
+
@queries << [family, connection]
|
151
|
+
end
|
152
|
+
async_resolve(connection, hostname, scheme)
|
153
|
+
consume
|
47
154
|
end
|
48
155
|
|
49
|
-
def
|
156
|
+
def async_resolve(connection, hostname, scheme)
|
157
|
+
families = connection.options.ip_families
|
158
|
+
log { "resolver: query for #{hostname}" }
|
159
|
+
resolve_timeout = @timeouts[connection.origin.host].first
|
160
|
+
|
161
|
+
Thread.start do
|
162
|
+
Thread.current.report_on_exception = false
|
163
|
+
begin
|
164
|
+
addrs = if resolve_timeout
|
165
|
+
Timeout.timeout(resolve_timeout) do
|
166
|
+
__addrinfo_resolve(hostname, scheme)
|
167
|
+
end
|
168
|
+
else
|
169
|
+
__addrinfo_resolve(hostname, scheme)
|
170
|
+
end
|
171
|
+
addrs = addrs.sort_by(&:afamily).group_by(&:afamily)
|
172
|
+
families.each do |family|
|
173
|
+
addresses = addrs[family]
|
174
|
+
next unless addresses
|
175
|
+
|
176
|
+
addresses.map!(&:ip_address)
|
177
|
+
addresses.uniq!
|
178
|
+
@pipe_mutex.synchronize do
|
179
|
+
@ips.unshift([family, connection, addresses])
|
180
|
+
@pipe_write.putc(DONE) unless @pipe_write.closed?
|
181
|
+
end
|
182
|
+
end
|
183
|
+
rescue Timeout::Error => e
|
184
|
+
ex = ResolveTimeoutError.new(resolve_timeout, e.message)
|
185
|
+
ex.set_backtrace(ex.backtrace)
|
186
|
+
@pipe_mutex.synchronize do
|
187
|
+
families.each do |family|
|
188
|
+
@ips.unshift([family, connection, ex])
|
189
|
+
@pipe_write.putc(ERROR) unless @pipe_write.closed?
|
190
|
+
end
|
191
|
+
end
|
192
|
+
rescue StandardError => e
|
193
|
+
@pipe_mutex.synchronize do
|
194
|
+
families.each do |family|
|
195
|
+
@ips.unshift([family, connection, e])
|
196
|
+
@pipe_write.putc(ERROR) unless @pipe_write.closed?
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
def __addrinfo_resolve(host, scheme)
|
204
|
+
Addrinfo.getaddrinfo(host, scheme, Socket::AF_UNSPEC, Socket::SOCK_STREAM)
|
205
|
+
end
|
50
206
|
end
|
51
207
|
end
|
data/lib/httpx/resolver.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "resolv"
|
4
|
+
require "ipaddr"
|
4
5
|
|
5
6
|
module HTTPX
|
6
7
|
module Resolver
|
@@ -8,10 +9,11 @@ module HTTPX
|
|
8
9
|
|
9
10
|
RESOLVE_TIMEOUT = 5
|
10
11
|
|
11
|
-
require "httpx/resolver/
|
12
|
+
require "httpx/resolver/resolver"
|
12
13
|
require "httpx/resolver/system"
|
13
14
|
require "httpx/resolver/native"
|
14
15
|
require "httpx/resolver/https"
|
16
|
+
require "httpx/resolver/multi"
|
15
17
|
|
16
18
|
register :system, System
|
17
19
|
register :native, Native
|
@@ -22,9 +24,27 @@ module HTTPX
|
|
22
24
|
|
23
25
|
@identifier_mutex = Mutex.new
|
24
26
|
@identifier = 1
|
27
|
+
@system_resolver = Resolv::Hosts.new
|
25
28
|
|
26
29
|
module_function
|
27
30
|
|
31
|
+
def nolookup_resolve(hostname)
|
32
|
+
ip_resolve(hostname) || cached_lookup(hostname) || system_resolve(hostname)
|
33
|
+
end
|
34
|
+
|
35
|
+
def ip_resolve(hostname)
|
36
|
+
[IPAddr.new(hostname)]
|
37
|
+
rescue ArgumentError
|
38
|
+
end
|
39
|
+
|
40
|
+
def system_resolve(hostname)
|
41
|
+
ips = @system_resolver.getaddresses(hostname)
|
42
|
+
return if ips.empty?
|
43
|
+
|
44
|
+
ips.map { |ip| IPAddr.new(ip) }
|
45
|
+
rescue IOError
|
46
|
+
end
|
47
|
+
|
28
48
|
def cached_lookup(hostname)
|
29
49
|
now = Utils.now
|
30
50
|
@lookup_mutex.synchronize do
|
@@ -32,25 +52,31 @@ module HTTPX
|
|
32
52
|
end
|
33
53
|
end
|
34
54
|
|
35
|
-
def cached_lookup_set(hostname, entries)
|
55
|
+
def cached_lookup_set(hostname, family, entries)
|
36
56
|
now = Utils.now
|
37
57
|
entries.each do |entry|
|
38
58
|
entry["TTL"] += now
|
39
59
|
end
|
40
60
|
@lookup_mutex.synchronize do
|
41
|
-
|
61
|
+
case family
|
62
|
+
when Socket::AF_INET6
|
63
|
+
@lookups[hostname].concat(entries)
|
64
|
+
when Socket::AF_INET
|
65
|
+
@lookups[hostname].unshift(*entries)
|
66
|
+
end
|
42
67
|
entries.each do |entry|
|
43
|
-
|
68
|
+
next unless entry["name"] != hostname
|
69
|
+
|
70
|
+
case family
|
71
|
+
when Socket::AF_INET6
|
72
|
+
@lookups[entry["name"]] << entry
|
73
|
+
when Socket::AF_INET
|
74
|
+
@lookups[entry["name"]].unshift(entry)
|
75
|
+
end
|
44
76
|
end
|
45
77
|
end
|
46
78
|
end
|
47
79
|
|
48
|
-
def uncache(hostname)
|
49
|
-
@lookup_mutex.synchronize do
|
50
|
-
@lookups.delete(hostname)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
80
|
# do not use directly!
|
55
81
|
def lookup(hostname, ttl)
|
56
82
|
return unless @lookups.key?(hostname)
|
@@ -62,7 +88,7 @@ module HTTPX
|
|
62
88
|
if address.key?("alias")
|
63
89
|
lookup(address["alias"], ttl)
|
64
90
|
else
|
65
|
-
address["data"]
|
91
|
+
IPAddr.new(address["data"])
|
66
92
|
end
|
67
93
|
end
|
68
94
|
ips unless ips.empty?
|
data/lib/httpx/response.rb
CHANGED
@@ -173,7 +173,7 @@ module HTTPX
|
|
173
173
|
rescue ArgumentError
|
174
174
|
@buffer.string
|
175
175
|
end
|
176
|
-
when Tempfile
|
176
|
+
when Tempfile
|
177
177
|
rewind
|
178
178
|
content = _with_same_buffer_pos { @buffer.read }
|
179
179
|
begin
|
@@ -253,6 +253,7 @@ module HTTPX
|
|
253
253
|
@buffer = StringIO.new("".b)
|
254
254
|
end
|
255
255
|
when :memory
|
256
|
+
# @type ivar @buffer: StringIO | Tempfile
|
256
257
|
if @length > @threshold_size
|
257
258
|
aux = @buffer
|
258
259
|
@buffer = Tempfile.new("httpx", encoding: Encoding::BINARY, mode: File::RDWR)
|
@@ -272,11 +273,12 @@ module HTTPX
|
|
272
273
|
def _with_same_buffer_pos
|
273
274
|
return yield unless @buffer && @buffer.respond_to?(:pos)
|
274
275
|
|
276
|
+
# @type ivar @buffer: StringIO | Tempfile
|
275
277
|
current_pos = @buffer.pos
|
276
278
|
@buffer.rewind
|
277
279
|
begin
|
278
280
|
yield
|
279
|
-
|
281
|
+
ensure
|
280
282
|
@buffer.pos = current_pos
|
281
283
|
end
|
282
284
|
end
|
data/lib/httpx/session.rb
CHANGED
@@ -207,7 +207,7 @@ module HTTPX
|
|
207
207
|
|
208
208
|
return responses unless request
|
209
209
|
|
210
|
-
pool.next_tick until (response = fetch_response(request, connections, request.options))
|
210
|
+
catch(:coalesced) { pool.next_tick } until (response = fetch_response(request, connections, request.options))
|
211
211
|
|
212
212
|
responses << response
|
213
213
|
requests.shift
|
@@ -309,18 +309,4 @@ module HTTPX
|
|
309
309
|
# :nocov:
|
310
310
|
end
|
311
311
|
end
|
312
|
-
|
313
|
-
unless ENV.grep(/https?_proxy$/i).empty?
|
314
|
-
proxy_session = plugin(:proxy)
|
315
|
-
::HTTPX.send(:remove_const, :Session)
|
316
|
-
::HTTPX.send(:const_set, :Session, proxy_session.class)
|
317
|
-
end
|
318
|
-
|
319
|
-
# :nocov:
|
320
|
-
if Session.default_options.debug_level > 2
|
321
|
-
proxy_session = plugin(:internal_telemetry)
|
322
|
-
::HTTPX.send(:remove_const, :Session)
|
323
|
-
::HTTPX.send(:const_set, :Session, proxy_session.class)
|
324
|
-
end
|
325
|
-
# :nocov:
|
326
312
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module HTTPX
|
4
|
+
unless ENV.keys.grep(/\Ahttps?_proxy\z/i).empty?
|
5
|
+
proxy_session = plugin(:proxy)
|
6
|
+
remove_const(:Session)
|
7
|
+
const_set(:Session, proxy_session.class)
|
8
|
+
|
9
|
+
# redefine the default options static var, which needs to
|
10
|
+
# refresh options_class
|
11
|
+
options = proxy_session.class.default_options.to_hash
|
12
|
+
options.freeze
|
13
|
+
original_verbosity = $VERBOSE
|
14
|
+
$VERBOSE = nil
|
15
|
+
Options.send(:const_set, :DEFAULT_OPTIONS, options)
|
16
|
+
$VERBOSE = original_verbosity
|
17
|
+
end
|
18
|
+
|
19
|
+
# :nocov:
|
20
|
+
if Session.default_options.debug_level > 2
|
21
|
+
proxy_session = plugin(:internal_telemetry)
|
22
|
+
remove_const(:Session)
|
23
|
+
const_set(:Session, proxy_session.class)
|
24
|
+
end
|
25
|
+
# :nocov:
|
26
|
+
end
|
data/lib/httpx/timers.rb
CHANGED
data/lib/httpx/version.rb
CHANGED
data/lib/httpx.rb
CHANGED
@@ -25,6 +25,8 @@ require "mutex_m"
|
|
25
25
|
# Top-Level Namespace
|
26
26
|
#
|
27
27
|
module HTTPX
|
28
|
+
EMPTY = [].freeze
|
29
|
+
|
28
30
|
# All plugins should be stored under this module/namespace. Can register and load
|
29
31
|
# plugins.
|
30
32
|
#
|
@@ -64,3 +66,4 @@ module HTTPX
|
|
64
66
|
end
|
65
67
|
|
66
68
|
require "httpx/session"
|
69
|
+
require "httpx/session_extensions"
|
data/sig/connection/http1.rbs
CHANGED
data/sig/connection/http2.rbs
CHANGED
@@ -46,8 +46,6 @@ module HTTPX
|
|
46
46
|
|
47
47
|
def send_pending: () -> void
|
48
48
|
|
49
|
-
def headline_uri: (Request) -> String
|
50
|
-
|
51
49
|
def set_protocol_headers: (Request) -> _Each[[String, String]]
|
52
50
|
|
53
51
|
def handle: (Request request, HTTP2Next::Stream stream) -> void
|
@@ -56,6 +54,8 @@ module HTTPX
|
|
56
54
|
|
57
55
|
def handle_stream: (HTTP2Next::Stream stream, Request request) -> void
|
58
56
|
|
57
|
+
def join_headline: (Request request) -> String
|
58
|
+
|
59
59
|
def join_headers: (HTTP2Next::Stream stream, Request request) -> void
|
60
60
|
|
61
61
|
def join_trailers: (HTTP2Next::Stream stream, Request request) -> void
|
data/sig/connection.rbs
CHANGED
data/sig/errors.rbs
CHANGED
@@ -26,6 +26,14 @@ module HTTPX
|
|
26
26
|
class ResolveError < Error
|
27
27
|
end
|
28
28
|
|
29
|
+
class HTTPError < Error
|
30
|
+
attr_reader response: Response
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def initialize: (Response response) -> void
|
35
|
+
end
|
36
|
+
|
29
37
|
class NativeResolveError < ResolveError
|
30
38
|
attr_reader connection: Connection
|
31
39
|
attr_reader host: String
|
data/sig/headers.rbs
CHANGED
data/sig/httpx.rbs
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
module HTTPX
|
2
2
|
extend Chainable
|
3
3
|
|
4
|
+
EMPTY: Array[untyped]
|
5
|
+
|
4
6
|
VERSION: String
|
5
7
|
|
6
8
|
type uri = URI::HTTP | URI::HTTPS | string
|
@@ -10,6 +12,8 @@ module HTTPX
|
|
10
12
|
:propfind | :proppatch | :mkcol | :copy | :move | :lock | :unlock | :orderpatch |
|
11
13
|
:acl | :report | :patch | :search
|
12
14
|
|
15
|
+
type ip_family = Integer #Socket::AF_INET6 | Socket::AF_INET
|
16
|
+
|
13
17
|
module Plugins
|
14
18
|
def self?.load_plugin: (Symbol) -> Module
|
15
19
|
|
data/sig/options.rbs
CHANGED
@@ -83,18 +83,16 @@ module HTTPX
|
|
83
83
|
|
84
84
|
attr_reader response_body_class: singleton(Response::Body)
|
85
85
|
|
86
|
-
attr_reader
|
86
|
+
attr_reader resolver_class: Symbol | Class
|
87
87
|
|
88
|
-
|
89
|
-
# response_body_class connection_class
|
90
|
-
# resolver_class resolver_options
|
88
|
+
attr_reader ssl: Hash[Symbol, untyped]
|
91
89
|
|
92
90
|
# io
|
93
91
|
type io_option = _ToIO | Hash[String, _ToIO]
|
94
92
|
attr_reader io: io_option?
|
95
93
|
|
96
94
|
# fallback_protocol
|
97
|
-
attr_reader fallback_protocol: String
|
95
|
+
attr_reader fallback_protocol: String
|
98
96
|
|
99
97
|
# debug
|
100
98
|
attr_reader debug: _IOLogger?
|
@@ -103,10 +101,13 @@ module HTTPX
|
|
103
101
|
attr_reader debug_level: Integer
|
104
102
|
|
105
103
|
# persistent
|
106
|
-
attr_reader persistent: bool
|
104
|
+
attr_reader persistent: bool
|
107
105
|
|
108
106
|
# resolver_options
|
109
|
-
attr_reader resolver_options: Hash[Symbol, untyped]
|
107
|
+
attr_reader resolver_options: Hash[Symbol, untyped]
|
108
|
+
|
109
|
+
# ip_families
|
110
|
+
attr_reader ip_families: Array[ip_family]
|
110
111
|
|
111
112
|
def ==: (untyped other) -> bool
|
112
113
|
def merge: (_ToHash[Symbol, untyped] other) -> instance
|
@@ -117,6 +118,8 @@ module HTTPX
|
|
117
118
|
REQUEST_IVARS: Array[Symbol]
|
118
119
|
|
119
120
|
def initialize: (?options options) -> untyped
|
121
|
+
|
122
|
+
def __initialize__: (?options options) -> untyped
|
120
123
|
end
|
121
124
|
|
122
125
|
type options = Options | Hash[Symbol, untyped]
|