httpx 0.18.1 → 0.18.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +4 -3
- data/doc/release_notes/0_18_2.md +10 -0
- data/doc/release_notes/0_18_3.md +7 -0
- data/doc/release_notes/0_18_4.md +14 -0
- data/doc/release_notes/0_18_5.md +10 -0
- data/lib/httpx/adapters/faraday.rb +51 -9
- data/lib/httpx/adapters/webmock.rb +71 -59
- data/lib/httpx/altsvc.rb +25 -9
- data/lib/httpx/connection/http1.rb +1 -1
- data/lib/httpx/connection/http2.rb +6 -0
- data/lib/httpx/io/udp.rb +0 -1
- data/lib/httpx/plugins/multipart/mime_type_detector.rb +12 -4
- data/lib/httpx/plugins/proxy.rb +15 -3
- data/lib/httpx/request.rb +1 -1
- data/lib/httpx/selector.rb +7 -0
- data/lib/httpx/session.rb +1 -1
- data/lib/httpx/version.rb +1 -1
- metadata +59 -51
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 843e16ae32c900167850fe3a864446af2cd6b6a9d3ca6368f64b999964a1a5b2
|
4
|
+
data.tar.gz: 533464195c08ab7e0ba2e5aa7871fdf8b59e59643122ca48ce5e7cf8a6ebb351
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6e170cf6a47bce0a1eeeea25c53870615958f77e2fe9eb9b4176783b860bc26c8d45712e0ad758ba2481bd2712a21bb14d10a32fb5f17871a9421413edf162ac
|
7
|
+
data.tar.gz: ae5a0bc77a54cf66528dfd89c7127b5ce64730be6fc0fe8be6d79966dfa36e2e04b348f39e1e91d3b457e34c35f8b3a33e18bc656f7823874ffbaedc72e3b8ad
|
data/README.md
CHANGED
@@ -45,7 +45,7 @@ response = HTTPX.get("https://nghttp2.org")
|
|
45
45
|
puts response.status #=> 200
|
46
46
|
body = response.body
|
47
47
|
puts body #=> #<HTTPX::Response ...
|
48
|
-
```
|
48
|
+
```
|
49
49
|
|
50
50
|
You can also send as many requests as you want simultaneously:
|
51
51
|
|
@@ -79,7 +79,7 @@ In Ruby, HTTP client implementations are a known cheap commodity. Why this one?
|
|
79
79
|
|
80
80
|
### Concurrency
|
81
81
|
|
82
|
-
This library supports HTTP/2 seamlessly (which means, if the request is secure, and the server support ALPN negotiation AND HTTP/2, the request will be made through HTTP/2). If you pass multiple URIs, and they can utilize the same connection, they will run concurrently in it.
|
82
|
+
This library supports HTTP/2 seamlessly (which means, if the request is secure, and the server support ALPN negotiation AND HTTP/2, the request will be made through HTTP/2). If you pass multiple URIs, and they can utilize the same connection, they will run concurrently in it.
|
83
83
|
|
84
84
|
However if the server supports HTTP/1.1, it will try to use HTTP pipelining, falling back to 1 request at a time if the server doesn't support it (if the server support Keep-Alive connections, it will reuse the same connection).
|
85
85
|
|
@@ -137,7 +137,8 @@ In order to use HTTP/2 under JRuby, [check this link](https://gitlab.com/honeyry
|
|
137
137
|
|
138
138
|
### Known bugs
|
139
139
|
|
140
|
-
Doesn't work with ruby 2.4.0 for Windows (see [#36](https://gitlab.com/honeyryderchuck/httpx/issues/36)).
|
140
|
+
* Doesn't work with ruby 2.4.0 for Windows (see [#36](https://gitlab.com/honeyryderchuck/httpx/issues/36)).
|
141
|
+
* Using `total_timeout` along with the `:persistent` plugin [does not work as you might expect](https://gitlab.com/honeyryderchuck/httpx/-/wikis/Timeouts#total_timeout).
|
141
142
|
|
142
143
|
## Contributing
|
143
144
|
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# 0.18.2
|
2
|
+
|
3
|
+
## Bugfixes
|
4
|
+
|
5
|
+
* A bug was reported and fixed, whereby a persistent connection with a `:total_timeout` set was triggering the timeout and leaving the process looping indefinitely.
|
6
|
+
|
7
|
+
|
8
|
+
## Chore
|
9
|
+
|
10
|
+
The quirk of using the `:persistent` plugin with `:total_timeout` has been documented: https://gitlab.com/honeyryderchuck/httpx/-/wikis/Timeouts#total_timeout.
|
@@ -0,0 +1,7 @@
|
|
1
|
+
# 0.18.3
|
2
|
+
|
3
|
+
## Bugfixes
|
4
|
+
|
5
|
+
* request bodies eager-loaded from enumerables yield duped partial chunks.
|
6
|
+
|
7
|
+
An error was observed while looking at webmock integration, where requests formed via the multipart plugin were returning an empty string as body. The issue was caused by an optimization on multipart encoder, which reuses the same buffer when reading chunks. Unfortunately, these cannot be yielded the same way via IO.copy_stream, as the same (cleared) buffer will be used to generate the eager-loaded body chunks.
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# 0.18.4
|
2
|
+
|
3
|
+
## Improvements
|
4
|
+
|
5
|
+
* faraday adapter: added support for `#on_data` callback in order to support [faraday streaming](https://lostisland.github.io/faraday/usage/streaming).
|
6
|
+
|
7
|
+
* multipart plugin: removed support for file mime type detection using `mime-types`. The reasoning behind it was that `mime-types` uses the filename, which is a very inaccurate detection strategy (ex: an mp4 video will be identified as `application/mp4`, instead of the correct `video/mp4`).
|
8
|
+
* multipart plugin: supported for file mime type detection using `marcel` and `filemagic` was added. Both use the magic header bytes, which is a more accurate strategy for file type detection.
|
9
|
+
|
10
|
+
## Bugfixes
|
11
|
+
|
12
|
+
* webmock adapter has been reimplemented to work with `httpx` plugins (such as the `:retries` plugin). Some other fixes were applied to make it work better under `vcr` (a common `webmock` extension).
|
13
|
+
|
14
|
+
* fixed the URI-related bug which was making requests stall under ruby 3.1 (still not officially testing against it).
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# 0.18.5
|
2
|
+
|
3
|
+
## Improvements
|
4
|
+
|
5
|
+
* ruby 3.1 is now officially supported.
|
6
|
+
* when user sets a `Host` header for an HTTP/2 request, this will be used in the `:authority` HTTP/2 pseudo-header, instead of silently ignored (mimicking what "curl" does).
|
7
|
+
|
8
|
+
## Bugfixes
|
9
|
+
|
10
|
+
* fixed "throw outside of catch block" error happening when pipelining requests on an HTTP/1 connnection and resulting in a timeout.
|
@@ -21,6 +21,17 @@ module Faraday
|
|
21
21
|
end
|
22
22
|
# :nocov:
|
23
23
|
|
24
|
+
unless Faraday::RequestOptions.method_defined?(:stream_response?)
|
25
|
+
module RequestOptionsExtensions
|
26
|
+
refine Faraday::RequestOptions do
|
27
|
+
def stream_response?
|
28
|
+
false
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
using RequestOptionsExtensions
|
33
|
+
end
|
34
|
+
|
24
35
|
module RequestMixin
|
25
36
|
using ::HTTPX::HashExtensions
|
26
37
|
|
@@ -64,6 +75,27 @@ module Faraday
|
|
64
75
|
|
65
76
|
include RequestMixin
|
66
77
|
|
78
|
+
module OnDataPlugin
|
79
|
+
module RequestMethods
|
80
|
+
attr_writer :response_on_data
|
81
|
+
|
82
|
+
def response=(response)
|
83
|
+
super
|
84
|
+
response.body.on_data = @response_on_data
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
module ResponseBodyMethods
|
89
|
+
attr_writer :on_data
|
90
|
+
|
91
|
+
def write(chunk)
|
92
|
+
return super unless @on_data
|
93
|
+
|
94
|
+
@on_data.call(chunk, chunk.bytesize)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
67
99
|
class Session < ::HTTPX::Session
|
68
100
|
plugin(:compression)
|
69
101
|
plugin(:persistent)
|
@@ -137,15 +169,21 @@ module Faraday
|
|
137
169
|
end
|
138
170
|
|
139
171
|
def run
|
140
|
-
requests = @handlers.map { |handler| build_request(handler.env) }
|
141
172
|
env = @handlers.last.env
|
142
173
|
|
143
|
-
proxy_options = { uri: env.request.proxy }
|
144
|
-
|
145
174
|
session = @session.with(options_from_env(env))
|
146
|
-
session = session.plugin(:proxy).with(proxy:
|
175
|
+
session = session.plugin(:proxy).with(proxy: { uri: env.request.proxy }) if env.request.proxy
|
176
|
+
session = session.plugin(OnDataPlugin) if env.request.stream_response?
|
177
|
+
|
178
|
+
requests = @handlers.map { |handler| session.build_request(*build_request(handler.env)) }
|
179
|
+
|
180
|
+
if env.request.stream_response?
|
181
|
+
requests.each do |request|
|
182
|
+
request.response_on_data = env.request.on_data
|
183
|
+
end
|
184
|
+
end
|
147
185
|
|
148
|
-
responses = session.request(requests)
|
186
|
+
responses = session.request(*requests)
|
149
187
|
Array(responses).each_with_index do |response, index|
|
150
188
|
handler = @handlers[index]
|
151
189
|
handler.on_response.call(response)
|
@@ -179,11 +217,15 @@ module Faraday
|
|
179
217
|
return handler
|
180
218
|
end
|
181
219
|
|
182
|
-
meth, uri, request_options = build_request(env)
|
183
|
-
|
184
220
|
session = @session.with(options_from_env(env))
|
185
|
-
session = session.plugin(:proxy).with(proxy:
|
186
|
-
|
221
|
+
session = session.plugin(:proxy).with(proxy: { uri: env.request.proxy }) if env.request.proxy
|
222
|
+
session = session.plugin(OnDataPlugin) if env.request.stream_response?
|
223
|
+
|
224
|
+
request = session.build_request(*build_request(env))
|
225
|
+
|
226
|
+
request.response_on_data = env.request.on_data if env.request.stream_response?
|
227
|
+
|
228
|
+
response = session.request(request)
|
187
229
|
response.raise_for_status unless response.is_a?(::HTTPX::Response)
|
188
230
|
save_response(env, response.status, response.body.to_s, response.headers, response.reason) do |response_headers|
|
189
231
|
response_headers.merge!(response.headers)
|
@@ -16,56 +16,8 @@ module WebMock
|
|
16
16
|
# Requests are "hijacked" at the session, before they're distributed to a connection.
|
17
17
|
#
|
18
18
|
module Plugin
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
def send_requests(*requests)
|
23
|
-
request_signatures = requests.map do |request|
|
24
|
-
request_signature = _build_webmock_request_signature(request)
|
25
|
-
WebMock::RequestRegistry.instance.requested_signatures.put(request_signature)
|
26
|
-
request_signature
|
27
|
-
end
|
28
|
-
|
29
|
-
responses = request_signatures.map do |request_signature|
|
30
|
-
WebMock::StubRegistry.instance.response_for_request(request_signature)
|
31
|
-
end
|
32
|
-
|
33
|
-
real_requests = {}
|
34
|
-
|
35
|
-
requests.each_with_index.each_with_object([request_signatures, responses]) do |(request, idx), (sig_reqs, mock_responses)|
|
36
|
-
if (webmock_response = mock_responses[idx])
|
37
|
-
mock_responses[idx] = _build_from_webmock_response(request, webmock_response)
|
38
|
-
WebMock::CallbackRegistry.invoke_callbacks({ lib: :httpx }, sig_reqs[idx], webmock_response)
|
39
|
-
log { "mocking #{request.uri} with #{mock_responses[idx].inspect}" }
|
40
|
-
elsif WebMock.net_connect_allowed?(sig_reqs[idx].uri)
|
41
|
-
log { "performing #{request.uri}" }
|
42
|
-
real_requests[request] = idx
|
43
|
-
else
|
44
|
-
raise WebMock::NetConnectNotAllowedError, sig_reqs[idx]
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
unless real_requests.empty?
|
49
|
-
reqs = real_requests.keys
|
50
|
-
reqs.zip(super(*reqs)).each do |req, res|
|
51
|
-
idx = real_requests[req]
|
52
|
-
|
53
|
-
if WebMock::CallbackRegistry.any_callbacks?
|
54
|
-
webmock_response = _build_webmock_response(req, res)
|
55
|
-
WebMock::CallbackRegistry.invoke_callbacks(
|
56
|
-
{ lib: :httpx, real_request: true }, request_signatures[idx],
|
57
|
-
webmock_response
|
58
|
-
)
|
59
|
-
end
|
60
|
-
|
61
|
-
responses[idx] = res
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
responses
|
66
|
-
end
|
67
|
-
|
68
|
-
def _build_webmock_request_signature(request)
|
19
|
+
class << self
|
20
|
+
def build_webmock_request_signature(request)
|
69
21
|
uri = WebMock::Util::URI.heuristic_parse(request.uri)
|
70
22
|
uri.path = uri.normalized_path.gsub("[^:]//", "/")
|
71
23
|
|
@@ -77,7 +29,7 @@ module WebMock
|
|
77
29
|
)
|
78
30
|
end
|
79
31
|
|
80
|
-
def
|
32
|
+
def build_webmock_response(_request, response)
|
81
33
|
webmock_response = WebMock::Response.new
|
82
34
|
webmock_response.status = [response.status, HTTP_REASONS[response.status]]
|
83
35
|
webmock_response.body = response.body.to_s
|
@@ -85,10 +37,10 @@ module WebMock
|
|
85
37
|
webmock_response
|
86
38
|
end
|
87
39
|
|
88
|
-
def
|
89
|
-
return
|
40
|
+
def build_from_webmock_response(request, webmock_response)
|
41
|
+
return build_error_response(request, HTTPX::TimeoutError.new(1, "Timed out")) if webmock_response.should_timeout
|
90
42
|
|
91
|
-
return
|
43
|
+
return build_error_response(request, webmock_response.exception) if webmock_response.exception
|
92
44
|
|
93
45
|
response = request.options.response_class.new(request,
|
94
46
|
webmock_response.status[0],
|
@@ -98,10 +50,70 @@ module WebMock
|
|
98
50
|
response
|
99
51
|
end
|
100
52
|
|
101
|
-
def
|
53
|
+
def build_error_response(request, exception)
|
102
54
|
HTTPX::ErrorResponse.new(request, exception, request.options)
|
103
55
|
end
|
104
56
|
end
|
57
|
+
|
58
|
+
module InstanceMethods
|
59
|
+
def build_connection(*)
|
60
|
+
connection = super
|
61
|
+
connection.once(:unmock_connection) do
|
62
|
+
pool.__send__(:resolve_connection, connection)
|
63
|
+
pool.__send__(:unregister_connection, connection) unless connection.addresses
|
64
|
+
end
|
65
|
+
connection
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
module ConnectionMethods
|
70
|
+
def initialize(*)
|
71
|
+
super
|
72
|
+
@mocked = true
|
73
|
+
end
|
74
|
+
|
75
|
+
def open?
|
76
|
+
return true if @mocked
|
77
|
+
|
78
|
+
super
|
79
|
+
end
|
80
|
+
|
81
|
+
def interests
|
82
|
+
return if @mocked
|
83
|
+
|
84
|
+
super
|
85
|
+
end
|
86
|
+
|
87
|
+
def send(request)
|
88
|
+
request_signature = Plugin.build_webmock_request_signature(request)
|
89
|
+
WebMock::RequestRegistry.instance.requested_signatures.put(request_signature)
|
90
|
+
|
91
|
+
if (mock_response = WebMock::StubRegistry.instance.response_for_request(request_signature))
|
92
|
+
response = Plugin.build_from_webmock_response(request, mock_response)
|
93
|
+
WebMock::CallbackRegistry.invoke_callbacks({ lib: :httpx }, request_signature, mock_response)
|
94
|
+
log { "mocking #{request.uri} with #{mock_response.inspect}" }
|
95
|
+
request.response = response
|
96
|
+
request.emit(:response, response)
|
97
|
+
elsif WebMock.net_connect_allowed?(request_signature.uri)
|
98
|
+
if WebMock::CallbackRegistry.any_callbacks?
|
99
|
+
request.on(:response) do |resp|
|
100
|
+
unless resp.is_a?(HTTPX::ErrorResponse)
|
101
|
+
webmock_response = Plugin.build_webmock_response(request, resp)
|
102
|
+
WebMock::CallbackRegistry.invoke_callbacks(
|
103
|
+
{ lib: :httpx, real_request: true }, request_signature,
|
104
|
+
webmock_response
|
105
|
+
)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
@mocked = false
|
110
|
+
emit(:unmock_connection, self)
|
111
|
+
super
|
112
|
+
else
|
113
|
+
raise WebMock::NetConnectNotAllowedError, request_signature
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
105
117
|
end
|
106
118
|
|
107
119
|
class HttpxAdapter < HttpLibAdapter
|
@@ -109,12 +121,12 @@ module WebMock
|
|
109
121
|
|
110
122
|
class << self
|
111
123
|
def enable!
|
112
|
-
@original_session =
|
124
|
+
@original_session = HTTPX::Session
|
113
125
|
|
114
|
-
webmock_session =
|
126
|
+
webmock_session = HTTPX.plugin(Plugin)
|
115
127
|
|
116
|
-
|
117
|
-
|
128
|
+
HTTPX.send(:remove_const, :Session)
|
129
|
+
HTTPX.send(:const_set, :Session, webmock_session.class)
|
118
130
|
end
|
119
131
|
|
120
132
|
def disable!
|
data/lib/httpx/altsvc.rb
CHANGED
@@ -70,7 +70,7 @@ module HTTPX
|
|
70
70
|
|
71
71
|
scanner = StringScanner.new(altsvc)
|
72
72
|
until scanner.eos?
|
73
|
-
|
73
|
+
alt_service = scanner.scan(/[^=]+=("[^"]+"|[^;,]+)/)
|
74
74
|
|
75
75
|
alt_params = []
|
76
76
|
loop do
|
@@ -80,29 +80,45 @@ module HTTPX
|
|
80
80
|
break if scanner.eos? || scanner.scan(/ *, */)
|
81
81
|
end
|
82
82
|
alt_params = Hash[alt_params.map { |field| field.split("=") }]
|
83
|
-
|
83
|
+
|
84
|
+
alt_proto, alt_authority = alt_service.split("=")
|
85
|
+
alt_origin = parse_altsvc_origin(alt_proto, alt_authority)
|
86
|
+
return unless alt_origin
|
87
|
+
|
88
|
+
yield(alt_origin, alt_params.merge("proto" => alt_proto))
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def parse_altsvc_scheme(alt_proto)
|
93
|
+
case alt_proto
|
94
|
+
when "h2c"
|
95
|
+
"http"
|
96
|
+
when "h2"
|
97
|
+
"https"
|
84
98
|
end
|
85
99
|
end
|
86
100
|
|
87
101
|
# :nocov:
|
88
102
|
if RUBY_VERSION < "2.2"
|
89
|
-
def parse_altsvc_origin(alt_origin)
|
90
|
-
|
103
|
+
def parse_altsvc_origin(alt_proto, alt_origin)
|
104
|
+
alt_scheme = parse_altsvc_scheme(alt_proto) or return
|
105
|
+
|
91
106
|
alt_origin = alt_origin[1..-2] if alt_origin.start_with?("\"") && alt_origin.end_with?("\"")
|
92
107
|
if alt_origin.start_with?(":")
|
93
|
-
alt_origin = "#{
|
108
|
+
alt_origin = "#{alt_scheme}://dummy#{alt_origin}"
|
94
109
|
uri = URI.parse(alt_origin)
|
95
110
|
uri.host = nil
|
96
111
|
uri
|
97
112
|
else
|
98
|
-
URI.parse("#{
|
113
|
+
URI.parse("#{alt_scheme}://#{alt_origin}")
|
99
114
|
end
|
100
115
|
end
|
101
116
|
else
|
102
|
-
def parse_altsvc_origin(alt_origin)
|
103
|
-
|
117
|
+
def parse_altsvc_origin(alt_proto, alt_origin)
|
118
|
+
alt_scheme = parse_altsvc_scheme(alt_proto) or return
|
104
119
|
alt_origin = alt_origin[1..-2] if alt_origin.start_with?("\"") && alt_origin.end_with?("\"")
|
105
|
-
|
120
|
+
|
121
|
+
URI.parse("#{alt_scheme}://#{alt_origin}")
|
106
122
|
end
|
107
123
|
end
|
108
124
|
# :nocov:
|
@@ -220,6 +220,12 @@ module HTTPX
|
|
220
220
|
|
221
221
|
def join_headers(stream, request)
|
222
222
|
extra_headers = set_protocol_headers(request)
|
223
|
+
|
224
|
+
if request.headers.key?("host")
|
225
|
+
log { "forbidden \"host\" header found (#{request.headers["host"]}), will use it as authority..." }
|
226
|
+
extra_headers[":authority"] = request.headers["host"]
|
227
|
+
end
|
228
|
+
|
223
229
|
log(level: 1, color: :yellow) do
|
224
230
|
request.headers.merge(extra_headers).each.map { |k, v| "#{stream.id}: -> HEADER: #{k}: #{v}" }.join("\n")
|
225
231
|
end
|
data/lib/httpx/io/udp.rb
CHANGED
@@ -8,11 +8,19 @@ module HTTPX
|
|
8
8
|
DEFAULT_MIMETYPE = "application/octet-stream"
|
9
9
|
|
10
10
|
# inspired by https://github.com/shrinerb/shrine/blob/master/lib/shrine/plugins/determine_mime_type.rb
|
11
|
-
if defined?(
|
11
|
+
if defined?(FileMagic)
|
12
|
+
def call(file, _)
|
13
|
+
return nil if file.eof? # FileMagic returns "application/x-empty" for empty files
|
14
|
+
|
15
|
+
FileMagic.open(FileMagic::MAGIC_MIME_TYPE) do |filemagic|
|
16
|
+
filemagic.buffer(file.read(MAGIC_NUMBER))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
elsif defined?(Marcel)
|
20
|
+
def call(file, filename)
|
21
|
+
return nil if file.eof? # marcel returns "application/octet-stream" for empty files
|
12
22
|
|
13
|
-
|
14
|
-
mime = MIME::Types.of(filename).first
|
15
|
-
mime.content_type if mime
|
23
|
+
Marcel::MimeType.for(file, name: filename)
|
16
24
|
end
|
17
25
|
|
18
26
|
elsif defined?(MimeMagic)
|
data/lib/httpx/plugins/proxy.rb
CHANGED
@@ -138,10 +138,20 @@ module HTTPX
|
|
138
138
|
error = response.error
|
139
139
|
case error
|
140
140
|
when NativeResolveError
|
141
|
+
return false unless @_proxy_uris && !@_proxy_uris.empty?
|
142
|
+
|
143
|
+
proxy_uri = URI(@_proxy_uris.first)
|
144
|
+
|
145
|
+
origin = error.connection.origin
|
146
|
+
|
141
147
|
# failed resolving proxy domain
|
142
|
-
|
148
|
+
origin.host == proxy_uri.host && origin.port == proxy_uri.port
|
143
149
|
when ResolveError
|
144
|
-
|
150
|
+
return false unless @_proxy_uris && !@_proxy_uris.empty?
|
151
|
+
|
152
|
+
proxy_uri = URI(@_proxy_uris.first)
|
153
|
+
|
154
|
+
error.message.end_with?(proxy_uri.to_s)
|
145
155
|
when *PROXY_ERRORS
|
146
156
|
# timeout errors connecting to proxy
|
147
157
|
true
|
@@ -160,7 +170,9 @@ module HTTPX
|
|
160
170
|
|
161
171
|
# redefining the connection origin as the proxy's URI,
|
162
172
|
# as this will be used as the tcp peer ip.
|
163
|
-
|
173
|
+
proxy_uri = URI(@options.proxy.uri)
|
174
|
+
@origin.host = proxy_uri.host
|
175
|
+
@origin.port = proxy_uri.port
|
164
176
|
end
|
165
177
|
|
166
178
|
def match?(uri, options)
|
data/lib/httpx/request.rb
CHANGED
data/lib/httpx/selector.rb
CHANGED
@@ -117,6 +117,13 @@ class HTTPX::Selector
|
|
117
117
|
end
|
118
118
|
|
119
119
|
def select(interval, &block)
|
120
|
+
# do not cause an infinite loop here.
|
121
|
+
#
|
122
|
+
# this may happen if timeout calculation actually triggered an error which causes
|
123
|
+
# the connections to be reaped (such as the total timeout error) before #select
|
124
|
+
# gets called.
|
125
|
+
return if interval.nil? && @selectables.empty?
|
126
|
+
|
120
127
|
return select_one(interval, &block) if @selectables.size == 1
|
121
128
|
|
122
129
|
select_many(interval, &block)
|
data/lib/httpx/session.rb
CHANGED
data/lib/httpx/version.rb
CHANGED
metadata
CHANGED
@@ -1,24 +1,24 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: httpx
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.18.
|
4
|
+
version: 0.18.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tiago Cardoso
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: http-2-next
|
15
|
-
prerelease: false
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
16
|
requirements:
|
18
17
|
- - ">="
|
19
18
|
- !ruby/object:Gem::Version
|
20
19
|
version: 0.4.1
|
21
20
|
type: :runtime
|
21
|
+
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
@@ -33,59 +33,63 @@ extra_rdoc_files:
|
|
33
33
|
- LICENSE.txt
|
34
34
|
- README.md
|
35
35
|
- doc/release_notes/0_0_1.md
|
36
|
-
- doc/release_notes/
|
37
|
-
- doc/release_notes/
|
38
|
-
- doc/release_notes/0_18_1.md
|
39
|
-
- doc/release_notes/0_1_0.md
|
40
|
-
- doc/release_notes/0_0_5.md
|
41
|
-
- doc/release_notes/0_15_0.md
|
42
|
-
- doc/release_notes/0_14_1.md
|
36
|
+
- doc/release_notes/0_0_2.md
|
37
|
+
- doc/release_notes/0_0_3.md
|
43
38
|
- doc/release_notes/0_0_4.md
|
44
|
-
- doc/release_notes/
|
45
|
-
- doc/release_notes/
|
46
|
-
- doc/release_notes/
|
47
|
-
- doc/release_notes/0_18_0.md
|
48
|
-
- doc/release_notes/0_6_5.md
|
49
|
-
- doc/release_notes/0_13_0.md
|
50
|
-
- doc/release_notes/0_6_1.md
|
51
|
-
- doc/release_notes/0_11_2.md
|
52
|
-
- doc/release_notes/0_7_0.md
|
53
|
-
- doc/release_notes/0_6_0.md
|
39
|
+
- doc/release_notes/0_0_5.md
|
40
|
+
- doc/release_notes/0_10_0.md
|
41
|
+
- doc/release_notes/0_10_1.md
|
54
42
|
- doc/release_notes/0_10_2.md
|
43
|
+
- doc/release_notes/0_11_0.md
|
44
|
+
- doc/release_notes/0_11_1.md
|
45
|
+
- doc/release_notes/0_11_2.md
|
55
46
|
- doc/release_notes/0_11_3.md
|
56
|
-
- doc/release_notes/0_8_2.md
|
57
|
-
- doc/release_notes/0_6_4.md
|
58
|
-
- doc/release_notes/0_13_1.md
|
59
47
|
- doc/release_notes/0_12_0.md
|
60
|
-
- doc/release_notes/
|
61
|
-
- doc/release_notes/
|
62
|
-
- doc/release_notes/0_10_1.md
|
63
|
-
- doc/release_notes/0_11_0.md
|
64
|
-
- doc/release_notes/0_8_1.md
|
65
|
-
- doc/release_notes/0_5_0.md
|
66
|
-
- doc/release_notes/0_6_7.md
|
48
|
+
- doc/release_notes/0_13_0.md
|
49
|
+
- doc/release_notes/0_13_1.md
|
67
50
|
- doc/release_notes/0_13_2.md
|
68
|
-
- doc/release_notes/
|
69
|
-
- doc/release_notes/
|
70
|
-
- doc/release_notes/
|
71
|
-
- doc/release_notes/0_4_0.md
|
72
|
-
- doc/release_notes/0_6_2.md
|
73
|
-
- doc/release_notes/0_10_0.md
|
74
|
-
- doc/release_notes/0_11_1.md
|
75
|
-
- doc/release_notes/0_8_0.md
|
76
|
-
- doc/release_notes/0_3_0.md
|
77
|
-
- doc/release_notes/0_15_2.md
|
51
|
+
- doc/release_notes/0_14_0.md
|
52
|
+
- doc/release_notes/0_14_1.md
|
53
|
+
- doc/release_notes/0_14_2.md
|
78
54
|
- doc/release_notes/0_14_3.md
|
79
|
-
- doc/release_notes/
|
80
|
-
- doc/release_notes/
|
55
|
+
- doc/release_notes/0_14_4.md
|
56
|
+
- doc/release_notes/0_14_5.md
|
57
|
+
- doc/release_notes/0_15_0.md
|
58
|
+
- doc/release_notes/0_15_1.md
|
59
|
+
- doc/release_notes/0_15_2.md
|
60
|
+
- doc/release_notes/0_15_3.md
|
61
|
+
- doc/release_notes/0_15_4.md
|
62
|
+
- doc/release_notes/0_16_0.md
|
81
63
|
- doc/release_notes/0_16_1.md
|
82
64
|
- doc/release_notes/0_17_0.md
|
83
|
-
- doc/release_notes/
|
84
|
-
- doc/release_notes/
|
85
|
-
- doc/release_notes/
|
86
|
-
- doc/release_notes/
|
87
|
-
- doc/release_notes/
|
65
|
+
- doc/release_notes/0_18_0.md
|
66
|
+
- doc/release_notes/0_18_1.md
|
67
|
+
- doc/release_notes/0_18_2.md
|
68
|
+
- doc/release_notes/0_18_3.md
|
69
|
+
- doc/release_notes/0_18_4.md
|
70
|
+
- doc/release_notes/0_18_5.md
|
71
|
+
- doc/release_notes/0_1_0.md
|
88
72
|
- doc/release_notes/0_2_0.md
|
73
|
+
- doc/release_notes/0_2_1.md
|
74
|
+
- doc/release_notes/0_3_0.md
|
75
|
+
- doc/release_notes/0_3_1.md
|
76
|
+
- doc/release_notes/0_4_0.md
|
77
|
+
- doc/release_notes/0_4_1.md
|
78
|
+
- doc/release_notes/0_5_0.md
|
79
|
+
- doc/release_notes/0_5_1.md
|
80
|
+
- doc/release_notes/0_6_0.md
|
81
|
+
- doc/release_notes/0_6_1.md
|
82
|
+
- doc/release_notes/0_6_2.md
|
83
|
+
- doc/release_notes/0_6_3.md
|
84
|
+
- doc/release_notes/0_6_4.md
|
85
|
+
- doc/release_notes/0_6_5.md
|
86
|
+
- doc/release_notes/0_6_6.md
|
87
|
+
- doc/release_notes/0_6_7.md
|
88
|
+
- doc/release_notes/0_7_0.md
|
89
|
+
- doc/release_notes/0_8_0.md
|
90
|
+
- doc/release_notes/0_8_1.md
|
91
|
+
- doc/release_notes/0_8_2.md
|
92
|
+
- doc/release_notes/0_9_0.md
|
89
93
|
files:
|
90
94
|
- LICENSE.txt
|
91
95
|
- README.md
|
@@ -121,6 +125,10 @@ files:
|
|
121
125
|
- doc/release_notes/0_17_0.md
|
122
126
|
- doc/release_notes/0_18_0.md
|
123
127
|
- doc/release_notes/0_18_1.md
|
128
|
+
- doc/release_notes/0_18_2.md
|
129
|
+
- doc/release_notes/0_18_3.md
|
130
|
+
- doc/release_notes/0_18_4.md
|
131
|
+
- doc/release_notes/0_18_5.md
|
124
132
|
- doc/release_notes/0_1_0.md
|
125
133
|
- doc/release_notes/0_2_0.md
|
126
134
|
- doc/release_notes/0_2_1.md
|
@@ -303,7 +311,7 @@ metadata:
|
|
303
311
|
source_code_uri: https://gitlab.com/honeyryderchuck/httpx
|
304
312
|
homepage_uri: https://honeyryderchuck.gitlab.io/httpx/
|
305
313
|
rubygems_mfa_required: 'true'
|
306
|
-
post_install_message:
|
314
|
+
post_install_message:
|
307
315
|
rdoc_options: []
|
308
316
|
require_paths:
|
309
317
|
- lib
|
@@ -318,8 +326,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
318
326
|
- !ruby/object:Gem::Version
|
319
327
|
version: '0'
|
320
328
|
requirements: []
|
321
|
-
rubygems_version: 3.
|
322
|
-
signing_key:
|
329
|
+
rubygems_version: 3.2.32
|
330
|
+
signing_key:
|
323
331
|
specification_version: 4
|
324
332
|
summary: HTTPX, to the future, and beyond
|
325
333
|
test_files: []
|