httpx 0.20.1 → 0.20.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/doc/release_notes/0_20_2.md +7 -0
- data/doc/release_notes/0_20_3.md +6 -0
- data/doc/release_notes/0_24_4.md +17 -0
- data/lib/httpx/connection.rb +6 -0
- data/lib/httpx/extensions.rb +28 -9
- data/lib/httpx/io/ssl.rb +6 -6
- data/lib/httpx/plugins/compression.rb +1 -1
- data/lib/httpx/plugins/response_cache/store.rb +39 -19
- data/lib/httpx/plugins/response_cache.rb +98 -8
- data/lib/httpx/pool.rb +1 -1
- data/lib/httpx/resolver/https.rb +1 -0
- data/lib/httpx/resolver/multi.rb +1 -1
- data/lib/httpx/resolver/native.rb +7 -3
- data/lib/httpx/resolver/resolver.rb +12 -2
- data/lib/httpx/response.rb +4 -1
- data/lib/httpx/selector.rb +9 -2
- data/lib/httpx/transcoder/body.rb +1 -1
- data/lib/httpx/version.rb +1 -1
- data/sig/connection.rbs +3 -0
- data/sig/plugins/response_cache.rbs +24 -4
- data/sig/resolver/native.rbs +3 -1
- data/sig/response.rbs +3 -0
- metadata +9 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3ae7fc4057762abf47253c487544c4e3cd07e31326adec158235f1b53130a8db
|
4
|
+
data.tar.gz: 0a09ef99c59c1b3fd1e516066b656b78d888ffd4eed1160c6c9d96f001669410
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 61c786041e8e27c55d45c30e5f8558b1423470254c5be819c2a9daaa61b8bb049e7e892e0a2673799d26339435fd237fbe772bcb02a0373969e7f382eaa76186
|
7
|
+
data.tar.gz: f24c113213513d847aa693242902d334e1052deaacdfd944def81d91ea9545113ad8a6a973c5b97ec141fc6474f5513b2a3228c9ba644f8560c29806c10c2886
|
@@ -0,0 +1,7 @@
|
|
1
|
+
# 0.20.2
|
2
|
+
|
3
|
+
## Bugfixes
|
4
|
+
|
5
|
+
* fix for selector timeout errors closing all connections and ignoring resolvers.
|
6
|
+
|
7
|
+
Timeout errors on select were being propagated to all pooled connections, although not all of them were being selected on, and not all of them having timed out. plus, resolver timeouts were doing the same, making connections fail with connection timeout error, rather than resolve timeout error. A patch was implemented, where the selector now yields an error to the selected connections, rather than plain raising exception.
|
@@ -0,0 +1,6 @@
|
|
1
|
+
# 0.20.3
|
2
|
+
|
3
|
+
## Bugfixes
|
4
|
+
|
5
|
+
* DoH resolver wasn't working for non-absolute (the large majority) of domains since v0.19.
|
6
|
+
* Allowing a single IP string to be passed to the resolver option `:nameserver` (just like the `resolv` library does), besides the already supported list of IPs.
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# 0.20.4
|
2
|
+
|
3
|
+
## Improvements
|
4
|
+
|
5
|
+
The `:response_cache` plugin is now more compliant with how the RFC 2616 defines which behaviour caches shall have:
|
6
|
+
|
7
|
+
* it caches only responses with one of the following status codes: 200, 203, 300, 301, 410.
|
8
|
+
* it discards cached responses which become stale.
|
9
|
+
* it supports "cache-control" header directives to decided when to cache, to store, what the response "age" is.
|
10
|
+
* it can cache more than one response for the same request, provided that the request presents different header values for the headers declared in the "vary" response header (previously, it was only caching the first response, and discarding the remainder).
|
11
|
+
|
12
|
+
|
13
|
+
|
14
|
+
## Bugfixes
|
15
|
+
|
16
|
+
* fixed DNS resolution bug which caused a loop when a failed connection attempt would cause a new DNS request to be triggered for the same domain, filling up and giving preference to the very IP which failed the attempt.
|
17
|
+
* response_cache: request verb is now taken into account, not causing HEAD/GET confusion for the same URL.
|
data/lib/httpx/connection.rb
CHANGED
@@ -276,6 +276,12 @@ module HTTPX
|
|
276
276
|
@state == :open || @state == :inactive
|
277
277
|
end
|
278
278
|
|
279
|
+
def raise_timeout_error(interval)
|
280
|
+
error = HTTPX::TimeoutError.new(interval, "timed out while waiting on select")
|
281
|
+
error.set_backtrace(caller)
|
282
|
+
on_error(error)
|
283
|
+
end
|
284
|
+
|
279
285
|
private
|
280
286
|
|
281
287
|
def connect
|
data/lib/httpx/extensions.rb
CHANGED
@@ -83,22 +83,41 @@ module HTTPX
|
|
83
83
|
end
|
84
84
|
|
85
85
|
module ArrayExtensions
|
86
|
-
|
86
|
+
module FilterMap
|
87
|
+
refine Array do
|
87
88
|
|
88
|
-
|
89
|
-
|
89
|
+
def filter_map
|
90
|
+
return to_enum(:filter_map) unless block_given?
|
90
91
|
|
91
|
-
|
92
|
-
|
93
|
-
|
92
|
+
each_with_object([]) do |item, res|
|
93
|
+
processed = yield(item)
|
94
|
+
res << processed if processed
|
95
|
+
end
|
94
96
|
end
|
95
97
|
end unless Array.method_defined?(:filter_map)
|
98
|
+
end
|
96
99
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
+
module Sum
|
101
|
+
refine Array do
|
102
|
+
def sum(accumulator = 0, &block)
|
103
|
+
values = block_given? ? map(&block) : self
|
104
|
+
values.inject(accumulator, :+)
|
105
|
+
end
|
100
106
|
end unless Array.method_defined?(:sum)
|
101
107
|
end
|
108
|
+
|
109
|
+
module Intersect
|
110
|
+
refine Array do
|
111
|
+
def intersect?(arr)
|
112
|
+
if size < arr.size
|
113
|
+
smaller = self
|
114
|
+
else
|
115
|
+
smaller, arr = arr, self
|
116
|
+
end
|
117
|
+
(array & smaller).size > 0
|
118
|
+
end
|
119
|
+
end unless Array.method_defined?(:intersect?)
|
120
|
+
end
|
102
121
|
end
|
103
122
|
|
104
123
|
module IOExtensions
|
data/lib/httpx/io/ssl.rb
CHANGED
@@ -145,12 +145,12 @@ module HTTPX
|
|
145
145
|
"#{super}\n\n" \
|
146
146
|
"SSL connection using #{@io.ssl_version} / #{Array(@io.cipher).first}\n" \
|
147
147
|
"ALPN, server accepted to use #{protocol}\n" \
|
148
|
-
"Server certificate:\n" \
|
149
|
-
"
|
150
|
-
"
|
151
|
-
"
|
152
|
-
"
|
153
|
-
"
|
148
|
+
"Server certificate:\n " \
|
149
|
+
"subject: #{server_cert.subject}\n " \
|
150
|
+
"start date: #{server_cert.not_before}\n " \
|
151
|
+
"expire date: #{server_cert.not_after}\n " \
|
152
|
+
"issuer: #{server_cert.issuer}\n " \
|
153
|
+
"SSL certificate verify ok."
|
154
154
|
end
|
155
155
|
end
|
156
156
|
end
|
@@ -13,35 +13,38 @@ module HTTPX::Plugins
|
|
13
13
|
@store = {}
|
14
14
|
end
|
15
15
|
|
16
|
-
def lookup(
|
17
|
-
@store[
|
16
|
+
def lookup(request)
|
17
|
+
responses = @store[request.response_cache_key]
|
18
|
+
|
19
|
+
return unless responses
|
20
|
+
|
21
|
+
response = responses.find(&method(:match_by_vary?).curry(2)[request])
|
22
|
+
|
23
|
+
return unless response && response.fresh?
|
24
|
+
|
25
|
+
response
|
18
26
|
end
|
19
27
|
|
20
|
-
def cached?(
|
21
|
-
|
28
|
+
def cached?(request)
|
29
|
+
lookup(request)
|
22
30
|
end
|
23
31
|
|
24
|
-
def cache(
|
25
|
-
|
32
|
+
def cache(request, response)
|
33
|
+
return unless ResponseCache.cacheable_request?(request) && ResponseCache.cacheable_response?(response)
|
34
|
+
|
35
|
+
responses = (@store[request.response_cache_key] ||= [])
|
36
|
+
|
37
|
+
responses.reject!(&method(:match_by_vary?).curry(2)[request])
|
38
|
+
|
39
|
+
responses << response
|
26
40
|
end
|
27
41
|
|
28
42
|
def prepare(request)
|
29
|
-
cached_response =
|
43
|
+
cached_response = lookup(request)
|
30
44
|
|
31
45
|
return unless cached_response
|
32
46
|
|
33
|
-
|
34
|
-
|
35
|
-
if (vary = cached_response.headers["vary"])
|
36
|
-
if vary == "*"
|
37
|
-
return unless request.headers.same_headers?(original_request.headers)
|
38
|
-
else
|
39
|
-
return unless vary.split(/ *, */).all? do |cache_field|
|
40
|
-
cache_field.downcase!
|
41
|
-
!original_request.headers.key?(cache_field) || request.headers[cache_field] == original_request.headers[cache_field]
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
47
|
+
return unless match_by_vary?(request, cached_response)
|
45
48
|
|
46
49
|
if !request.headers.key?("if-modified-since") && (last_modified = cached_response.headers["last-modified"])
|
47
50
|
request.headers.add("if-modified-since", last_modified)
|
@@ -51,6 +54,23 @@ module HTTPX::Plugins
|
|
51
54
|
request.headers.add("if-none-match", etag)
|
52
55
|
end
|
53
56
|
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def match_by_vary?(request, response)
|
61
|
+
vary = response.vary
|
62
|
+
|
63
|
+
return true unless vary
|
64
|
+
|
65
|
+
original_request = response.instance_variable_get(:@request)
|
66
|
+
|
67
|
+
return request.headers.same_headers?(original_request.headers) if vary == %w[*]
|
68
|
+
|
69
|
+
vary.all? do |cache_field|
|
70
|
+
cache_field.downcase!
|
71
|
+
!original_request.headers.key?(cache_field) || request.headers[cache_field] == original_request.headers[cache_field]
|
72
|
+
end
|
73
|
+
end
|
54
74
|
end
|
55
75
|
end
|
56
76
|
end
|
@@ -9,7 +9,9 @@ module HTTPX
|
|
9
9
|
#
|
10
10
|
module ResponseCache
|
11
11
|
CACHEABLE_VERBS = %i[get head].freeze
|
12
|
+
CACHEABLE_STATUS_CODES = [200, 203, 206, 300, 301, 410].freeze
|
12
13
|
private_constant :CACHEABLE_VERBS
|
14
|
+
private_constant :CACHEABLE_STATUS_CODES
|
13
15
|
|
14
16
|
class << self
|
15
17
|
def load_dependencies(*)
|
@@ -17,14 +19,28 @@ module HTTPX
|
|
17
19
|
end
|
18
20
|
|
19
21
|
def cacheable_request?(request)
|
20
|
-
CACHEABLE_VERBS.include?(request.verb)
|
22
|
+
CACHEABLE_VERBS.include?(request.verb) &&
|
23
|
+
(
|
24
|
+
!request.headers.key?("cache-control") || !request.headers.get("cache-control").include?("no-store")
|
25
|
+
)
|
21
26
|
end
|
22
27
|
|
23
28
|
def cacheable_response?(response)
|
24
29
|
response.is_a?(Response) &&
|
25
|
-
|
30
|
+
(
|
31
|
+
response.cache_control.nil? ||
|
32
|
+
# TODO: !response.cache_control.include?("private") && is shared cache
|
33
|
+
!response.cache_control.include?("no-store")
|
34
|
+
) &&
|
35
|
+
CACHEABLE_STATUS_CODES.include?(response.status) &&
|
36
|
+
# RFC 2616 13.4 - A response received with a status code of 200, 203, 206, 300, 301 or
|
37
|
+
# 410 MAY be stored by a cache and used in reply to a subsequent
|
38
|
+
# request, subject to the expiration mechanism, unless a cache-control
|
39
|
+
# directive prohibits caching. However, a cache that does not support
|
40
|
+
# the Range and Content-Range headers MUST NOT cache 206 (Partial
|
41
|
+
# Content) responses.
|
26
42
|
response.status != 206 && (
|
27
|
-
response.headers.key?("etag") || response.headers.key?("last-modified-at")
|
43
|
+
response.headers.key?("etag") || response.headers.key?("last-modified-at") || response.fresh?
|
28
44
|
)
|
29
45
|
end
|
30
46
|
|
@@ -52,7 +68,7 @@ module HTTPX
|
|
52
68
|
|
53
69
|
def build_request(*)
|
54
70
|
request = super
|
55
|
-
return request unless ResponseCache.cacheable_request?(request) && @options.response_cache_store.cached?(request
|
71
|
+
return request unless ResponseCache.cacheable_request?(request) && @options.response_cache_store.cached?(request)
|
56
72
|
|
57
73
|
@options.response_cache_store.prepare(request)
|
58
74
|
|
@@ -62,25 +78,99 @@ module HTTPX
|
|
62
78
|
def fetch_response(request, *)
|
63
79
|
response = super
|
64
80
|
|
65
|
-
|
81
|
+
return unless response
|
82
|
+
|
83
|
+
if ResponseCache.cached_response?(response)
|
66
84
|
log { "returning cached response for #{request.uri}" }
|
67
|
-
cached_response = @options.response_cache_store.lookup(request
|
85
|
+
cached_response = @options.response_cache_store.lookup(request)
|
68
86
|
|
69
87
|
response.copy_from_cached(cached_response)
|
70
|
-
end
|
71
88
|
|
72
|
-
|
89
|
+
else
|
90
|
+
@options.response_cache_store.cache(request, response)
|
91
|
+
end
|
73
92
|
|
74
93
|
response
|
75
94
|
end
|
76
95
|
end
|
77
96
|
|
97
|
+
module RequestMethods
|
98
|
+
def response_cache_key
|
99
|
+
@response_cache_key ||= Digest::SHA1.hexdigest("httpx-response-cache-#{@verb}#{@uri}")
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
78
103
|
module ResponseMethods
|
79
104
|
def copy_from_cached(other)
|
80
105
|
@body = other.body
|
81
106
|
|
82
107
|
@body.__send__(:rewind)
|
83
108
|
end
|
109
|
+
|
110
|
+
# A response is fresh if its age has not yet exceeded its freshness lifetime.
|
111
|
+
def fresh?
|
112
|
+
if cache_control
|
113
|
+
return false if cache_control.include?("no-cache")
|
114
|
+
|
115
|
+
# check age: max-age
|
116
|
+
max_age = cache_control.find { |directive| directive.start_with?("s-maxage") }
|
117
|
+
|
118
|
+
max_age ||= cache_control.find { |directive| directive.start_with?("max-age") }
|
119
|
+
|
120
|
+
max_age = max_age[/age=(\d+)/, 1] if max_age
|
121
|
+
|
122
|
+
max_age = max_age.to_i if max_age
|
123
|
+
|
124
|
+
return max_age > age if max_age
|
125
|
+
end
|
126
|
+
|
127
|
+
# check age: expires
|
128
|
+
if @headers.key?("expires")
|
129
|
+
begin
|
130
|
+
expires = Time.httpdate(@headers["expires"])
|
131
|
+
rescue ArgumentError
|
132
|
+
return true
|
133
|
+
end
|
134
|
+
|
135
|
+
return (expires - Time.now).to_i.positive?
|
136
|
+
end
|
137
|
+
|
138
|
+
true
|
139
|
+
end
|
140
|
+
|
141
|
+
def cache_control
|
142
|
+
return @cache_control if defined?(@cache_control)
|
143
|
+
|
144
|
+
@cache_control = begin
|
145
|
+
return unless @headers.key?("cache-control")
|
146
|
+
|
147
|
+
@headers["cache-control"].split(/ *, */)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def vary
|
152
|
+
return @vary if defined?(@vary)
|
153
|
+
|
154
|
+
@vary = begin
|
155
|
+
return unless @headers.key?("vary")
|
156
|
+
|
157
|
+
@headers["vary"].split(/ *, */)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
private
|
162
|
+
|
163
|
+
def age
|
164
|
+
return @headers["age"].to_i if @headers.key?("age")
|
165
|
+
|
166
|
+
(Time.now - date).to_i
|
167
|
+
end
|
168
|
+
|
169
|
+
def date
|
170
|
+
@date ||= Time.httpdate(@headers["date"])
|
171
|
+
rescue NoMethodError, ArgumentError
|
172
|
+
Time.now.httpdate
|
173
|
+
end
|
84
174
|
end
|
85
175
|
end
|
86
176
|
register_plugin :response_cache, ResponseCache
|
data/lib/httpx/pool.rb
CHANGED
data/lib/httpx/resolver/https.rb
CHANGED
data/lib/httpx/resolver/multi.rb
CHANGED
@@ -45,7 +45,7 @@ module HTTPX
|
|
45
45
|
super
|
46
46
|
@ns_index = 0
|
47
47
|
@resolver_options = DEFAULTS.merge(@options.resolver_options)
|
48
|
-
@nameserver = @resolver_options[:nameserver]
|
48
|
+
@nameserver = Array(@resolver_options[:nameserver]) if @resolver_options[:nameserver]
|
49
49
|
@ndots = @resolver_options[:ndots]
|
50
50
|
@search = Array(@resolver_options[:search]).map { |srch| srch.scan(/[^.]+/) }
|
51
51
|
@_timeouts = Array(@resolver_options[:timeouts])
|
@@ -118,6 +118,10 @@ module HTTPX
|
|
118
118
|
@timeouts.values_at(*hosts).reject(&:empty?).map(&:first).min
|
119
119
|
end
|
120
120
|
|
121
|
+
def raise_timeout_error(interval)
|
122
|
+
do_retry(interval)
|
123
|
+
end
|
124
|
+
|
121
125
|
private
|
122
126
|
|
123
127
|
def calculate_interests
|
@@ -134,10 +138,10 @@ module HTTPX
|
|
134
138
|
dwrite if calculate_interests == :w
|
135
139
|
end
|
136
140
|
|
137
|
-
def do_retry
|
141
|
+
def do_retry(loop_time = nil)
|
138
142
|
return if @queries.empty? || !@start_timeout
|
139
143
|
|
140
|
-
loop_time
|
144
|
+
loop_time ||= Utils.elapsed_time(@start_timeout)
|
141
145
|
|
142
146
|
query = @queries.first
|
143
147
|
|
@@ -8,6 +8,8 @@ module HTTPX
|
|
8
8
|
include Callbacks
|
9
9
|
include Loggable
|
10
10
|
|
11
|
+
using ArrayExtensions::Intersect
|
12
|
+
|
11
13
|
RECORD_TYPES = {
|
12
14
|
Socket::AF_INET6 => Resolv::DNS::Resource::IN::AAAA,
|
13
15
|
Socket::AF_INET => Resolv::DNS::Resource::IN::A,
|
@@ -48,6 +50,10 @@ module HTTPX
|
|
48
50
|
addresses.map! do |address|
|
49
51
|
address.is_a?(IPAddr) ? address : IPAddr.new(address.to_s)
|
50
52
|
end
|
53
|
+
|
54
|
+
# double emission check
|
55
|
+
return if connection.addresses && !addresses.intersect?(connection.addresses)
|
56
|
+
|
51
57
|
log { "resolver: answer #{connection.origin.host}: #{addresses.inspect}" }
|
52
58
|
if @pool && # if triggered by early resolve, pool may not be here yet
|
53
59
|
!connection.io &&
|
@@ -56,8 +62,12 @@ module HTTPX
|
|
56
62
|
addresses.first.to_s != connection.origin.host.to_s
|
57
63
|
log { "resolver: A response, applying resolution delay..." }
|
58
64
|
@pool.after(0.05) do
|
59
|
-
|
60
|
-
|
65
|
+
# double emission check
|
66
|
+
unless connection.addresses && addresses.intersect?(connection.addresses)
|
67
|
+
|
68
|
+
connection.addresses = addresses
|
69
|
+
emit(:resolve, connection)
|
70
|
+
end
|
61
71
|
end
|
62
72
|
else
|
63
73
|
connection.addresses = addresses
|
data/lib/httpx/response.rb
CHANGED
@@ -56,7 +56,7 @@ module HTTPX
|
|
56
56
|
|
57
57
|
# :nocov:
|
58
58
|
def inspect
|
59
|
-
"#<Response:#{object_id} "\
|
59
|
+
"#<Response:#{object_id} " \
|
60
60
|
"HTTP/#{version} " \
|
61
61
|
"@status=#{@status} " \
|
62
62
|
"@headers=#{@headers} " \
|
@@ -310,9 +310,12 @@ module HTTPX
|
|
310
310
|
|
311
311
|
class ErrorResponse
|
312
312
|
include Loggable
|
313
|
+
extend Forwardable
|
313
314
|
|
314
315
|
attr_reader :request, :error
|
315
316
|
|
317
|
+
def_delegator :@request, :uri
|
318
|
+
|
316
319
|
def initialize(request, error, options)
|
317
320
|
@request = request
|
318
321
|
@error = error
|
data/lib/httpx/selector.rb
CHANGED
@@ -74,7 +74,10 @@ class HTTPX::Selector
|
|
74
74
|
|
75
75
|
readers, writers = IO.select(r, w, nil, interval)
|
76
76
|
|
77
|
-
|
77
|
+
if readers.nil? && writers.nil? && interval
|
78
|
+
[*r, *w].each { |io| io.raise_timeout_error(interval) }
|
79
|
+
return
|
80
|
+
end
|
78
81
|
rescue IOError, SystemCallError
|
79
82
|
@selectables.reject!(&:closed?)
|
80
83
|
retry
|
@@ -108,7 +111,11 @@ class HTTPX::Selector
|
|
108
111
|
when nil then return
|
109
112
|
end
|
110
113
|
|
111
|
-
|
114
|
+
unless result || interval.nil?
|
115
|
+
io.raise_timeout_error(interval)
|
116
|
+
return
|
117
|
+
end
|
118
|
+
# raise HTTPX::TimeoutError.new(interval, "timed out while waiting on select")
|
112
119
|
|
113
120
|
yield io
|
114
121
|
rescue IOError, SystemCallError
|
data/lib/httpx/version.rb
CHANGED
data/sig/connection.rbs
CHANGED
@@ -8,15 +8,19 @@ module HTTPX
|
|
8
8
|
def self?.cached_response?: (response response) -> bool
|
9
9
|
|
10
10
|
class Store
|
11
|
-
@store: Hash[
|
11
|
+
@store: Hash[String, Array[Response]]
|
12
12
|
|
13
|
-
def lookup: (
|
13
|
+
def lookup: (Request request) -> Response?
|
14
14
|
|
15
|
-
def cached?: (
|
15
|
+
def cached?: (Request request) -> boolish
|
16
16
|
|
17
|
-
def cache: (
|
17
|
+
def cache: (Request request, Response response) -> void
|
18
18
|
|
19
19
|
def prepare: (Request request) -> void
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def match_by_vary?: (Request request, Response response) -> bool
|
20
24
|
end
|
21
25
|
|
22
26
|
module InstanceMethods
|
@@ -25,8 +29,24 @@ module HTTPX
|
|
25
29
|
def clear_response_cache: () -> void
|
26
30
|
end
|
27
31
|
|
32
|
+
module RequestMethods
|
33
|
+
def response_cache_key: () -> String
|
34
|
+
end
|
35
|
+
|
28
36
|
module ResponseMethods
|
29
37
|
def copy_from_cached: (Response other) -> void
|
38
|
+
|
39
|
+
def fresh?: () -> bool
|
40
|
+
|
41
|
+
def cache_control: () -> Array[String]?
|
42
|
+
|
43
|
+
def vary: () -> Array[String]?
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def age: () -> Integer
|
48
|
+
|
49
|
+
def date: () -> Time
|
30
50
|
end
|
31
51
|
end
|
32
52
|
|
data/sig/resolver/native.rbs
CHANGED
@@ -27,6 +27,8 @@ module HTTPX
|
|
27
27
|
|
28
28
|
def timeout: () -> Numeric?
|
29
29
|
|
30
|
+
def raise_timeout_error: (Numeric interval) -> void
|
31
|
+
|
30
32
|
private
|
31
33
|
|
32
34
|
def initialize: (ip_family family, options options) -> void
|
@@ -35,7 +37,7 @@ module HTTPX
|
|
35
37
|
|
36
38
|
def consume: () -> void
|
37
39
|
|
38
|
-
def do_retry: () -> void
|
40
|
+
def do_retry: (?Numeric loop_time) -> void
|
39
41
|
|
40
42
|
def dread: (Integer) -> void
|
41
43
|
| () -> void
|
data/sig/response.rbs
CHANGED
@@ -96,6 +96,7 @@ module HTTPX
|
|
96
96
|
class ErrorResponse
|
97
97
|
include _Response
|
98
98
|
include Loggable
|
99
|
+
extend Forwardable
|
99
100
|
|
100
101
|
@options: Options
|
101
102
|
@error: Exception
|
@@ -104,6 +105,8 @@ module HTTPX
|
|
104
105
|
|
105
106
|
def status: () -> (Integer | _ToS)
|
106
107
|
|
108
|
+
def uri: () -> URI::Generic
|
109
|
+
|
107
110
|
private
|
108
111
|
|
109
112
|
def initialize: (Request, Exception, options) -> untyped
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: httpx
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.20.
|
4
|
+
version: 0.20.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tiago Cardoso
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-08-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: http-2-next
|
@@ -82,6 +82,9 @@ extra_rdoc_files:
|
|
82
82
|
- doc/release_notes/0_1_0.md
|
83
83
|
- doc/release_notes/0_20_0.md
|
84
84
|
- doc/release_notes/0_20_1.md
|
85
|
+
- doc/release_notes/0_20_2.md
|
86
|
+
- doc/release_notes/0_20_3.md
|
87
|
+
- doc/release_notes/0_24_4.md
|
85
88
|
- doc/release_notes/0_2_0.md
|
86
89
|
- doc/release_notes/0_2_1.md
|
87
90
|
- doc/release_notes/0_3_0.md
|
@@ -156,6 +159,9 @@ files:
|
|
156
159
|
- doc/release_notes/0_1_0.md
|
157
160
|
- doc/release_notes/0_20_0.md
|
158
161
|
- doc/release_notes/0_20_1.md
|
162
|
+
- doc/release_notes/0_20_2.md
|
163
|
+
- doc/release_notes/0_20_3.md
|
164
|
+
- doc/release_notes/0_24_4.md
|
159
165
|
- doc/release_notes/0_2_0.md
|
160
166
|
- doc/release_notes/0_2_1.md
|
161
167
|
- doc/release_notes/0_3_0.md
|
@@ -360,7 +366,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
360
366
|
- !ruby/object:Gem::Version
|
361
367
|
version: '0'
|
362
368
|
requirements: []
|
363
|
-
rubygems_version: 3.
|
369
|
+
rubygems_version: 3.3.7
|
364
370
|
signing_key:
|
365
371
|
specification_version: 4
|
366
372
|
summary: HTTPX, to the future, and beyond
|