httpx 0.18.4 → 0.19.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.
- checksums.yaml +4 -4
- data/doc/release_notes/0_18_3.md +1 -1
- data/doc/release_notes/0_18_4.md +2 -2
- data/doc/release_notes/0_18_5.md +10 -0
- data/doc/release_notes/0_18_6.md +5 -0
- data/doc/release_notes/0_18_7.md +5 -0
- data/doc/release_notes/0_19_0.md +39 -0
- data/lib/httpx/adapters/faraday.rb +7 -3
- data/lib/httpx/connection/http1.rb +6 -6
- data/lib/httpx/connection/http2.rb +7 -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 +7 -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 +35 -15
- 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 +92 -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,92 @@
|
|
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 !connection.io &&
|
53
|
+
connection.options.ip_families.size > 1 &&
|
54
|
+
family == Socket::AF_INET &&
|
55
|
+
addresses.first.to_s != connection.origin.host.to_s
|
56
|
+
log { "resolver: A response, applying resolution delay..." }
|
57
|
+
@pool.after(0.05) do
|
58
|
+
connection.addresses = addresses
|
59
|
+
emit(:resolve, connection)
|
60
|
+
end
|
61
|
+
else
|
62
|
+
connection.addresses = addresses
|
63
|
+
emit(:resolve, connection)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def early_resolve(connection, hostname: connection.origin.host)
|
70
|
+
addresses = @resolver_options[:cache] && (connection.addresses || HTTPX::Resolver.nolookup_resolve(hostname))
|
71
|
+
|
72
|
+
return unless addresses
|
73
|
+
|
74
|
+
addresses.select! { |addr| addr.family == @family }
|
75
|
+
|
76
|
+
emit_addresses(connection, @family, addresses)
|
77
|
+
end
|
78
|
+
|
79
|
+
def emit_resolve_error(connection, hostname = connection.origin.host, ex = nil)
|
80
|
+
emit(:error, connection, resolve_error(hostname, ex))
|
81
|
+
end
|
82
|
+
|
83
|
+
def resolve_error(hostname, ex = nil)
|
84
|
+
return ex if ex.is_a?(ResolveError)
|
85
|
+
|
86
|
+
message = ex ? ex.message : "Can't resolve #{hostname}"
|
87
|
+
error = ResolveError.new(message)
|
88
|
+
error.set_backtrace(ex ? ex.backtrace : caller)
|
89
|
+
error
|
90
|
+
end
|
91
|
+
end
|
92
|
+
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]
|