httpx 0.21.0 → 0.22.4
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/README.md +53 -35
- data/doc/release_notes/0_10_0.md +2 -2
- data/doc/release_notes/0_11_0.md +3 -5
- data/doc/release_notes/0_12_0.md +5 -5
- data/doc/release_notes/0_13_0.md +4 -4
- data/doc/release_notes/0_14_0.md +2 -2
- data/doc/release_notes/0_16_0.md +3 -3
- data/doc/release_notes/0_17_0.md +1 -1
- data/doc/release_notes/0_18_0.md +4 -4
- data/doc/release_notes/0_18_2.md +1 -1
- data/doc/release_notes/0_19_0.md +1 -1
- data/doc/release_notes/0_20_0.md +1 -1
- data/doc/release_notes/0_21_0.md +7 -5
- data/doc/release_notes/0_21_1.md +12 -0
- data/doc/release_notes/0_22_0.md +13 -0
- data/doc/release_notes/0_22_1.md +11 -0
- data/doc/release_notes/0_22_2.md +5 -0
- data/doc/release_notes/0_22_3.md +55 -0
- data/doc/release_notes/0_22_4.md +6 -0
- data/lib/httpx/adapters/datadog.rb +1 -1
- data/lib/httpx/adapters/faraday.rb +12 -4
- data/lib/httpx/adapters/sentry.rb +6 -2
- data/lib/httpx/connection/http2.rb +1 -1
- data/lib/httpx/connection.rb +34 -6
- data/lib/httpx/errors.rb +2 -0
- data/lib/httpx/extensions.rb +10 -1
- data/lib/httpx/io/tcp.rb +2 -1
- data/lib/httpx/io/udp.rb +4 -5
- data/lib/httpx/options.rb +2 -2
- data/lib/httpx/plugins/authentication.rb +1 -1
- data/lib/httpx/plugins/aws_sigv4.rb +2 -2
- data/lib/httpx/plugins/basic_authentication.rb +1 -1
- data/lib/httpx/plugins/circuit_breaker/circuit.rb +1 -1
- data/lib/httpx/plugins/circuit_breaker.rb +1 -1
- data/lib/httpx/plugins/compression/gzip.rb +1 -1
- data/lib/httpx/plugins/compression.rb +4 -4
- data/lib/httpx/plugins/cookies.rb +1 -1
- data/lib/httpx/plugins/digest_authentication.rb +3 -1
- data/lib/httpx/plugins/expect.rb +4 -3
- data/lib/httpx/plugins/follow_redirects.rb +8 -1
- data/lib/httpx/plugins/grpc/message.rb +1 -1
- data/lib/httpx/plugins/grpc.rb +1 -1
- data/lib/httpx/plugins/h2c.rb +1 -1
- data/lib/httpx/plugins/multipart/decoder.rb +7 -57
- data/lib/httpx/plugins/multipart.rb +2 -2
- data/lib/httpx/plugins/ntlm_authentication.rb +3 -1
- data/lib/httpx/plugins/persistent.rb +1 -1
- data/lib/httpx/plugins/proxy/http.rb +4 -2
- data/lib/httpx/plugins/proxy.rb +1 -1
- data/lib/httpx/plugins/push_promise.rb +1 -1
- data/lib/httpx/plugins/rate_limiter.rb +3 -1
- data/lib/httpx/plugins/response_cache.rb +1 -1
- data/lib/httpx/plugins/retries.rb +3 -2
- data/lib/httpx/plugins/stream.rb +0 -2
- data/lib/httpx/plugins/upgrade.rb +3 -1
- data/lib/httpx/plugins/webdav.rb +2 -0
- data/lib/httpx/pool.rb +41 -2
- data/lib/httpx/request.rb +1 -1
- data/lib/httpx/resolver/https.rb +16 -2
- data/lib/httpx/resolver/native.rb +28 -26
- data/lib/httpx/resolver/resolver.rb +9 -8
- data/lib/httpx/resolver.rb +8 -0
- data/lib/httpx/response.rb +8 -0
- data/lib/httpx/transcoder/xml.rb +0 -2
- data/lib/httpx/transcoder.rb +1 -1
- data/lib/httpx/utils.rb +30 -0
- data/lib/httpx/version.rb +1 -1
- data/lib/httpx.rb +6 -0
- data/sig/connection.rbs +3 -1
- data/sig/plugins/multipart.rbs +0 -2
- data/sig/pool.rbs +3 -1
- data/sig/resolver/https.rbs +3 -2
- data/sig/resolver/native.rbs +2 -1
- data/sig/resolver/resolver.rbs +3 -1
- data/sig/resolver.rbs +1 -1
- data/sig/response.rbs +4 -1
- data/sig/utils.rbs +2 -0
- metadata +21 -9
@@ -9,7 +9,7 @@ module HTTPX
|
|
9
9
|
# * when the server is unavailable (503);
|
10
10
|
# * when a 3xx request comes with a "retry-after" value
|
11
11
|
#
|
12
|
-
# https://gitlab.com/
|
12
|
+
# https://gitlab.com/os85/httpx/wikis/RateLimiter
|
13
13
|
#
|
14
14
|
module RateLimiter
|
15
15
|
class << self
|
@@ -23,6 +23,8 @@ module HTTPX
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def retry_on_rate_limited_response(response)
|
26
|
+
return false unless response.is_a?(Response)
|
27
|
+
|
26
28
|
status = response.status
|
27
29
|
|
28
30
|
RATE_LIMIT_CODES.include?(status)
|
@@ -5,7 +5,7 @@ module HTTPX
|
|
5
5
|
#
|
6
6
|
# This plugin adds support for retrying requests when certain errors happen.
|
7
7
|
#
|
8
|
-
# https://gitlab.com/
|
8
|
+
# https://gitlab.com/os85/httpx/wikis/Response-Cache
|
9
9
|
#
|
10
10
|
module ResponseCache
|
11
11
|
CACHEABLE_VERBS = %i[get head].freeze
|
@@ -5,7 +5,7 @@ module HTTPX
|
|
5
5
|
#
|
6
6
|
# This plugin adds support for retrying requests when certain errors happen.
|
7
7
|
#
|
8
|
-
# https://gitlab.com/
|
8
|
+
# https://gitlab.com/os85/httpx/wikis/Retries
|
9
9
|
#
|
10
10
|
module Retries
|
11
11
|
MAX_RETRIES = 3
|
@@ -23,9 +23,10 @@ module HTTPX
|
|
23
23
|
Parser::Error,
|
24
24
|
TLSError,
|
25
25
|
TimeoutError,
|
26
|
+
ConnectionError,
|
26
27
|
Connection::HTTP2::GoawayError,
|
27
28
|
].freeze
|
28
|
-
DEFAULT_JITTER = ->(interval) { interval * (
|
29
|
+
DEFAULT_JITTER = ->(interval) { interval * ((rand + 1) * 0.5) }
|
29
30
|
|
30
31
|
if ENV.key?("HTTPX_NO_JITTER")
|
31
32
|
def self.extra_options(options)
|
data/lib/httpx/plugins/stream.rb
CHANGED
@@ -35,7 +35,9 @@ module HTTPX
|
|
35
35
|
response = super
|
36
36
|
|
37
37
|
if response
|
38
|
-
return response unless response.
|
38
|
+
return response unless response.is_a?(Response)
|
39
|
+
|
40
|
+
return response unless response.headers.key?("upgrade")
|
39
41
|
|
40
42
|
upgrade_protocol = response.headers["upgrade"].split(/ *, */).first
|
41
43
|
|
data/lib/httpx/plugins/webdav.rb
CHANGED
data/lib/httpx/pool.rb
CHANGED
@@ -72,7 +72,7 @@ module HTTPX
|
|
72
72
|
end
|
73
73
|
|
74
74
|
def init_connection(connection, _options)
|
75
|
-
resolve_connection(connection)
|
75
|
+
resolve_connection(connection) unless connection.family
|
76
76
|
connection.timers = @timers
|
77
77
|
connection.on(:open) do
|
78
78
|
@connected_connections += 1
|
@@ -116,19 +116,57 @@ module HTTPX
|
|
116
116
|
# resolve a name (not the same as name being an IP, yet)
|
117
117
|
# 2. when the connection is initialized with an external already open IO.
|
118
118
|
#
|
119
|
+
connection.once(:connect_error, &connection.method(:handle_error))
|
119
120
|
on_resolver_connection(connection)
|
120
121
|
return
|
121
122
|
end
|
122
123
|
|
123
124
|
find_resolver_for(connection) do |resolver|
|
124
|
-
resolver << connection
|
125
|
+
resolver << try_clone_connection(connection, resolver.family)
|
125
126
|
next if resolver.empty?
|
126
127
|
|
127
128
|
select_connection(resolver)
|
128
129
|
end
|
129
130
|
end
|
130
131
|
|
132
|
+
def try_clone_connection(connection, family)
|
133
|
+
connection.family ||= family
|
134
|
+
|
135
|
+
return connection if connection.family == family
|
136
|
+
|
137
|
+
new_connection = connection.class.new(connection.type, connection.origin, connection.options)
|
138
|
+
new_connection.family = family
|
139
|
+
|
140
|
+
connection.once(:tcp_open) { new_connection.force_reset }
|
141
|
+
connection.once(:connect_error) do |err|
|
142
|
+
if new_connection.connecting?
|
143
|
+
new_connection.merge(connection)
|
144
|
+
else
|
145
|
+
connection.handle_error(err)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
new_connection.once(:tcp_open) do |new_conn|
|
150
|
+
if new_conn != connection
|
151
|
+
new_conn.merge(connection)
|
152
|
+
connection.force_reset
|
153
|
+
end
|
154
|
+
end
|
155
|
+
new_connection.once(:connect_error) do |err|
|
156
|
+
if connection.connecting?
|
157
|
+
# main connection has the requests
|
158
|
+
connection.merge(new_connection)
|
159
|
+
else
|
160
|
+
new_connection.handle_error(err)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
init_connection(new_connection, connection.options)
|
165
|
+
new_connection
|
166
|
+
end
|
167
|
+
|
131
168
|
def on_resolver_connection(connection)
|
169
|
+
@connections << connection unless @connections.include?(connection)
|
132
170
|
found_connection = @connections.find do |ch|
|
133
171
|
ch != connection && ch.mergeable?(connection)
|
134
172
|
end
|
@@ -186,6 +224,7 @@ module HTTPX
|
|
186
224
|
def coalesce_connections(conn1, conn2)
|
187
225
|
return register_connection(conn2) unless conn1.coalescable?(conn2)
|
188
226
|
|
227
|
+
conn2.emit(:tcp_open, conn1)
|
189
228
|
conn1.merge(conn2)
|
190
229
|
@connections.delete(conn2)
|
191
230
|
end
|
data/lib/httpx/request.rb
CHANGED
@@ -86,7 +86,7 @@ module HTTPX
|
|
86
86
|
def response=(response)
|
87
87
|
return unless response
|
88
88
|
|
89
|
-
if response.is_a?(Response) && response.status == 100
|
89
|
+
if response.is_a?(Response) && response.status == 100 && @headers.key?("expect")
|
90
90
|
@informational_status = response.status
|
91
91
|
return
|
92
92
|
end
|
data/lib/httpx/resolver/https.rb
CHANGED
@@ -69,7 +69,8 @@ module HTTPX
|
|
69
69
|
@building_connection = true
|
70
70
|
connection = @options.connection_class.new("ssl", @uri, @options.merge(ssl: { alpn_protocols: %w[h2] }))
|
71
71
|
@pool.init_connection(connection, @options)
|
72
|
-
|
72
|
+
# only explicity emit addresses if connection didn't pre-resolve, i.e. it's not an IP.
|
73
|
+
emit_addresses(connection, @family, @uri_addresses) unless connection.addresses
|
73
74
|
@building_connection = false
|
74
75
|
connection
|
75
76
|
end
|
@@ -135,9 +136,22 @@ module HTTPX
|
|
135
136
|
emit_resolve_error(connection, connection.origin.host, e)
|
136
137
|
return
|
137
138
|
end
|
138
|
-
|
139
|
+
|
140
|
+
if answers.nil?
|
141
|
+
# Indicates no such domain was found.
|
142
|
+
|
139
143
|
host = @requests.delete(request)
|
140
144
|
connection = @queries.delete(host)
|
145
|
+
|
146
|
+
emit_resolve_error(connection) unless @queries.value?(connection)
|
147
|
+
elsif answers.empty?
|
148
|
+
# no address found, eliminate candidates
|
149
|
+
host = @requests.delete(request)
|
150
|
+
connection = @queries.delete(host)
|
151
|
+
|
152
|
+
# eliminate other candidates
|
153
|
+
@queries.delete_if { |_, conn| connection == conn }
|
154
|
+
|
141
155
|
emit_resolve_error(connection)
|
142
156
|
return
|
143
157
|
|
@@ -13,27 +13,15 @@ module HTTPX
|
|
13
13
|
**Resolv::DNS::Config.default_config_hash,
|
14
14
|
packet_size: 512,
|
15
15
|
timeouts: Resolver::RESOLVE_TIMEOUT,
|
16
|
-
}
|
16
|
+
}
|
17
17
|
else
|
18
18
|
{
|
19
19
|
nameserver: nil,
|
20
20
|
**Resolv::DNS::Config.default_config_hash,
|
21
21
|
packet_size: 512,
|
22
22
|
timeouts: Resolver::RESOLVE_TIMEOUT,
|
23
|
-
}
|
24
|
-
end
|
25
|
-
|
26
|
-
# nameservers for ipv6 are misconfigured in certain systems;
|
27
|
-
# this can use an unexpected endless loop
|
28
|
-
# https://gitlab.com/honeyryderchuck/httpx/issues/56
|
29
|
-
DEFAULTS[:nameserver].select! do |nameserver|
|
30
|
-
begin
|
31
|
-
IPAddr.new(nameserver)
|
32
|
-
true
|
33
|
-
rescue IPAddr::InvalidAddressError
|
34
|
-
false
|
35
|
-
end
|
36
|
-
end if DEFAULTS[:nameserver]
|
23
|
+
}
|
24
|
+
end.freeze
|
37
25
|
|
38
26
|
DNS_PORT = 53
|
39
27
|
|
@@ -152,10 +140,21 @@ module HTTPX
|
|
152
140
|
host = connection.origin.host
|
153
141
|
timeout = (@timeouts[host][0] -= loop_time)
|
154
142
|
|
155
|
-
return unless timeout
|
143
|
+
return unless timeout <= 0
|
156
144
|
|
157
145
|
@timeouts[host].shift
|
158
|
-
|
146
|
+
|
147
|
+
if !@timeouts[host].empty?
|
148
|
+
log { "resolver: timeout after #{timeout}s, retry(#{@timeouts[host].first}) #{host}..." }
|
149
|
+
resolve(connection)
|
150
|
+
elsif @ns_index + 1 < @nameserver.size
|
151
|
+
# try on the next nameserver
|
152
|
+
@ns_index += 1
|
153
|
+
log { "resolver: failed resolving #{host} on nameserver #{@nameserver[@ns_index - 1]} (timeout error)" }
|
154
|
+
transition(:idle)
|
155
|
+
resolve(connection)
|
156
|
+
else
|
157
|
+
|
159
158
|
@timeouts.delete(host)
|
160
159
|
@queries.delete(h)
|
161
160
|
|
@@ -165,9 +164,6 @@ module HTTPX
|
|
165
164
|
# This loop_time passed to the exception is bogus. Ideally we would pass the total
|
166
165
|
# resolve timeout, including from the previous retries.
|
167
166
|
raise ResolveTimeoutError.new(loop_time, "Timed out while resolving #{connection.origin.host}")
|
168
|
-
else
|
169
|
-
log { "resolver: timeout after #{timeout}s, retry(#{@timeouts[host].first}) #{host}..." }
|
170
|
-
resolve(connection)
|
171
167
|
end
|
172
168
|
end
|
173
169
|
|
@@ -205,7 +201,8 @@ module HTTPX
|
|
205
201
|
raise ex
|
206
202
|
end
|
207
203
|
|
208
|
-
if addresses.nil?
|
204
|
+
if addresses.nil?
|
205
|
+
# Indicates no such domain was found.
|
209
206
|
hostname, connection = @queries.first
|
210
207
|
@queries.delete(hostname)
|
211
208
|
@timeouts.delete(hostname)
|
@@ -214,6 +211,14 @@ module HTTPX
|
|
214
211
|
@connections.delete(connection)
|
215
212
|
raise NativeResolveError.new(connection, connection.origin.host)
|
216
213
|
end
|
214
|
+
elsif addresses.empty?
|
215
|
+
# no address found, eliminate candidates
|
216
|
+
_, connection = @queries.first
|
217
|
+
candidates = @queries.select { |_, conn| connection == conn }.keys
|
218
|
+
@queries.delete_if { |hs, _| candidates.include?(hs) }
|
219
|
+
@timeouts.delete_if { |hs, _| candidates.include?(hs) }
|
220
|
+
@connections.delete(connection)
|
221
|
+
raise NativeResolveError.new(connection, connection.origin.host)
|
217
222
|
else
|
218
223
|
address = addresses.first
|
219
224
|
name = address["name"]
|
@@ -299,11 +304,8 @@ module HTTPX
|
|
299
304
|
|
300
305
|
ip, port = @nameserver[@ns_index]
|
301
306
|
port ||= DNS_PORT
|
302
|
-
|
303
|
-
|
304
|
-
type = IO.registry(uri.scheme)
|
305
|
-
log { "resolver: server: #{uri}..." }
|
306
|
-
@io = type.new(uri, [IPAddr.new(ip)], @options)
|
307
|
+
log { "resolver: server: #{ip}:#{port}..." }
|
308
|
+
@io = UDP.new(ip, port, @options)
|
307
309
|
end
|
308
310
|
|
309
311
|
def transition(nextstate)
|
@@ -54,7 +54,7 @@ module HTTPX
|
|
54
54
|
# double emission check
|
55
55
|
return if connection.addresses && !addresses.intersect?(connection.addresses)
|
56
56
|
|
57
|
-
log { "resolver: answer #{connection.origin.host}: #{addresses.inspect}" }
|
57
|
+
log { "resolver: answer #{FAMILY_TYPES[RECORD_TYPES[family]]} #{connection.origin.host}: #{addresses.inspect}" }
|
58
58
|
if @pool && # if triggered by early resolve, pool may not be here yet
|
59
59
|
!connection.io &&
|
60
60
|
connection.options.ip_families.size > 1 &&
|
@@ -63,20 +63,21 @@ module HTTPX
|
|
63
63
|
log { "resolver: A response, applying resolution delay..." }
|
64
64
|
@pool.after(0.05) do
|
65
65
|
# double emission check
|
66
|
-
unless connection.addresses && addresses.intersect?(connection.addresses)
|
67
|
-
|
68
|
-
connection.addresses = addresses
|
69
|
-
emit(:resolve, connection)
|
70
|
-
end
|
66
|
+
emit_resolved_connection(connection, addresses) unless connection.addresses && addresses.intersect?(connection.addresses)
|
71
67
|
end
|
72
68
|
else
|
73
|
-
connection
|
74
|
-
emit(:resolve, connection)
|
69
|
+
emit_resolved_connection(connection, addresses)
|
75
70
|
end
|
76
71
|
end
|
77
72
|
|
78
73
|
private
|
79
74
|
|
75
|
+
def emit_resolved_connection(connection, addresses)
|
76
|
+
connection.addresses = addresses
|
77
|
+
|
78
|
+
emit(:resolve, connection)
|
79
|
+
end
|
80
|
+
|
80
81
|
def early_resolve(connection, hostname: connection.origin.host)
|
81
82
|
addresses = @resolver_options[:cache] && (connection.addresses || HTTPX::Resolver.nolookup_resolve(hostname))
|
82
83
|
|
data/lib/httpx/resolver.rb
CHANGED
@@ -108,7 +108,15 @@ module HTTPX
|
|
108
108
|
|
109
109
|
def decode_dns_answer(payload)
|
110
110
|
message = Resolv::DNS::Message.decode(payload)
|
111
|
+
|
112
|
+
# no domain was found
|
113
|
+
return if message.rcode == Resolv::DNS::RCode::NXDomain
|
114
|
+
|
111
115
|
addresses = []
|
116
|
+
|
117
|
+
# TODO: raise an "other dns OtherResolvError" type of error
|
118
|
+
return addresses if message.rcode != Resolv::DNS::RCode::NoError
|
119
|
+
|
112
120
|
message.each_answer do |question, _, value|
|
113
121
|
case value
|
114
122
|
when Resolv::DNS::Resource::IN::CNAME
|
data/lib/httpx/response.rb
CHANGED
@@ -128,6 +128,8 @@ module HTTPX
|
|
128
128
|
end
|
129
129
|
|
130
130
|
class Body
|
131
|
+
attr_reader :encoding
|
132
|
+
|
131
133
|
def initialize(response, options)
|
132
134
|
@response = response
|
133
135
|
@headers = response.headers
|
@@ -179,6 +181,12 @@ module HTTPX
|
|
179
181
|
end
|
180
182
|
end
|
181
183
|
|
184
|
+
def filename
|
185
|
+
return unless @headers.key?("content-disposition")
|
186
|
+
|
187
|
+
Utils.get_filename(@headers["content-disposition"])
|
188
|
+
end
|
189
|
+
|
182
190
|
def to_s
|
183
191
|
case @buffer
|
184
192
|
when StringIO
|
data/lib/httpx/transcoder/xml.rb
CHANGED
@@ -38,7 +38,6 @@ module HTTPX::Transcoder
|
|
38
38
|
begin
|
39
39
|
require "nokogiri"
|
40
40
|
|
41
|
-
# rubocop:disable Lint/DuplicateMethods
|
42
41
|
def decode(response)
|
43
42
|
content_type = response.content_type.mime_type
|
44
43
|
|
@@ -51,7 +50,6 @@ module HTTPX::Transcoder
|
|
51
50
|
raise HTTPX::Error, "\"nokogiri\" is required in order to decode XML"
|
52
51
|
end
|
53
52
|
end
|
54
|
-
# rubocop:enable Lint/DuplicateMethods
|
55
53
|
end
|
56
54
|
register "xml", Xml
|
57
55
|
end
|
data/lib/httpx/transcoder.rb
CHANGED
data/lib/httpx/utils.rb
CHANGED
@@ -3,6 +3,12 @@
|
|
3
3
|
module HTTPX
|
4
4
|
module Utils
|
5
5
|
using URIExtensions
|
6
|
+
using HTTPX::RegexpExtensions unless Regexp.method_defined?(:match?)
|
7
|
+
|
8
|
+
TOKEN = %r{[^\s()<>,;:\\"/\[\]?=]+}.freeze
|
9
|
+
VALUE = /"(?:\\"|[^"])*"|#{TOKEN}/.freeze
|
10
|
+
FILENAME_REGEX = /\s*filename=(#{VALUE})/.freeze
|
11
|
+
FILENAME_EXTENSION_REGEX = /\s*filename\*=(#{VALUE})/.freeze
|
6
12
|
|
7
13
|
module_function
|
8
14
|
|
@@ -25,6 +31,30 @@ module HTTPX
|
|
25
31
|
time - Time.now
|
26
32
|
end
|
27
33
|
|
34
|
+
def get_filename(header, _prefix_regex = nil)
|
35
|
+
filename = nil
|
36
|
+
case header
|
37
|
+
when FILENAME_REGEX
|
38
|
+
filename = Regexp.last_match(1)
|
39
|
+
filename = Regexp.last_match(1) if filename =~ /^"(.*)"$/
|
40
|
+
when FILENAME_EXTENSION_REGEX
|
41
|
+
filename = Regexp.last_match(1)
|
42
|
+
encoding, _, filename = filename.split("'", 3)
|
43
|
+
end
|
44
|
+
|
45
|
+
return unless filename
|
46
|
+
|
47
|
+
filename = URI::DEFAULT_PARSER.unescape(filename) if filename.scan(/%.?.?/).all? { |s| /%[0-9a-fA-F]{2}/.match?(s) }
|
48
|
+
|
49
|
+
filename.scrub!
|
50
|
+
|
51
|
+
filename = filename.gsub(/\\(.)/, '\1') unless /\\[^\\"]/.match?(filename)
|
52
|
+
|
53
|
+
filename.force_encoding ::Encoding.find(encoding) if encoding
|
54
|
+
|
55
|
+
filename
|
56
|
+
end
|
57
|
+
|
28
58
|
if RUBY_VERSION < "2.3"
|
29
59
|
|
30
60
|
def to_uri(uri)
|
data/lib/httpx/version.rb
CHANGED
data/lib/httpx.rb
CHANGED
@@ -67,3 +67,9 @@ end
|
|
67
67
|
|
68
68
|
require "httpx/session"
|
69
69
|
require "httpx/session_extensions"
|
70
|
+
|
71
|
+
# load integrations when possible
|
72
|
+
|
73
|
+
require "httpx/adapters/datadog" if defined?(DDTrace) || defined?(Datadog)
|
74
|
+
require "httpx/adapters/sentry" if defined?(Sentry)
|
75
|
+
require "httpx/adapters/webmock" if defined?(WebMock)
|
data/sig/connection.rbs
CHANGED
@@ -21,6 +21,7 @@ module HTTPX
|
|
21
21
|
|
22
22
|
BUFFER_SIZE: Integer
|
23
23
|
|
24
|
+
attr_reader type: io_type
|
24
25
|
attr_reader origin: URI::Generic
|
25
26
|
attr_reader origins: Array[String]
|
26
27
|
attr_reader state: Symbol
|
@@ -28,7 +29,8 @@ module HTTPX
|
|
28
29
|
attr_reader options: Options
|
29
30
|
attr_writer timers: Timers
|
30
31
|
|
31
|
-
|
32
|
+
attr_accessor family: Integer?
|
33
|
+
|
32
34
|
@window_size: Integer
|
33
35
|
@read_buffer: Buffer
|
34
36
|
@write_buffer: Buffer
|
data/sig/plugins/multipart.rbs
CHANGED
data/sig/pool.rbs
CHANGED
data/sig/resolver/https.rbs
CHANGED
@@ -6,7 +6,8 @@ module HTTPX
|
|
6
6
|
DEFAULTS: Hash[Symbol, untyped]
|
7
7
|
FAMILY_TYPES: Hash[singleton(Resolv::DNS::Resource), String]
|
8
8
|
|
9
|
-
|
9
|
+
attr_reader family: ip_family
|
10
|
+
|
10
11
|
@options: Options
|
11
12
|
@requests: Hash[Request, String]
|
12
13
|
@connections: Array[Connection]
|
@@ -33,7 +34,7 @@ module HTTPX
|
|
33
34
|
|
34
35
|
def build_request: (String hostname) -> Request
|
35
36
|
|
36
|
-
def decode_response_body: (Response) -> Array[dns_result]
|
37
|
+
def decode_response_body: (Response) -> Array[dns_result]?
|
37
38
|
end
|
38
39
|
end
|
39
40
|
end
|
data/sig/resolver/native.rbs
CHANGED
data/sig/resolver/resolver.rbs
CHANGED
@@ -6,7 +6,7 @@ module HTTPX
|
|
6
6
|
|
7
7
|
RECORD_TYPES: Hash[Integer, singleton(Resolv::DNS::Resource)]
|
8
8
|
|
9
|
-
attr_reader family: ip_family
|
9
|
+
attr_reader family: ip_family?
|
10
10
|
|
11
11
|
@record_type: singleton(Resolv::DNS::Resource)
|
12
12
|
@options: Options
|
@@ -24,6 +24,8 @@ module HTTPX
|
|
24
24
|
|
25
25
|
private
|
26
26
|
|
27
|
+
def emit_resolved_connection: (Connection connection, Array[IPAddr] addresses) -> void
|
28
|
+
|
27
29
|
def initialize: (ip_family? family, options options) -> void
|
28
30
|
|
29
31
|
def early_resolve: (Connection connection, ?hostname: String) -> void
|
data/sig/resolver.rbs
CHANGED
data/sig/response.rbs
CHANGED
@@ -48,13 +48,14 @@ module HTTPX
|
|
48
48
|
include _ToS
|
49
49
|
include _ToStr
|
50
50
|
|
51
|
+
attr_reader encoding: String
|
52
|
+
|
51
53
|
@response: Response
|
52
54
|
@headers: Headers
|
53
55
|
@options: Options
|
54
56
|
@state: :idle | :memory | :buffer | :closed
|
55
57
|
@threshold_size: Integer
|
56
58
|
@window_size: Integer
|
57
|
-
@encoding: String
|
58
59
|
@length: Integer
|
59
60
|
@buffer: StringIO | Tempfile | nil
|
60
61
|
|
@@ -63,6 +64,8 @@ module HTTPX
|
|
63
64
|
def each: () { (String) -> void } -> void
|
64
65
|
| () -> Enumerable[String]
|
65
66
|
|
67
|
+
def filename: () -> String?
|
68
|
+
|
66
69
|
def bytesize: () -> (Integer | Float)
|
67
70
|
def empty?: () -> bool
|
68
71
|
def copy_to: (String | File | _Writer destination) -> void
|