httpx 0.6.3 → 0.6.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/lib/httpx.rb +2 -0
- data/lib/httpx/adapters/faraday.rb +10 -6
- data/lib/httpx/altsvc.rb +2 -0
- data/lib/httpx/connection.rb +9 -7
- data/lib/httpx/headers.rb +6 -0
- data/lib/httpx/io/ssl.rb +6 -4
- data/lib/httpx/io/tcp.rb +10 -7
- data/lib/httpx/io/udp.rb +2 -0
- data/lib/httpx/plugins/compression.rb +1 -1
- data/lib/httpx/plugins/digest_authentication.rb +10 -16
- data/lib/httpx/plugins/h2c.rb +1 -14
- data/lib/httpx/plugins/proxy.rb +13 -3
- data/lib/httpx/plugins/proxy/socks4.rb +3 -2
- data/lib/httpx/plugins/proxy/socks5.rb +6 -6
- data/lib/httpx/plugins/push_promise.rb +2 -0
- data/lib/httpx/pool.rb +10 -2
- data/lib/httpx/request.rb +16 -1
- data/lib/httpx/resolver/https.rb +8 -4
- data/lib/httpx/resolver/native.rb +8 -0
- data/lib/httpx/response.rb +15 -1
- data/lib/httpx/timeout.rb +3 -1
- data/lib/httpx/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b8a8f66dc2833078c5d718a91b0aa5ab0f3cfd0ddfa021ddebe491dc8a74cda1
|
4
|
+
data.tar.gz: b722b06b29af3a535efdc5da32298c358b5cb91ab248224fe21bc5f15982cbfb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c2a70d09852cf6612b50cf13fa54cdb71111bec0583f12830d58a5e042b0dae316e84d3e4b4db132bad77cda88fefd7d7cdd3c6b9ab288c08fdc573b8ff2e3fb
|
7
|
+
data.tar.gz: fd164d361e5e9b3d7c7439567c014a748c6eedb4b1887ff20213f653ea7234ca5567cd96bc71d651637049bf6405751f46fe423638ae1b820dac4767b2434fc9
|
data/lib/httpx.rb
CHANGED
@@ -47,11 +47,13 @@ module HTTPX
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
+
# :nocov:
|
50
51
|
def self.const_missing(const_name)
|
51
52
|
super unless const_name == :Client
|
52
53
|
warn "DEPRECATION WARNING: the class #{self}::Client is deprecated. Use #{self}::Session instead."
|
53
54
|
Session
|
54
55
|
end
|
56
|
+
# :nocov:
|
55
57
|
|
56
58
|
extend Chainable
|
57
59
|
end
|
@@ -6,6 +6,7 @@ require "faraday"
|
|
6
6
|
module Faraday
|
7
7
|
class Adapter
|
8
8
|
class HTTPX < Faraday::Adapter
|
9
|
+
# :nocov:
|
9
10
|
SSL_ERROR = if defined?(Faraday::SSLError)
|
10
11
|
Faraday::SSLError
|
11
12
|
else
|
@@ -17,6 +18,7 @@ module Faraday
|
|
17
18
|
else
|
18
19
|
Faraday::Error::ConnectionFailed
|
19
20
|
end
|
21
|
+
# :nocov:
|
20
22
|
|
21
23
|
module RequestMixin
|
22
24
|
private
|
@@ -63,6 +65,7 @@ module Faraday
|
|
63
65
|
plugin(:compression)
|
64
66
|
plugin(:persistent)
|
65
67
|
|
68
|
+
# :nocov:
|
66
69
|
module ReasonPlugin
|
67
70
|
if RUBY_VERSION < "2.5"
|
68
71
|
def self.load_dependencies(*)
|
@@ -85,6 +88,7 @@ module Faraday
|
|
85
88
|
end
|
86
89
|
end
|
87
90
|
end
|
91
|
+
# :nocov:
|
88
92
|
plugin(ReasonPlugin)
|
89
93
|
end
|
90
94
|
|
@@ -185,26 +189,26 @@ module Faraday
|
|
185
189
|
return handler
|
186
190
|
end
|
187
191
|
|
188
|
-
request_options = build_request(env)
|
192
|
+
meth, uri, request_options = build_request(env)
|
189
193
|
|
190
194
|
session = @session.with(options_from_env(env))
|
191
195
|
session = session.plugin(:proxy).with_proxy(proxy_options) if env.request.proxy
|
192
|
-
response = session.__send__(
|
196
|
+
response = session.__send__(meth, uri, **request_options)
|
193
197
|
response.raise_for_status unless response.is_a?(::HTTPX::Response)
|
194
198
|
save_response(env, response.status, response.body.to_s, response.headers, response.reason) do |response_headers|
|
195
199
|
response_headers.merge!(response.headers)
|
196
200
|
end
|
197
201
|
@app.call(env)
|
198
|
-
rescue OpenSSL::SSL::SSLError =>
|
199
|
-
raise SSL_ERROR,
|
202
|
+
rescue OpenSSL::SSL::SSLError => e
|
203
|
+
raise SSL_ERROR, e
|
200
204
|
rescue Errno::ECONNABORTED,
|
201
205
|
Errno::ECONNREFUSED,
|
202
206
|
Errno::ECONNRESET,
|
203
207
|
Errno::EHOSTUNREACH,
|
204
208
|
Errno::EINVAL,
|
205
209
|
Errno::ENETUNREACH,
|
206
|
-
Errno::EPIPE =>
|
207
|
-
raise CONNECTION_FAILED_ERROR,
|
210
|
+
Errno::EPIPE => e
|
211
|
+
raise CONNECTION_FAILED_ERROR, e
|
208
212
|
end
|
209
213
|
|
210
214
|
private
|
data/lib/httpx/altsvc.rb
CHANGED
@@ -67,6 +67,7 @@ module HTTPX
|
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
|
+
# :nocov:
|
70
71
|
if RUBY_VERSION < "2.2"
|
71
72
|
def parse_altsvc_origin(alt_origin)
|
72
73
|
alt_proto, alt_origin = alt_origin.split("=")
|
@@ -87,5 +88,6 @@ module HTTPX
|
|
87
88
|
URI.parse("#{alt_proto}://#{alt_origin}")
|
88
89
|
end
|
89
90
|
end
|
91
|
+
# :nocov:
|
90
92
|
end
|
91
93
|
end
|
data/lib/httpx/connection.rb
CHANGED
@@ -128,9 +128,9 @@ module HTTPX
|
|
128
128
|
end
|
129
129
|
|
130
130
|
def purge_pending
|
131
|
-
[
|
132
|
-
pending.reject! do |request
|
133
|
-
yield
|
131
|
+
[*@parser.pending, *@pending].each do |pending|
|
132
|
+
pending.reject! do |request|
|
133
|
+
yield request
|
134
134
|
end
|
135
135
|
end
|
136
136
|
end
|
@@ -358,15 +358,17 @@ module HTTPX
|
|
358
358
|
end
|
359
359
|
|
360
360
|
def handle_error(error)
|
361
|
-
if error.instance_of?(TimeoutError)
|
362
|
-
@timeout
|
363
|
-
|
361
|
+
if error.instance_of?(TimeoutError)
|
362
|
+
if @timeout
|
363
|
+
@timeout -= error.timeout
|
364
|
+
return unless @timeout <= 0
|
365
|
+
end
|
364
366
|
|
365
367
|
error = error.to_connection_error if connecting?
|
366
368
|
end
|
367
369
|
|
368
370
|
parser.handle_error(error) if @parser && parser.respond_to?(:handle_error)
|
369
|
-
@pending.each do |request
|
371
|
+
@pending.each do |request|
|
370
372
|
request.emit(:response, ErrorResponse.new(request, error, @options))
|
371
373
|
end
|
372
374
|
end
|
data/lib/httpx/headers.rb
CHANGED
@@ -130,6 +130,12 @@ module HTTPX
|
|
130
130
|
@headers.to_s
|
131
131
|
end
|
132
132
|
|
133
|
+
# :nocov:
|
134
|
+
def inspect
|
135
|
+
to_hash.inspect
|
136
|
+
end
|
137
|
+
# :nocov:
|
138
|
+
|
133
139
|
# this is internal API and doesn't abide to other public API
|
134
140
|
# guarantees, like downcasing strings.
|
135
141
|
# Please do not use this outside of core!
|
data/lib/httpx/io/ssl.rb
CHANGED
@@ -7,7 +7,9 @@ module HTTPX
|
|
7
7
|
TLS_OPTIONS = if OpenSSL::SSL::SSLContext.instance_methods.include?(:alpn_protocols)
|
8
8
|
{ alpn_protocols: %w[h2 http/1.1] }
|
9
9
|
else
|
10
|
+
# :nocov:
|
10
11
|
{}
|
12
|
+
# :nocov:
|
11
13
|
end
|
12
14
|
|
13
15
|
def initialize(_, _, options)
|
@@ -18,10 +20,6 @@ module HTTPX
|
|
18
20
|
@state = :negotiated if @keep_open
|
19
21
|
end
|
20
22
|
|
21
|
-
def scheme
|
22
|
-
"https"
|
23
|
-
end
|
24
|
-
|
25
23
|
def protocol
|
26
24
|
@io.alpn_protocol || super
|
27
25
|
rescue StandardError
|
@@ -68,6 +66,7 @@ module HTTPX
|
|
68
66
|
::IO::WaitWritable
|
69
67
|
end
|
70
68
|
|
69
|
+
# :nocov:
|
71
70
|
if RUBY_VERSION < "2.3"
|
72
71
|
def read(*)
|
73
72
|
super
|
@@ -93,11 +92,14 @@ module HTTPX
|
|
93
92
|
end
|
94
93
|
end
|
95
94
|
end
|
95
|
+
# :nocov:
|
96
96
|
|
97
|
+
# :nocov:
|
97
98
|
def inspect
|
98
99
|
id = @io.closed? ? "closed" : @io.to_io.fileno
|
99
100
|
"#<SSL(fd: #{id}): #{@ip}:#{@port} state: #{@state}>"
|
100
101
|
end
|
102
|
+
# :nocov:
|
101
103
|
|
102
104
|
private
|
103
105
|
|
data/lib/httpx/io/tcp.rb
CHANGED
@@ -41,10 +41,6 @@ module HTTPX
|
|
41
41
|
@io ||= build_socket
|
42
42
|
end
|
43
43
|
|
44
|
-
def scheme
|
45
|
-
"http"
|
46
|
-
end
|
47
|
-
|
48
44
|
def to_io
|
49
45
|
@io.to_io
|
50
46
|
end
|
@@ -68,6 +64,11 @@ module HTTPX
|
|
68
64
|
rescue Errno::EHOSTUNREACH => e
|
69
65
|
raise e if @ip_index <= 0
|
70
66
|
|
67
|
+
@ip_index -= 1
|
68
|
+
retry
|
69
|
+
rescue Errno::ETIMEDOUT => e
|
70
|
+
raise ConnectTimeout, e.message if @ip_index <= 0
|
71
|
+
|
71
72
|
@ip_index -= 1
|
72
73
|
retry
|
73
74
|
rescue Errno::EINPROGRESS,
|
@@ -76,6 +77,7 @@ module HTTPX
|
|
76
77
|
end
|
77
78
|
|
78
79
|
if RUBY_VERSION < "2.3"
|
80
|
+
# :nocov:
|
79
81
|
def read(size, buffer)
|
80
82
|
@io.read_nonblock(size, buffer)
|
81
83
|
buffer.bytesize
|
@@ -94,6 +96,7 @@ module HTTPX
|
|
94
96
|
rescue EOFError
|
95
97
|
nil
|
96
98
|
end
|
99
|
+
# :nocov:
|
97
100
|
else
|
98
101
|
def read(size, buffer)
|
99
102
|
ret = @io.read_nonblock(size, buffer, exception: false)
|
@@ -131,10 +134,12 @@ module HTTPX
|
|
131
134
|
@state == :idle || @state == :closed
|
132
135
|
end
|
133
136
|
|
137
|
+
# :nocov:
|
134
138
|
def inspect
|
135
139
|
id = @io.closed? ? "closed" : @io.fileno
|
136
140
|
"#<TCP(fd: #{id}): #{@ip}:#{@port} (state: #{@state})>"
|
137
141
|
end
|
142
|
+
# :nocov:
|
138
143
|
|
139
144
|
private
|
140
145
|
|
@@ -154,9 +159,7 @@ module HTTPX
|
|
154
159
|
end
|
155
160
|
|
156
161
|
def do_transition(nextstate)
|
157
|
-
log(level: 1)
|
158
|
-
log_transition_state(nextstate)
|
159
|
-
end
|
162
|
+
log(level: 1) { log_transition_state(nextstate) }
|
160
163
|
@state = nextstate
|
161
164
|
end
|
162
165
|
|
data/lib/httpx/io/udp.rb
CHANGED
@@ -59,9 +59,7 @@ module HTTPX
|
|
59
59
|
prev_response = response
|
60
60
|
end
|
61
61
|
|
62
|
-
|
63
|
-
|
64
|
-
responses
|
62
|
+
responses.size == 1 ? responses.first : responses
|
65
63
|
end
|
66
64
|
end
|
67
65
|
|
@@ -81,8 +79,9 @@ module HTTPX
|
|
81
79
|
|
82
80
|
uri = request.path
|
83
81
|
|
84
|
-
params = Hash[auth_info.
|
85
|
-
|
82
|
+
params = Hash[auth_info.split(/ *, */)
|
83
|
+
.map { |val| val.split("=") }
|
84
|
+
.map { |k, v| [k, v.delete("\"")] }]
|
86
85
|
nonce = params["nonce"]
|
87
86
|
nc = next_nonce
|
88
87
|
|
@@ -90,24 +89,19 @@ module HTTPX
|
|
90
89
|
qop = params["qop"]
|
91
90
|
|
92
91
|
if params["algorithm"] =~ /(.*?)(-sess)?$/
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
when "SHA256" then ::Digest::SHA256
|
98
|
-
when "SHA384" then ::Digest::SHA384
|
99
|
-
when "SHA512" then ::Digest::SHA512
|
100
|
-
when "RMD160" then ::Digest::RMD160
|
101
|
-
else raise DigestError, "unknown algorithm \"#{Regexp.last_match(1)}\""
|
102
|
-
end
|
92
|
+
alg = Regexp.last_match(1)
|
93
|
+
algorithm = ::Digest.const_get(alg)
|
94
|
+
raise DigestError, "unknown algorithm \"#{alg}\"" unless algorithm
|
95
|
+
|
103
96
|
sess = Regexp.last_match(2)
|
97
|
+
params.delete("algorithm")
|
104
98
|
else
|
105
99
|
algorithm = ::Digest::MD5
|
106
100
|
end
|
107
101
|
|
108
102
|
if qop || sess
|
109
103
|
cnonce = make_cnonce
|
110
|
-
nc = format("
|
104
|
+
nc = format("%<nonce>08x", nonce: nc)
|
111
105
|
end
|
112
106
|
|
113
107
|
a1 = if sess
|
data/lib/httpx/plugins/h2c.rb
CHANGED
@@ -30,9 +30,7 @@ module HTTPX
|
|
30
30
|
|
31
31
|
responses = send_requests(*requests, h2c_options)
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
responses
|
33
|
+
responses.size == 1 ? responses.first : responses
|
36
34
|
end
|
37
35
|
|
38
36
|
private
|
@@ -109,17 +107,6 @@ module HTTPX
|
|
109
107
|
super("http/1.1")
|
110
108
|
end
|
111
109
|
end
|
112
|
-
|
113
|
-
module FrameBuilder
|
114
|
-
include HTTP2Next
|
115
|
-
|
116
|
-
module_function
|
117
|
-
|
118
|
-
def settings_value(settings)
|
119
|
-
frame = Framer.new.generate(type: :settings, stream: 0, payload: settings)
|
120
|
-
Base64.urlsafe_encode64(frame[9..-1])
|
121
|
-
end
|
122
|
-
end
|
123
110
|
end
|
124
111
|
register_plugin(:h2c, H2C)
|
125
112
|
end
|
data/lib/httpx/plugins/proxy.rb
CHANGED
@@ -5,6 +5,7 @@ require "ipaddr"
|
|
5
5
|
require "forwardable"
|
6
6
|
|
7
7
|
module HTTPX
|
8
|
+
HTTPProxyError = Class.new(Error)
|
8
9
|
module Plugins
|
9
10
|
#
|
10
11
|
# This plugin adds support for proxies. It ships with support for:
|
@@ -17,7 +18,7 @@ module HTTPX
|
|
17
18
|
# https://gitlab.com/honeyryderchuck/httpx/wikis/Proxy
|
18
19
|
#
|
19
20
|
module Proxy
|
20
|
-
Error =
|
21
|
+
Error = HTTPProxyError
|
21
22
|
PROXY_ERRORS = [TimeoutError, IOError, SystemCallError, Error].freeze
|
22
23
|
|
23
24
|
class Parameters
|
@@ -34,14 +35,23 @@ module HTTPX
|
|
34
35
|
end
|
35
36
|
|
36
37
|
def token_authentication
|
37
|
-
|
38
|
+
return unless authenticated?
|
39
|
+
|
40
|
+
Base64.strict_encode64("#{@username}:#{@password}")
|
38
41
|
end
|
39
42
|
|
40
43
|
def ==(other)
|
41
|
-
|
44
|
+
case other
|
45
|
+
when Parameters
|
42
46
|
@uri == other.uri &&
|
43
47
|
@username == other.username &&
|
44
48
|
@password == other.password
|
49
|
+
when URI::Generic, String
|
50
|
+
proxy_uri = @uri.dup
|
51
|
+
proxy_uri.user = @username
|
52
|
+
proxy_uri.password = @password
|
53
|
+
other_uri = other.is_a?(URI::Generic) ? other : URI.parse(other)
|
54
|
+
proxy_uri == other_uri
|
45
55
|
else
|
46
56
|
super
|
47
57
|
end
|
@@ -4,6 +4,7 @@ require "resolv"
|
|
4
4
|
require "ipaddr"
|
5
5
|
|
6
6
|
module HTTPX
|
7
|
+
Socks4Error = Class.new(Error)
|
7
8
|
module Plugins
|
8
9
|
module Proxy
|
9
10
|
module Socks4
|
@@ -12,7 +13,7 @@ module HTTPX
|
|
12
13
|
GRANTED = 90
|
13
14
|
PROTOCOLS = %w[socks4 socks4a].freeze
|
14
15
|
|
15
|
-
Error =
|
16
|
+
Error = Socks4Error
|
16
17
|
|
17
18
|
module ConnectionMethods
|
18
19
|
private
|
@@ -100,7 +101,7 @@ module HTTPX
|
|
100
101
|
|
101
102
|
packet << [ip.to_i].pack("N")
|
102
103
|
rescue IPAddr::InvalidAddressError
|
103
|
-
if parameters.uri.scheme
|
104
|
+
if parameters.uri.scheme =~ /^socks4a?$/
|
104
105
|
# resolv defaults to IPv4, and socks4 doesn't support IPv6 otherwise
|
105
106
|
ip = IPAddr.new(Resolv.getaddress(uri.host))
|
106
107
|
packet << [ip.to_i].pack("N")
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module HTTPX
|
4
|
+
Socks5Error = Class.new(Error)
|
4
5
|
module Plugins
|
5
6
|
module Proxy
|
6
7
|
module Socks5
|
@@ -14,7 +15,7 @@ module HTTPX
|
|
14
15
|
IPV6 = 4
|
15
16
|
SUCCESS = 0
|
16
17
|
|
17
|
-
Error =
|
18
|
+
Error = Socks5Error
|
18
19
|
|
19
20
|
module ConnectionMethods
|
20
21
|
def call
|
@@ -77,15 +78,14 @@ module HTTPX
|
|
77
78
|
case method
|
78
79
|
when PASSWD
|
79
80
|
transition(:authenticating)
|
80
|
-
|
81
|
+
nil
|
81
82
|
when NONE
|
82
83
|
__on_socks5_error("no supported authorization methods")
|
83
84
|
else
|
84
85
|
transition(:negotiating)
|
85
86
|
end
|
86
87
|
when :authenticating
|
87
|
-
|
88
|
-
__socks5_check_version(version)
|
88
|
+
_, status = packet.unpack("CC")
|
89
89
|
return transition(:negotiating) if status == SUCCESS
|
90
90
|
|
91
91
|
__on_socks5_error("socks authentication error: #{status}")
|
@@ -147,8 +147,8 @@ module HTTPX
|
|
147
147
|
|
148
148
|
def authenticate(parameters)
|
149
149
|
user = parameters.username
|
150
|
-
|
151
|
-
[0x01, user.bytesize, user,
|
150
|
+
password = parameters.password
|
151
|
+
[0x01, user.bytesize, user, password.bytesize, password].pack("CCA*CA*")
|
152
152
|
end
|
153
153
|
|
154
154
|
def connect(uri)
|
@@ -44,7 +44,9 @@ module HTTPX
|
|
44
44
|
|
45
45
|
def __on_promise_request(parser, stream, h)
|
46
46
|
log(level: 1, label: "#{stream.id}: ") do
|
47
|
+
# :nocov:
|
47
48
|
h.map { |k, v| "-> PROMISE HEADER: #{k}: #{v}" }.join("\n")
|
49
|
+
# :nocov:
|
48
50
|
end
|
49
51
|
headers = @options.headers_class.new(h)
|
50
52
|
path = headers[":path"]
|
data/lib/httpx/pool.rb
CHANGED
@@ -33,9 +33,9 @@ module HTTPX
|
|
33
33
|
end
|
34
34
|
@timers.fire
|
35
35
|
end
|
36
|
-
rescue StandardError =>
|
36
|
+
rescue StandardError => e
|
37
37
|
@connections.each do |connection|
|
38
|
-
connection.emit(:error,
|
38
|
+
connection.emit(:error, e)
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
@@ -161,7 +161,15 @@ module HTTPX
|
|
161
161
|
resolver.on(:error, &method(:on_resolver_error))
|
162
162
|
resolver.on(:close) { on_resolver_close(resolver) }
|
163
163
|
resolver
|
164
|
+
# rubocop: disable Layout/RescueEnsureAlignment
|
165
|
+
rescue ArgumentError
|
166
|
+
# this block is here because of an error which happens on CI from time to time
|
167
|
+
warn "tried resolver: #{resolver_type}"
|
168
|
+
warn "initialize: #{resolver_type.instance_method(:initialize).source_location}"
|
169
|
+
warn "new: #{resolver_type.method(:new).source_location}"
|
170
|
+
raise
|
164
171
|
end
|
172
|
+
# rubocop: enable Layout/RescueEnsureAlignment
|
165
173
|
end
|
166
174
|
end
|
167
175
|
end
|
data/lib/httpx/request.rb
CHANGED
@@ -60,6 +60,7 @@ module HTTPX
|
|
60
60
|
@state = :idle
|
61
61
|
end
|
62
62
|
|
63
|
+
# :nocov:
|
63
64
|
if RUBY_VERSION < "2.2"
|
64
65
|
# rubocop: disable Lint/UriEscapeUnescape:
|
65
66
|
def initialize_with_escape(verb, uri, options = {})
|
@@ -69,6 +70,7 @@ module HTTPX
|
|
69
70
|
alias_method :initialize, :initialize_with_escape
|
70
71
|
# rubocop: enable Lint/UriEscapeUnescape:
|
71
72
|
end
|
73
|
+
# :nocov:
|
72
74
|
|
73
75
|
def merge_headers(h)
|
74
76
|
@headers = @headers.merge(h)
|
@@ -123,9 +125,15 @@ module HTTPX
|
|
123
125
|
nil
|
124
126
|
end
|
125
127
|
|
128
|
+
# :nocov:
|
126
129
|
def inspect
|
127
|
-
"#<Request
|
130
|
+
"#<HTTPX::Request:#{object_id} " \
|
131
|
+
"#{@verb.to_s.upcase} " \
|
132
|
+
"#{uri} " \
|
133
|
+
"@headers=#{@headers} " \
|
134
|
+
"@body=#{@body}>"
|
128
135
|
end
|
136
|
+
# :nocov:
|
129
137
|
|
130
138
|
class Body
|
131
139
|
class << self
|
@@ -201,6 +209,13 @@ module HTTPX
|
|
201
209
|
def chunk!
|
202
210
|
@headers.add("transfer-encoding", "chunked")
|
203
211
|
end
|
212
|
+
|
213
|
+
# :nocov:
|
214
|
+
def inspect
|
215
|
+
"#<HTTPX::Request::Body:#{object_id} " \
|
216
|
+
"#{unbounded_body? ? "stream" : "@bytesize=#{bytesize}"}>"
|
217
|
+
end
|
218
|
+
# :nocov:
|
204
219
|
end
|
205
220
|
|
206
221
|
def transition(nextstate)
|
data/lib/httpx/resolver/https.rb
CHANGED
@@ -9,6 +9,7 @@ module HTTPX
|
|
9
9
|
class Resolver::HTTPS
|
10
10
|
extend Forwardable
|
11
11
|
include Resolver::ResolverMixin
|
12
|
+
using URIExtensions
|
12
13
|
|
13
14
|
NAMESERVER = "https://1.1.1.1/dns-query"
|
14
15
|
|
@@ -38,7 +39,10 @@ module HTTPX
|
|
38
39
|
end
|
39
40
|
|
40
41
|
def <<(connection)
|
42
|
+
return if @uri.origin == connection.origin.to_s
|
43
|
+
|
41
44
|
@uri_addresses ||= Resolv.getaddresses(@uri.host)
|
45
|
+
|
42
46
|
if @uri_addresses.empty?
|
43
47
|
ex = ResolveError.new("Can't resolve #{connection.origin.host}")
|
44
48
|
ex.set_backtrace(caller)
|
@@ -94,11 +98,11 @@ module HTTPX
|
|
94
98
|
|
95
99
|
def on_response(request, response)
|
96
100
|
response.raise_for_status
|
97
|
-
rescue
|
101
|
+
rescue StandardError => e
|
98
102
|
connection = @requests[request]
|
99
103
|
hostname = @queries.key(connection)
|
100
|
-
error = ResolveError.new("Can't resolve #{hostname}: #{
|
101
|
-
error.set_backtrace(
|
104
|
+
error = ResolveError.new("Can't resolve #{hostname}: #{e.message}")
|
105
|
+
error.set_backtrace(e.backtrace)
|
102
106
|
emit(:error, connection, error)
|
103
107
|
else
|
104
108
|
parse(response)
|
@@ -176,8 +180,8 @@ module HTTPX
|
|
176
180
|
payload = Resolver.encode_dns_query(hostname, type: RECORD_TYPES[type])
|
177
181
|
request = rklass.new("POST", uri, @options.merge(body: [payload]))
|
178
182
|
request.headers["content-type"] = "application/dns-message"
|
179
|
-
request.headers["accept"] = "application/dns-message"
|
180
183
|
end
|
184
|
+
request.headers["accept"] = "application/dns-message"
|
181
185
|
request.on(:response, &method(:on_response).curry[request])
|
182
186
|
request.on(:promise, &method(:on_promise))
|
183
187
|
request
|
@@ -14,6 +14,7 @@ module HTTPX
|
|
14
14
|
"AAAA" => Resolv::DNS::Resource::IN::AAAA,
|
15
15
|
}.freeze
|
16
16
|
|
17
|
+
# :nocov:
|
17
18
|
DEFAULTS = if RUBY_VERSION < "2.2"
|
18
19
|
{
|
19
20
|
**Resolv::DNS::Config.default_config_hash,
|
@@ -42,6 +43,7 @@ module HTTPX
|
|
42
43
|
false
|
43
44
|
end
|
44
45
|
end if DEFAULTS[:nameserver]
|
46
|
+
# :nocov:
|
45
47
|
|
46
48
|
DNS_PORT = 53
|
47
49
|
|
@@ -93,7 +95,9 @@ module HTTPX
|
|
93
95
|
@ns_index += 1
|
94
96
|
if @ns_index < @nameserver.size
|
95
97
|
log(label: "resolver: ") do
|
98
|
+
# :nocov:
|
96
99
|
"failed resolving on nameserver #{@nameserver[@ns_index - 1]} (#{e.message})"
|
100
|
+
# :nocov:
|
97
101
|
end
|
98
102
|
transition(:idle)
|
99
103
|
else
|
@@ -132,6 +136,8 @@ module HTTPX
|
|
132
136
|
end
|
133
137
|
|
134
138
|
def timeout
|
139
|
+
return if @connections.empty?
|
140
|
+
|
135
141
|
@start_timeout = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
136
142
|
hosts = @queries.keys
|
137
143
|
@timeouts.values_at(*hosts).reject(&:empty?).map(&:first).min
|
@@ -166,7 +172,9 @@ module HTTPX
|
|
166
172
|
else
|
167
173
|
connections << connection
|
168
174
|
log(label: "resolver: ") do
|
175
|
+
# :nocov:
|
169
176
|
"timeout after #{prev_timeout}s, retry(#{timeouts.first}) #{host}..."
|
177
|
+
# :nocov:
|
170
178
|
end
|
171
179
|
end
|
172
180
|
end
|
data/lib/httpx/response.rb
CHANGED
@@ -52,9 +52,15 @@ module HTTPX
|
|
52
52
|
bodyless? || (@request.verb == :connect && @status == 200)
|
53
53
|
end
|
54
54
|
|
55
|
+
# :nocov:
|
55
56
|
def inspect
|
56
|
-
"#<Response:#{object_id}
|
57
|
+
"#<Response:#{object_id} "\
|
58
|
+
"HTTP/#{version} " \
|
59
|
+
"@status=#{@status} " \
|
60
|
+
"@headers=#{@headers} " \
|
61
|
+
"@body=#{@body}>"
|
57
62
|
end
|
63
|
+
# :nocov:
|
58
64
|
|
59
65
|
def raise_for_status
|
60
66
|
return if @status < 400
|
@@ -165,6 +171,14 @@ module HTTPX
|
|
165
171
|
to_s == other.to_s
|
166
172
|
end
|
167
173
|
|
174
|
+
# :nocov:
|
175
|
+
def inspect
|
176
|
+
"#<HTTPX::Response::Body:#{object_id} " \
|
177
|
+
"@state=#{@state} " \
|
178
|
+
"@length=#{@length}>"
|
179
|
+
end
|
180
|
+
# :nocov:
|
181
|
+
|
168
182
|
private
|
169
183
|
|
170
184
|
def rewind
|
data/lib/httpx/timeout.rb
CHANGED
@@ -10,7 +10,7 @@ module HTTPX
|
|
10
10
|
def self.new(opts = {})
|
11
11
|
return opts if opts.is_a?(Timeout)
|
12
12
|
|
13
|
-
super
|
13
|
+
super(**opts)
|
14
14
|
end
|
15
15
|
|
16
16
|
attr_reader :connect_timeout, :operation_timeout, :total_timeout
|
@@ -25,8 +25,10 @@ module HTTPX
|
|
25
25
|
|
26
26
|
return unless loop_timeout
|
27
27
|
|
28
|
+
# :nocov:
|
28
29
|
warn ":loop_timeout is deprecated, use :operation_timeout instead"
|
29
30
|
@operation_timeout = loop_timeout
|
31
|
+
# :nocov:
|
30
32
|
end
|
31
33
|
|
32
34
|
def ==(other)
|
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.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:
|
11
|
+
date: 2020-01-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: http-2-next
|
@@ -163,7 +163,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
163
163
|
- !ruby/object:Gem::Version
|
164
164
|
version: '0'
|
165
165
|
requirements: []
|
166
|
-
rubygems_version: 3.
|
166
|
+
rubygems_version: 3.1.2
|
167
167
|
signing_key:
|
168
168
|
specification_version: 4
|
169
169
|
summary: HTTPX, to the future, and beyond
|