httpx 0.6.7 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +7 -5
- data/doc/release_notes/0_0_1.md +7 -0
- data/doc/release_notes/0_0_2.md +9 -0
- data/doc/release_notes/0_0_3.md +9 -0
- data/doc/release_notes/0_0_4.md +7 -0
- data/doc/release_notes/0_0_5.md +5 -0
- data/doc/release_notes/0_1_0.md +9 -0
- data/doc/release_notes/0_2_0.md +5 -0
- data/doc/release_notes/0_2_1.md +16 -0
- data/doc/release_notes/0_3_0.md +12 -0
- data/doc/release_notes/0_3_1.md +6 -0
- data/doc/release_notes/0_4_0.md +51 -0
- data/doc/release_notes/0_4_1.md +3 -0
- data/doc/release_notes/0_5_0.md +15 -0
- data/doc/release_notes/0_5_1.md +14 -0
- data/doc/release_notes/0_6_0.md +5 -0
- data/doc/release_notes/0_6_1.md +6 -0
- data/doc/release_notes/0_6_2.md +6 -0
- data/doc/release_notes/0_6_3.md +13 -0
- data/doc/release_notes/0_6_4.md +21 -0
- data/doc/release_notes/0_6_5.md +22 -0
- data/doc/release_notes/0_6_6.md +19 -0
- data/doc/release_notes/0_6_7.md +5 -0
- data/doc/release_notes/0_7_0.md +46 -0
- data/doc/release_notes/0_8_0.md +27 -0
- data/doc/release_notes/0_8_1.md +8 -0
- data/doc/release_notes/0_8_2.md +7 -0
- data/doc/release_notes/0_9_0.md +38 -0
- data/lib/httpx/adapters/faraday.rb +2 -2
- data/lib/httpx/altsvc.rb +18 -2
- data/lib/httpx/chainable.rb +27 -9
- data/lib/httpx/connection.rb +215 -65
- data/lib/httpx/connection/http1.rb +54 -18
- data/lib/httpx/connection/http2.rb +100 -37
- data/lib/httpx/extensions.rb +2 -2
- data/lib/httpx/headers.rb +2 -2
- data/lib/httpx/io/ssl.rb +11 -3
- data/lib/httpx/io/tcp.rb +12 -2
- data/lib/httpx/loggable.rb +6 -6
- data/lib/httpx/options.rb +43 -28
- data/lib/httpx/plugins/authentication.rb +1 -1
- data/lib/httpx/plugins/compression.rb +28 -8
- data/lib/httpx/plugins/compression/gzip.rb +22 -12
- data/lib/httpx/plugins/cookies.rb +12 -8
- data/lib/httpx/plugins/digest_authentication.rb +2 -0
- data/lib/httpx/plugins/expect.rb +79 -0
- data/lib/httpx/plugins/follow_redirects.rb +1 -2
- data/lib/httpx/plugins/h2c.rb +0 -1
- data/lib/httpx/plugins/proxy.rb +23 -20
- data/lib/httpx/plugins/proxy/http.rb +9 -6
- data/lib/httpx/plugins/proxy/socks4.rb +1 -1
- data/lib/httpx/plugins/proxy/socks5.rb +5 -1
- data/lib/httpx/plugins/proxy/ssh.rb +0 -4
- data/lib/httpx/plugins/push_promise.rb +2 -2
- data/lib/httpx/plugins/retries.rb +32 -29
- data/lib/httpx/pool.rb +15 -10
- data/lib/httpx/registry.rb +2 -1
- data/lib/httpx/request.rb +8 -6
- data/lib/httpx/resolver.rb +7 -8
- data/lib/httpx/resolver/https.rb +15 -3
- data/lib/httpx/resolver/native.rb +22 -32
- data/lib/httpx/resolver/options.rb +2 -2
- data/lib/httpx/resolver/resolver_mixin.rb +1 -1
- data/lib/httpx/response.rb +17 -3
- data/lib/httpx/selector.rb +96 -95
- data/lib/httpx/session.rb +33 -34
- data/lib/httpx/timeout.rb +7 -1
- data/lib/httpx/version.rb +1 -1
- metadata +77 -20
data/lib/httpx/session.rb
CHANGED
@@ -5,7 +5,9 @@ module HTTPX
|
|
5
5
|
include Loggable
|
6
6
|
include Chainable
|
7
7
|
|
8
|
-
|
8
|
+
EMPTY_HASH = {}.freeze
|
9
|
+
|
10
|
+
def initialize(options = EMPTY_HASH, &blk)
|
9
11
|
@options = self.class.default_options.merge(options)
|
10
12
|
@responses = {}
|
11
13
|
@persistent = @options.persistent
|
@@ -29,13 +31,21 @@ module HTTPX
|
|
29
31
|
end
|
30
32
|
|
31
33
|
def request(*args, **options)
|
32
|
-
requests = build_requests(*args, options)
|
34
|
+
requests = args.first.is_a?(Request) ? args : build_requests(*args, options)
|
33
35
|
responses = send_requests(*requests, options)
|
34
36
|
return responses.first if responses.size == 1
|
35
37
|
|
36
38
|
responses
|
37
39
|
end
|
38
40
|
|
41
|
+
def build_request(verb, uri, options = EMPTY_HASH)
|
42
|
+
rklass = @options.request_class
|
43
|
+
request = rklass.new(verb, uri, @options.merge(options).merge(persistent: @persistent))
|
44
|
+
request.on(:response, &method(:on_response).curry[request])
|
45
|
+
request.on(:promise, &method(:on_promise))
|
46
|
+
request
|
47
|
+
end
|
48
|
+
|
39
49
|
private
|
40
50
|
|
41
51
|
def pool
|
@@ -47,7 +57,7 @@ module HTTPX
|
|
47
57
|
end
|
48
58
|
|
49
59
|
def on_promise(_, stream)
|
50
|
-
log(level: 2
|
60
|
+
log(level: 2) { "#{stream.id}: refusing stream!" }
|
51
61
|
stream.refuse
|
52
62
|
end
|
53
63
|
|
@@ -60,22 +70,33 @@ module HTTPX
|
|
60
70
|
connection = pool.find_connection(uri, options) || build_connection(uri, options)
|
61
71
|
unless connections.nil? || connections.include?(connection)
|
62
72
|
connections << connection
|
63
|
-
set_connection_callbacks(connection, options)
|
73
|
+
set_connection_callbacks(connection, connections, options)
|
64
74
|
end
|
65
75
|
connection
|
66
76
|
end
|
67
77
|
|
68
|
-
def set_connection_callbacks(connection, options)
|
78
|
+
def set_connection_callbacks(connection, connections, options)
|
69
79
|
connection.on(:uncoalesce) do |uncoalesced_uri|
|
70
80
|
other_connection = build_connection(uncoalesced_uri, options)
|
81
|
+
connections << other_connection
|
71
82
|
connection.unmerge(other_connection)
|
72
83
|
end
|
73
84
|
connection.on(:altsvc) do |alt_origin, origin, alt_params|
|
74
|
-
build_altsvc_connection(connection, alt_origin, origin, alt_params, options)
|
85
|
+
other_connection = build_altsvc_connection(connection, connections, alt_origin, origin, alt_params, options)
|
86
|
+
connections << other_connection if other_connection
|
87
|
+
end
|
88
|
+
connection.on(:exhausted) do
|
89
|
+
other_connection = connection.create_idle
|
90
|
+
other_connection.merge(connection)
|
91
|
+
catch(:coalesced) do
|
92
|
+
pool.init_connection(other_connection, options)
|
93
|
+
end
|
94
|
+
set_connection_callbacks(other_connection, connections, options)
|
95
|
+
connections << other_connection
|
75
96
|
end
|
76
97
|
end
|
77
98
|
|
78
|
-
def build_altsvc_connection(existing_connection, alt_origin, origin, alt_params, options)
|
99
|
+
def build_altsvc_connection(existing_connection, connections, alt_origin, origin, alt_params, options)
|
79
100
|
altsvc = AltSvc.cached_altsvc_set(origin, alt_params.merge("origin" => alt_origin))
|
80
101
|
|
81
102
|
# altsvc already exists, somehow it wasn't advertised, probably noop
|
@@ -85,7 +106,7 @@ module HTTPX
|
|
85
106
|
# advertised altsvc is the same origin being used, ignore
|
86
107
|
return if connection == existing_connection
|
87
108
|
|
88
|
-
set_connection_callbacks(connection, options)
|
109
|
+
set_connection_callbacks(connection, connections, options)
|
89
110
|
|
90
111
|
log(level: 1) { "#{origin} alt-svc: #{alt_origin}" }
|
91
112
|
|
@@ -99,8 +120,10 @@ module HTTPX
|
|
99
120
|
end
|
100
121
|
|
101
122
|
connection.merge(existing_connection)
|
123
|
+
connection
|
102
124
|
rescue UnsupportedSchemeError
|
103
125
|
altsvc["noop"] = true
|
126
|
+
nil
|
104
127
|
end
|
105
128
|
|
106
129
|
def build_requests(*args, options)
|
@@ -109,8 +132,8 @@ module HTTPX
|
|
109
132
|
requests = case args.size
|
110
133
|
when 1
|
111
134
|
reqs = args.first
|
112
|
-
reqs.map do |verb, uri|
|
113
|
-
build_request(verb, uri, request_options)
|
135
|
+
reqs.map do |verb, uri, opts = EMPTY_HASH|
|
136
|
+
build_request(verb, uri, request_options.merge(opts))
|
114
137
|
end
|
115
138
|
when 2, 3
|
116
139
|
verb, uris = args
|
@@ -155,7 +178,6 @@ module HTTPX
|
|
155
178
|
error = catch(:resolve_error) do
|
156
179
|
connection = find_connection(request, connections, request_options)
|
157
180
|
connection.send(request)
|
158
|
-
set_request_timeout(connection, request, request_options)
|
159
181
|
end
|
160
182
|
next unless error.is_a?(ResolveError)
|
161
183
|
|
@@ -183,29 +205,6 @@ module HTTPX
|
|
183
205
|
end
|
184
206
|
end
|
185
207
|
|
186
|
-
def build_request(verb, uri, options)
|
187
|
-
rklass = @options.request_class
|
188
|
-
request = rklass.new(verb, uri, @options.merge(options))
|
189
|
-
request.on(:response, &method(:on_response).curry[request])
|
190
|
-
request.on(:promise, &method(:on_promise))
|
191
|
-
request
|
192
|
-
end
|
193
|
-
|
194
|
-
def set_request_timeout(connection, request, options)
|
195
|
-
total = options.timeout.total_timeout
|
196
|
-
return unless total
|
197
|
-
|
198
|
-
timer = pool.after(total) do
|
199
|
-
unless @responses[request]
|
200
|
-
error = TotalTimeoutError.new(total, "Timed out after #{total} seconds")
|
201
|
-
response = ErrorResponse.new(request, error, options)
|
202
|
-
request.emit(:response, response)
|
203
|
-
connection.reset
|
204
|
-
end
|
205
|
-
end
|
206
|
-
request.timer = timer
|
207
|
-
end
|
208
|
-
|
209
208
|
@default_options = Options.new
|
210
209
|
@default_options.freeze
|
211
210
|
@plugins = []
|
data/lib/httpx/timeout.rb
CHANGED
@@ -6,6 +6,7 @@ module HTTPX
|
|
6
6
|
class Timeout
|
7
7
|
CONNECT_TIMEOUT = 60
|
8
8
|
OPERATION_TIMEOUT = 60
|
9
|
+
KEEP_ALIVE_TIMEOUT = 20
|
9
10
|
|
10
11
|
def self.new(opts = {})
|
11
12
|
return opts if opts.is_a?(Timeout)
|
@@ -13,14 +14,16 @@ module HTTPX
|
|
13
14
|
super(**opts)
|
14
15
|
end
|
15
16
|
|
16
|
-
attr_reader :connect_timeout, :operation_timeout, :total_timeout
|
17
|
+
attr_reader :connect_timeout, :operation_timeout, :keep_alive_timeout, :total_timeout
|
17
18
|
|
18
19
|
def initialize(connect_timeout: CONNECT_TIMEOUT,
|
19
20
|
operation_timeout: OPERATION_TIMEOUT,
|
21
|
+
keep_alive_timeout: KEEP_ALIVE_TIMEOUT,
|
20
22
|
total_timeout: nil,
|
21
23
|
loop_timeout: nil)
|
22
24
|
@connect_timeout = connect_timeout
|
23
25
|
@operation_timeout = operation_timeout
|
26
|
+
@keep_alive_timeout = keep_alive_timeout
|
24
27
|
@total_timeout = total_timeout
|
25
28
|
|
26
29
|
return unless loop_timeout
|
@@ -35,6 +38,7 @@ module HTTPX
|
|
35
38
|
if other.is_a?(Timeout)
|
36
39
|
@connect_timeout == other.instance_variable_get(:@connect_timeout) &&
|
37
40
|
@operation_timeout == other.instance_variable_get(:@operation_timeout) &&
|
41
|
+
@keep_alive_timeout == other.instance_variable_get(:@keep_alive_timeout) &&
|
38
42
|
@total_timeout == other.instance_variable_get(:@total_timeout)
|
39
43
|
else
|
40
44
|
super
|
@@ -49,9 +53,11 @@ module HTTPX
|
|
49
53
|
when Timeout
|
50
54
|
connect_timeout = other.instance_variable_get(:@connect_timeout) || @connect_timeout
|
51
55
|
operation_timeout = other.instance_variable_get(:@operation_timeout) || @operation_timeout
|
56
|
+
keep_alive_timeout = other.instance_variable_get(:@keep_alive_timeout) || @keep_alive_timeout
|
52
57
|
total_timeout = other.instance_variable_get(:@total_timeout) || @total_timeout
|
53
58
|
Timeout.new(connect_timeout: connect_timeout,
|
54
59
|
operation_timeout: operation_timeout,
|
60
|
+
keep_alive_timeout: keep_alive_timeout,
|
55
61
|
total_timeout: total_timeout)
|
56
62
|
else
|
57
63
|
raise ArgumentError, "can't merge with #{other.class}"
|
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.
|
4
|
+
version: 0.9.0
|
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: 2020-
|
11
|
+
date: 2020-10-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: http-2-next
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: http-cookie
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: http-form_data
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -58,29 +72,71 @@ dependencies:
|
|
58
72
|
- - "<"
|
59
73
|
- !ruby/object:Gem::Version
|
60
74
|
version: '3'
|
61
|
-
- !ruby/object:Gem::Dependency
|
62
|
-
name: http-cookie
|
63
|
-
requirement: !ruby/object:Gem::Requirement
|
64
|
-
requirements:
|
65
|
-
- - "~>"
|
66
|
-
- !ruby/object:Gem::Version
|
67
|
-
version: '1.0'
|
68
|
-
type: :development
|
69
|
-
prerelease: false
|
70
|
-
version_requirements: !ruby/object:Gem::Requirement
|
71
|
-
requirements:
|
72
|
-
- - "~>"
|
73
|
-
- !ruby/object:Gem::Version
|
74
|
-
version: '1.0'
|
75
75
|
description: A client library for making HTTP requests from Ruby.
|
76
76
|
email:
|
77
77
|
- cardoso_tiago@hotmail.com
|
78
78
|
executables: []
|
79
79
|
extensions: []
|
80
|
-
extra_rdoc_files:
|
80
|
+
extra_rdoc_files:
|
81
|
+
- LICENSE.txt
|
82
|
+
- README.md
|
83
|
+
- doc/release_notes/0_0_1.md
|
84
|
+
- doc/release_notes/0_1_0.md
|
85
|
+
- doc/release_notes/0_0_5.md
|
86
|
+
- doc/release_notes/0_0_4.md
|
87
|
+
- doc/release_notes/0_6_5.md
|
88
|
+
- doc/release_notes/0_6_1.md
|
89
|
+
- doc/release_notes/0_7_0.md
|
90
|
+
- doc/release_notes/0_6_0.md
|
91
|
+
- doc/release_notes/0_8_2.md
|
92
|
+
- doc/release_notes/0_6_4.md
|
93
|
+
- doc/release_notes/0_9_0.md
|
94
|
+
- doc/release_notes/0_6_3.md
|
95
|
+
- doc/release_notes/0_8_1.md
|
96
|
+
- doc/release_notes/0_5_0.md
|
97
|
+
- doc/release_notes/0_6_7.md
|
98
|
+
- doc/release_notes/0_4_1.md
|
99
|
+
- doc/release_notes/0_5_1.md
|
100
|
+
- doc/release_notes/0_6_6.md
|
101
|
+
- doc/release_notes/0_4_0.md
|
102
|
+
- doc/release_notes/0_6_2.md
|
103
|
+
- doc/release_notes/0_8_0.md
|
104
|
+
- doc/release_notes/0_3_0.md
|
105
|
+
- doc/release_notes/0_2_1.md
|
106
|
+
- doc/release_notes/0_0_3.md
|
107
|
+
- doc/release_notes/0_0_2.md
|
108
|
+
- doc/release_notes/0_3_1.md
|
109
|
+
- doc/release_notes/0_2_0.md
|
81
110
|
files:
|
82
111
|
- LICENSE.txt
|
83
112
|
- README.md
|
113
|
+
- doc/release_notes/0_0_1.md
|
114
|
+
- doc/release_notes/0_0_2.md
|
115
|
+
- doc/release_notes/0_0_3.md
|
116
|
+
- doc/release_notes/0_0_4.md
|
117
|
+
- doc/release_notes/0_0_5.md
|
118
|
+
- doc/release_notes/0_1_0.md
|
119
|
+
- doc/release_notes/0_2_0.md
|
120
|
+
- doc/release_notes/0_2_1.md
|
121
|
+
- doc/release_notes/0_3_0.md
|
122
|
+
- doc/release_notes/0_3_1.md
|
123
|
+
- doc/release_notes/0_4_0.md
|
124
|
+
- doc/release_notes/0_4_1.md
|
125
|
+
- doc/release_notes/0_5_0.md
|
126
|
+
- doc/release_notes/0_5_1.md
|
127
|
+
- doc/release_notes/0_6_0.md
|
128
|
+
- doc/release_notes/0_6_1.md
|
129
|
+
- doc/release_notes/0_6_2.md
|
130
|
+
- doc/release_notes/0_6_3.md
|
131
|
+
- doc/release_notes/0_6_4.md
|
132
|
+
- doc/release_notes/0_6_5.md
|
133
|
+
- doc/release_notes/0_6_6.md
|
134
|
+
- doc/release_notes/0_6_7.md
|
135
|
+
- doc/release_notes/0_7_0.md
|
136
|
+
- doc/release_notes/0_8_0.md
|
137
|
+
- doc/release_notes/0_8_1.md
|
138
|
+
- doc/release_notes/0_8_2.md
|
139
|
+
- doc/release_notes/0_9_0.md
|
84
140
|
- lib/httpx.rb
|
85
141
|
- lib/httpx/adapters/faraday.rb
|
86
142
|
- lib/httpx/altsvc.rb
|
@@ -109,6 +165,7 @@ files:
|
|
109
165
|
- lib/httpx/plugins/compression/gzip.rb
|
110
166
|
- lib/httpx/plugins/cookies.rb
|
111
167
|
- lib/httpx/plugins/digest_authentication.rb
|
168
|
+
- lib/httpx/plugins/expect.rb
|
112
169
|
- lib/httpx/plugins/follow_redirects.rb
|
113
170
|
- lib/httpx/plugins/h2c.rb
|
114
171
|
- lib/httpx/plugins/multipart.rb
|
@@ -148,7 +205,7 @@ metadata:
|
|
148
205
|
changelog_uri: https://honeyryderchuck.gitlab.io/httpx/#release-notes
|
149
206
|
documentation_uri: https://honeyryderchuck.gitlab.io/httpx/rdoc/
|
150
207
|
source_code_uri: https://gitlab.com/honeyryderchuck/httpx
|
151
|
-
post_install_message:
|
208
|
+
post_install_message:
|
152
209
|
rdoc_options: []
|
153
210
|
require_paths:
|
154
211
|
- lib
|
@@ -164,7 +221,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
164
221
|
version: '0'
|
165
222
|
requirements: []
|
166
223
|
rubygems_version: 3.1.2
|
167
|
-
signing_key:
|
224
|
+
signing_key:
|
168
225
|
specification_version: 4
|
169
226
|
summary: HTTPX, to the future, and beyond
|
170
227
|
test_files: []
|