httpx 0.6.4 → 0.6.5
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/lib/httpx/connection.rb +2 -3
- data/lib/httpx/io/udp.rb +12 -2
- data/lib/httpx/options.rb +1 -0
- data/lib/httpx/plugins/proxy.rb +10 -0
- data/lib/httpx/plugins/proxy/http.rb +8 -8
- data/lib/httpx/plugins/proxy/socks4.rb +2 -2
- data/lib/httpx/plugins/proxy/socks5.rb +2 -2
- data/lib/httpx/resolver/https.rb +3 -1
- data/lib/httpx/resolver/native.rb +25 -21
- data/lib/httpx/resolver/resolver_mixin.rb +6 -2
- data/lib/httpx/resolver/system.rb +7 -4
- data/lib/httpx/session.rb +8 -3
- data/lib/httpx/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 54a10e717268eab1bd790ceb5488f7641814e96f0edc7ff2252d020a73f956d4
|
4
|
+
data.tar.gz: fac249b2c424c310e8535bdd8940dfeec194b5438e30876da6a3875f349d49ab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 044c55f050be59ec7ef78bde8529b1957d120538c89d1488991b07d87cc60b34c66999861fe48b01719e712dd7ab1f03f349890e4ccc074303788b30798a5a90
|
7
|
+
data.tar.gz: 0a6b3a24a7d35e7cba39df0b58519b15c15361a96a2e458a1a0bab890a62922ed0cb34881cc506031d8be4a95505444e1401f4570f5d5286372baea548d4b2be
|
data/lib/httpx/connection.rb
CHANGED
@@ -254,8 +254,7 @@ module HTTPX
|
|
254
254
|
end
|
255
255
|
|
256
256
|
def send_pending
|
257
|
-
while !@write_buffer.full? && (
|
258
|
-
request = req_args
|
257
|
+
while !@write_buffer.full? && (request = @pending.shift)
|
259
258
|
parser.send(request)
|
260
259
|
end
|
261
260
|
end
|
@@ -368,7 +367,7 @@ module HTTPX
|
|
368
367
|
end
|
369
368
|
|
370
369
|
parser.handle_error(error) if @parser && parser.respond_to?(:handle_error)
|
371
|
-
@pending.
|
370
|
+
while (request = @pending.shift)
|
372
371
|
request.emit(:response, ErrorResponse.new(request, error, @options))
|
373
372
|
end
|
374
373
|
end
|
data/lib/httpx/io/udp.rb
CHANGED
@@ -24,8 +24,18 @@ module HTTPX
|
|
24
24
|
true
|
25
25
|
end
|
26
26
|
|
27
|
-
|
28
|
-
|
27
|
+
if RUBY_VERSION < "2.2"
|
28
|
+
# :nocov:
|
29
|
+
def close
|
30
|
+
@io.close
|
31
|
+
rescue StandardError
|
32
|
+
nil
|
33
|
+
end
|
34
|
+
# :nocov:
|
35
|
+
else
|
36
|
+
def close
|
37
|
+
@io.close
|
38
|
+
end
|
29
39
|
end
|
30
40
|
|
31
41
|
def write(buffer)
|
data/lib/httpx/options.rb
CHANGED
data/lib/httpx/plugins/proxy.rb
CHANGED
@@ -204,6 +204,16 @@ module HTTPX
|
|
204
204
|
transition(:closed)
|
205
205
|
emit(:close)
|
206
206
|
end
|
207
|
+
|
208
|
+
def transition(nextstate)
|
209
|
+
return super unless @options.proxy
|
210
|
+
|
211
|
+
case nextstate
|
212
|
+
when :closing
|
213
|
+
@state = :open if @state == :connecting
|
214
|
+
end
|
215
|
+
super
|
216
|
+
end
|
207
217
|
end
|
208
218
|
end
|
209
219
|
register_plugin :proxy, Proxy
|
@@ -41,7 +41,7 @@ module HTTPX
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def __http_proxy_connect
|
44
|
-
req
|
44
|
+
req = @pending.first
|
45
45
|
# if the first request after CONNECT is to an https address, it is assumed that
|
46
46
|
# all requests in the queue are not only ALL HTTPS, but they also share the certificate,
|
47
47
|
# and therefore, will share the connection.
|
@@ -55,17 +55,17 @@ module HTTPX
|
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
58
|
-
def __http_on_connect(
|
58
|
+
def __http_on_connect(_, response)
|
59
59
|
if response.status == 200
|
60
|
-
req
|
60
|
+
req = @pending.first
|
61
61
|
request_uri = req.uri
|
62
62
|
@io = ProxySSL.new(@io, request_uri, @options)
|
63
63
|
transition(:connected)
|
64
64
|
throw(:called)
|
65
65
|
else
|
66
|
-
pending = @pending
|
66
|
+
pending = @pending + @parser.pending
|
67
67
|
while (req = pending.shift)
|
68
|
-
emit(:response,
|
68
|
+
req.emit(:response, response)
|
69
69
|
end
|
70
70
|
end
|
71
71
|
end
|
@@ -78,6 +78,8 @@ module HTTPX
|
|
78
78
|
|
79
79
|
def set_request_headers(request)
|
80
80
|
super
|
81
|
+
proxy_params = @options.proxy
|
82
|
+
request.headers["proxy-authorization"] = "Basic #{proxy_params.token_authentication}" if proxy_params.authenticated?
|
81
83
|
request.headers["proxy-connection"] = request.headers["connection"]
|
82
84
|
request.headers.delete("connection")
|
83
85
|
end
|
@@ -102,10 +104,8 @@ module HTTPX
|
|
102
104
|
end
|
103
105
|
|
104
106
|
class ConnectRequest < Request
|
105
|
-
def initialize(uri,
|
107
|
+
def initialize(uri, _options)
|
106
108
|
super(:connect, uri, {})
|
107
|
-
proxy_params = options.proxy
|
108
|
-
@headers["proxy-authentication"] = "Basic #{proxy_params.token_authentication}" if proxy_params.authenticated?
|
109
109
|
@headers.delete("accept")
|
110
110
|
end
|
111
111
|
|
@@ -28,7 +28,7 @@ module HTTPX
|
|
28
28
|
@io.connect
|
29
29
|
return unless @io.connected?
|
30
30
|
|
31
|
-
req
|
31
|
+
req = @pending.first
|
32
32
|
return unless req
|
33
33
|
|
34
34
|
request_uri = req.uri
|
@@ -51,7 +51,7 @@ module HTTPX
|
|
51
51
|
def __socks4_on_packet(packet)
|
52
52
|
_version, status, _port, _ip = packet.unpack("CCnN")
|
53
53
|
if status == GRANTED
|
54
|
-
req
|
54
|
+
req = @pending.first
|
55
55
|
request_uri = req.uri
|
56
56
|
@io = ProxySSL.new(@io, request_uri, @options) if request_uri.scheme == "https"
|
57
57
|
transition(:connected)
|
@@ -52,7 +52,7 @@ module HTTPX
|
|
52
52
|
when :negotiating
|
53
53
|
return unless @state == :connecting || @state == :authenticating
|
54
54
|
|
55
|
-
req
|
55
|
+
req = @pending.first
|
56
56
|
request_uri = req.uri
|
57
57
|
@write_buffer << Packet.connect(request_uri)
|
58
58
|
when :connected
|
@@ -93,7 +93,7 @@ module HTTPX
|
|
93
93
|
version, reply, = packet.unpack("CC")
|
94
94
|
__socks5_check_version(version)
|
95
95
|
__on_socks5_error("socks5 negotiation error: #{reply}") unless reply == SUCCESS
|
96
|
-
req
|
96
|
+
req = @pending.first
|
97
97
|
request_uri = req.uri
|
98
98
|
@io = ProxySSL.new(@io, request_uri, @options) if request_uri.scheme == "https"
|
99
99
|
transition(:connected)
|
data/lib/httpx/resolver/https.rb
CHANGED
@@ -121,6 +121,7 @@ module HTTPX
|
|
121
121
|
rescue Resolv::DNS::DecodeError, JSON::JSONError => e
|
122
122
|
host, connection = @queries.first
|
123
123
|
if @_record_types[host].empty?
|
124
|
+
@queries.delete(host)
|
124
125
|
emit_resolve_error(connection, host, e)
|
125
126
|
return
|
126
127
|
end
|
@@ -129,6 +130,7 @@ module HTTPX
|
|
129
130
|
host, connection = @queries.first
|
130
131
|
@_record_types[host].shift
|
131
132
|
if @_record_types[host].empty?
|
133
|
+
@queries.delete(host)
|
132
134
|
@_record_types.delete(host)
|
133
135
|
emit_resolve_error(connection, host)
|
134
136
|
return
|
@@ -158,7 +160,7 @@ module HTTPX
|
|
158
160
|
next unless connection # probably a retried query for which there's an answer
|
159
161
|
|
160
162
|
@connections.delete(connection)
|
161
|
-
Resolver.cached_lookup_set(hostname, addresses)
|
163
|
+
Resolver.cached_lookup_set(hostname, addresses) if @resolver_options.cache
|
162
164
|
emit_addresses(connection, addresses.map { |addr| addr["data"] })
|
163
165
|
end
|
164
166
|
end
|
@@ -59,7 +59,7 @@ module HTTPX
|
|
59
59
|
@_record_types = Hash.new { |types, host| types[host] = @resolver_options.record_types.dup }
|
60
60
|
@connections = []
|
61
61
|
@queries = {}
|
62
|
-
@read_buffer =
|
62
|
+
@read_buffer = "".b
|
63
63
|
@write_buffer = Buffer.new(@resolver_options.packet_size)
|
64
64
|
@state = :idle
|
65
65
|
end
|
@@ -90,8 +90,7 @@ module HTTPX
|
|
90
90
|
consume
|
91
91
|
end
|
92
92
|
nil
|
93
|
-
rescue Errno::EHOSTUNREACH
|
94
|
-
NativeResolveError => e
|
93
|
+
rescue Errno::EHOSTUNREACH => e
|
95
94
|
@ns_index += 1
|
96
95
|
if @ns_index < @nameserver.size
|
97
96
|
log(label: "resolver: ") do
|
@@ -101,25 +100,14 @@ module HTTPX
|
|
101
100
|
end
|
102
101
|
transition(:idle)
|
103
102
|
else
|
104
|
-
|
105
|
-
e.respond_to?(:host)
|
106
|
-
emit_resolve_error(e.connection, e.host, e)
|
107
|
-
else
|
108
|
-
@queries.each do |host, connection|
|
109
|
-
emit_resolve_error(connection, host, e)
|
110
|
-
end
|
111
|
-
end
|
103
|
+
handle_error(e)
|
112
104
|
end
|
105
|
+
rescue NativeResolveError => e
|
106
|
+
handle_error(e)
|
113
107
|
end
|
114
108
|
|
115
109
|
def interests
|
116
|
-
|
117
|
-
writable = !@write_buffer.empty?
|
118
|
-
if readable
|
119
|
-
writable ? :rw : :r
|
120
|
-
else
|
121
|
-
writable ? :w : :r
|
122
|
-
end
|
110
|
+
!@write_buffer.empty? || @queries.empty? ? :w : :r
|
123
111
|
end
|
124
112
|
|
125
113
|
def <<(connection)
|
@@ -168,6 +156,7 @@ module HTTPX
|
|
168
156
|
@timeouts[host].shift
|
169
157
|
if @timeouts[host].empty?
|
170
158
|
@timeouts.delete(host)
|
159
|
+
@connections.delete(connection)
|
171
160
|
raise NativeResolveError.new(connection, host)
|
172
161
|
else
|
173
162
|
connections << connection
|
@@ -182,7 +171,7 @@ module HTTPX
|
|
182
171
|
connections.each { |ch| resolve(ch) }
|
183
172
|
end
|
184
173
|
|
185
|
-
def dread(wsize = @
|
174
|
+
def dread(wsize = @resolver_options.packet_size)
|
186
175
|
loop do
|
187
176
|
siz = @io.read(wsize, @read_buffer)
|
188
177
|
unless siz
|
@@ -192,7 +181,7 @@ module HTTPX
|
|
192
181
|
return if siz.zero?
|
193
182
|
|
194
183
|
log(label: "resolver: ") { "READ: #{siz} bytes..." }
|
195
|
-
parse(@read_buffer
|
184
|
+
parse(@read_buffer)
|
196
185
|
end
|
197
186
|
end
|
198
187
|
|
@@ -216,6 +205,8 @@ module HTTPX
|
|
216
205
|
rescue Resolv::DNS::DecodeError => e
|
217
206
|
hostname, connection = @queries.first
|
218
207
|
if @_record_types[hostname].empty?
|
208
|
+
@queries.delete(hostname)
|
209
|
+
@connections.delete(connection)
|
219
210
|
ex = NativeResolveError.new(connection, hostname, e.message)
|
220
211
|
ex.set_backtrace(e.backtrace)
|
221
212
|
raise ex
|
@@ -226,7 +217,9 @@ module HTTPX
|
|
226
217
|
hostname, connection = @queries.first
|
227
218
|
@_record_types[hostname].shift
|
228
219
|
if @_record_types[hostname].empty?
|
220
|
+
@queries.delete(hostname)
|
229
221
|
@_record_types.delete(hostname)
|
222
|
+
@connections.delete(connection)
|
230
223
|
raise NativeResolveError.new(connection, hostname)
|
231
224
|
end
|
232
225
|
else
|
@@ -244,7 +237,7 @@ module HTTPX
|
|
244
237
|
end
|
245
238
|
else
|
246
239
|
@connections.delete(connection)
|
247
|
-
Resolver.cached_lookup_set(connection.origin.host, addresses)
|
240
|
+
Resolver.cached_lookup_set(connection.origin.host, addresses) if @resolver_options.cache
|
248
241
|
emit_addresses(connection, addresses.map { |addr| addr["data"] })
|
249
242
|
end
|
250
243
|
end
|
@@ -301,5 +294,16 @@ module HTTPX
|
|
301
294
|
end
|
302
295
|
@state = nextstate
|
303
296
|
end
|
297
|
+
|
298
|
+
def handle_error(error)
|
299
|
+
if error.respond_to?(:connection) &&
|
300
|
+
error.respond_to?(:host)
|
301
|
+
emit_resolve_error(error.connection, error.host, error)
|
302
|
+
else
|
303
|
+
@queries.each do |host, connection|
|
304
|
+
emit_resolve_error(connection, host, error)
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|
304
308
|
end
|
305
309
|
end
|
@@ -38,7 +38,7 @@ module HTTPX
|
|
38
38
|
def early_resolve(connection, hostname: connection.origin.host)
|
39
39
|
addresses = connection.addresses ||
|
40
40
|
ip_resolve(hostname) ||
|
41
|
-
Resolver.cached_lookup(hostname) ||
|
41
|
+
(@resolver_options.cache && Resolver.cached_lookup(hostname)) ||
|
42
42
|
system_resolve(hostname)
|
43
43
|
return unless addresses
|
44
44
|
|
@@ -58,10 +58,14 @@ module HTTPX
|
|
58
58
|
end
|
59
59
|
|
60
60
|
def emit_resolve_error(connection, hostname, ex = nil)
|
61
|
+
emit(:error, connection, resolve_error(hostname, ex))
|
62
|
+
end
|
63
|
+
|
64
|
+
def resolve_error(hostname, ex = nil)
|
61
65
|
message = ex ? ex.message : "Can't resolve #{hostname}"
|
62
66
|
error = ResolveError.new(message)
|
63
67
|
error.set_backtrace(ex ? ex.backtrace : caller)
|
64
|
-
|
68
|
+
error
|
65
69
|
end
|
66
70
|
end
|
67
71
|
end
|
@@ -14,10 +14,13 @@ module HTTPX
|
|
14
14
|
|
15
15
|
def initialize(options)
|
16
16
|
@options = Options.new(options)
|
17
|
-
|
17
|
+
@resolver_options = Resolver::Options.new(@options.resolver_options)
|
18
18
|
@state = :idle
|
19
|
-
|
20
|
-
|
19
|
+
resolv_options = @resolver_options.to_h
|
20
|
+
timeouts = resolv_options.delete(:timeouts)
|
21
|
+
resolv_options.delete(:cache)
|
22
|
+
@resolver = Resolv::DNS.new(resolv_options.empty? ? nil : resolv_options)
|
23
|
+
@resolver.timeouts = timeouts if timeouts
|
21
24
|
end
|
22
25
|
|
23
26
|
def closed?
|
@@ -34,7 +37,7 @@ module HTTPX
|
|
34
37
|
ip_resolve(hostname) ||
|
35
38
|
system_resolve(hostname) ||
|
36
39
|
@resolver.getaddresses(hostname)
|
37
|
-
|
40
|
+
throw(:resolve_error, resolve_error(hostname)) if addresses.empty?
|
38
41
|
|
39
42
|
emit_addresses(connection, addresses)
|
40
43
|
rescue Errno::EHOSTUNREACH, *RESOLV_ERRORS => e
|
data/lib/httpx/session.rb
CHANGED
@@ -152,9 +152,14 @@ module HTTPX
|
|
152
152
|
request_options = @options.merge(options)
|
153
153
|
|
154
154
|
requests.each do |request|
|
155
|
-
|
156
|
-
|
157
|
-
|
155
|
+
error = catch(:resolve_error) do
|
156
|
+
connection = find_connection(request, connections, request_options)
|
157
|
+
connection.send(request)
|
158
|
+
set_request_timeout(connection, request, request_options)
|
159
|
+
end
|
160
|
+
next unless error.is_a?(ResolveError)
|
161
|
+
|
162
|
+
request.emit(:response, ErrorResponse.new(request, error, options))
|
158
163
|
end
|
159
164
|
|
160
165
|
responses = []
|
data/lib/httpx/version.rb
CHANGED
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.6.
|
4
|
+
version: 0.6.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tiago Cardoso
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-02-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: http-2-next
|