httpx 0.22.4 → 0.23.0
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/doc/release_notes/0_22_5.md +6 -0
- data/doc/release_notes/0_23_0.md +42 -0
- data/lib/httpx/adapters/datadog.rb +12 -2
- data/lib/httpx/adapters/faraday.rb +1 -1
- data/lib/httpx/adapters/sentry.rb +15 -5
- data/lib/httpx/adapters/webmock.rb +2 -2
- data/lib/httpx/buffer.rb +4 -0
- data/lib/httpx/callbacks.rb +3 -3
- data/lib/httpx/chainable.rb +4 -4
- data/lib/httpx/connection/http1.rb +2 -2
- data/lib/httpx/connection/http2.rb +2 -3
- data/lib/httpx/connection.rb +31 -11
- data/lib/httpx/io/udp.rb +2 -0
- data/lib/httpx/io/unix.rb +1 -5
- data/lib/httpx/io.rb +0 -10
- data/lib/httpx/options.rb +16 -2
- data/lib/httpx/plugins/authentication/digest.rb +1 -1
- data/lib/httpx/plugins/aws_sdk_authentication.rb +1 -3
- data/lib/httpx/plugins/aws_sigv4.rb +1 -1
- data/lib/httpx/plugins/compression/brotli.rb +4 -4
- data/lib/httpx/plugins/compression/deflate.rb +12 -7
- data/lib/httpx/plugins/compression/gzip.rb +7 -5
- data/lib/httpx/plugins/compression.rb +9 -8
- data/lib/httpx/plugins/digest_authentication.rb +1 -4
- data/lib/httpx/plugins/follow_redirects.rb +1 -1
- data/lib/httpx/plugins/grpc/message.rb +3 -1
- data/lib/httpx/plugins/grpc.rb +3 -3
- data/lib/httpx/plugins/h2c.rb +5 -9
- data/lib/httpx/plugins/internal_telemetry.rb +16 -0
- data/lib/httpx/plugins/multipart.rb +14 -2
- data/lib/httpx/plugins/proxy/http.rb +4 -4
- data/lib/httpx/plugins/proxy.rb +65 -31
- data/lib/httpx/plugins/response_cache.rb +2 -2
- data/lib/httpx/plugins/retries.rb +49 -2
- data/lib/httpx/plugins/upgrade/h2.rb +3 -3
- data/lib/httpx/plugins/upgrade.rb +4 -7
- data/lib/httpx/plugins/webdav.rb +7 -7
- data/lib/httpx/pool.rb +7 -3
- data/lib/httpx/request.rb +23 -13
- data/lib/httpx/resolver/https.rb +37 -20
- data/lib/httpx/resolver/multi.rb +1 -6
- data/lib/httpx/resolver/native.rb +128 -36
- data/lib/httpx/resolver.rb +26 -14
- data/lib/httpx/response.rb +14 -16
- data/lib/httpx/session.rb +1 -0
- data/lib/httpx/transcoder/body.rb +0 -1
- data/lib/httpx/transcoder/chunker.rb +0 -1
- data/lib/httpx/transcoder/form.rb +0 -1
- data/lib/httpx/transcoder/json.rb +0 -1
- data/lib/httpx/transcoder/xml.rb +0 -1
- data/lib/httpx/transcoder.rb +0 -2
- data/lib/httpx/version.rb +1 -1
- data/lib/httpx.rb +0 -1
- data/sig/buffer.rbs +1 -0
- data/sig/chainable.rbs +3 -3
- data/sig/connection.rbs +17 -6
- data/sig/errors.rbs +9 -0
- data/sig/httpx.rbs +3 -3
- data/sig/io/ssl.rbs +17 -0
- data/sig/io/tcp.rbs +57 -0
- data/sig/io/udp.rbs +20 -0
- data/sig/io/unix.rbs +10 -0
- data/sig/options.rbs +5 -1
- data/sig/plugins/compression.rbs +6 -2
- data/sig/plugins/cookies/jar.rbs +2 -2
- data/sig/plugins/grpc.rbs +3 -3
- data/sig/plugins/h2c.rbs +1 -1
- data/sig/plugins/proxy.rbs +1 -5
- data/sig/plugins/response_cache.rbs +1 -1
- data/sig/plugins/retries.rbs +28 -8
- data/sig/plugins/upgrade.rbs +5 -3
- data/sig/request.rbs +6 -2
- data/sig/resolver/https.rbs +3 -1
- data/sig/resolver/native.rbs +7 -2
- data/sig/resolver/resolver.rbs +0 -2
- data/sig/resolver/system.rbs +2 -0
- data/sig/resolver.rbs +8 -4
- data/sig/response.rbs +6 -2
- data/sig/session.rbs +10 -10
- data/sig/transcoder/xml.rbs +1 -1
- data/sig/transcoder.rbs +4 -5
- metadata +11 -5
- data/lib/httpx/registry.rb +0 -85
- data/sig/registry.rbs +0 -13
data/lib/httpx/plugins/grpc.rb
CHANGED
@@ -233,7 +233,7 @@ module HTTPX
|
|
233
233
|
uri.path = rpc_method
|
234
234
|
|
235
235
|
headers = HEADERS.merge(
|
236
|
-
"grpc-accept-encoding" => ["identity", *@options.encodings.
|
236
|
+
"grpc-accept-encoding" => ["identity", *@options.encodings.keys]
|
237
237
|
)
|
238
238
|
unless deadline == Float::INFINITY
|
239
239
|
# convert to milliseconds
|
@@ -249,7 +249,7 @@ module HTTPX
|
|
249
249
|
|
250
250
|
if compression
|
251
251
|
headers["grpc-encoding"] = compression
|
252
|
-
deflater = @options.encodings.
|
252
|
+
deflater = @options.encodings[compression].deflater if @options.encodings.key?(compression)
|
253
253
|
end
|
254
254
|
|
255
255
|
headers.merge!(@options.call_credentials.call) if @options.call_credentials
|
@@ -264,7 +264,7 @@ module HTTPX
|
|
264
264
|
Message.encode(input, deflater: deflater)
|
265
265
|
end
|
266
266
|
|
267
|
-
build_request(
|
267
|
+
build_request("POST", uri, headers: headers, body: body)
|
268
268
|
end
|
269
269
|
end
|
270
270
|
end
|
data/lib/httpx/plugins/h2c.rb
CHANGED
@@ -9,16 +9,12 @@ module HTTPX
|
|
9
9
|
# https://gitlab.com/os85/httpx/wikis/Upgrade#h2c
|
10
10
|
#
|
11
11
|
module H2C
|
12
|
-
VALID_H2C_VERBS = %
|
12
|
+
VALID_H2C_VERBS = %w[GET OPTIONS HEAD].freeze
|
13
13
|
|
14
14
|
class << self
|
15
|
-
def load_dependencies(
|
15
|
+
def load_dependencies(klass)
|
16
16
|
require "base64"
|
17
|
-
end
|
18
|
-
|
19
|
-
def configure(klass)
|
20
17
|
klass.plugin(:upgrade)
|
21
|
-
klass.default_options.upgrade_handlers.register "h2c", self
|
22
18
|
end
|
23
19
|
|
24
20
|
def call(connection, request, response)
|
@@ -26,7 +22,7 @@ module HTTPX
|
|
26
22
|
end
|
27
23
|
|
28
24
|
def extra_options(options)
|
29
|
-
options.merge(max_concurrent_requests: 1)
|
25
|
+
options.merge(max_concurrent_requests: 1, upgrade_handlers: options.upgrade_handlers.merge("h2c" => self))
|
30
26
|
end
|
31
27
|
end
|
32
28
|
|
@@ -38,7 +34,7 @@ module HTTPX
|
|
38
34
|
|
39
35
|
connection = pool.find_connection(upgrade_request.uri, upgrade_request.options)
|
40
36
|
|
41
|
-
return super if connection && connection.upgrade_protocol ==
|
37
|
+
return super if connection && connection.upgrade_protocol == "h2c"
|
42
38
|
|
43
39
|
# build upgrade request
|
44
40
|
upgrade_request.headers.add("connection", "upgrade")
|
@@ -83,7 +79,7 @@ module HTTPX
|
|
83
79
|
set_parser_callbacks(@parser)
|
84
80
|
@inflight += 1
|
85
81
|
@parser.upgrade(request, response)
|
86
|
-
@upgrade_protocol =
|
82
|
+
@upgrade_protocol = "h2c"
|
87
83
|
|
88
84
|
if request.options.max_concurrent_requests != @options.max_concurrent_requests
|
89
85
|
@options = @options.merge(max_concurrent_requests: nil)
|
@@ -32,6 +32,15 @@ module HTTPX
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
+
module NativeResolverMethods
|
36
|
+
def transition(nextstate)
|
37
|
+
state = @state
|
38
|
+
val = super
|
39
|
+
meter_elapsed_time("Resolver::Native: #{state} -> #{nextstate}")
|
40
|
+
val
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
35
44
|
module InstanceMethods
|
36
45
|
def self.included(klass)
|
37
46
|
klass.prepend TrackTimeMethods
|
@@ -42,6 +51,13 @@ module HTTPX
|
|
42
51
|
meter_elapsed_time("Session: initializing...")
|
43
52
|
super
|
44
53
|
meter_elapsed_time("Session: initialized!!!")
|
54
|
+
resolver_type = @options.resolver_class
|
55
|
+
resolver_type = Resolver.resolver_for(resolver_type)
|
56
|
+
return unless resolver_type <= Resolver::Native
|
57
|
+
|
58
|
+
resolver_type.prepend TrackTimeMethods
|
59
|
+
resolver_type.prepend NativeResolverMethods
|
60
|
+
@options = @options.merge(resolver_class: resolver_type)
|
45
61
|
end
|
46
62
|
|
47
63
|
def close(*)
|
@@ -40,9 +40,21 @@ module HTTPX
|
|
40
40
|
require "httpx/plugins/multipart/part"
|
41
41
|
require "httpx/plugins/multipart/mime_type_detector"
|
42
42
|
end
|
43
|
+
end
|
44
|
+
|
45
|
+
module RequestBodyMethods
|
46
|
+
private
|
47
|
+
|
48
|
+
def initialize_body(options)
|
49
|
+
return FormTranscoder.encode(options.form) if options.form
|
50
|
+
|
51
|
+
super
|
52
|
+
end
|
53
|
+
end
|
43
54
|
|
44
|
-
|
45
|
-
|
55
|
+
module ResponseMethods
|
56
|
+
def form
|
57
|
+
decode(FormTranscoder)
|
46
58
|
end
|
47
59
|
end
|
48
60
|
|
@@ -61,7 +61,7 @@ module HTTPX
|
|
61
61
|
return unless @io.connected?
|
62
62
|
|
63
63
|
@parser || begin
|
64
|
-
@parser =
|
64
|
+
@parser = self.class.parser_type(@io.protocol).new(@write_buffer, @options.merge(max_concurrent_requests: 1))
|
65
65
|
parser = @parser
|
66
66
|
parser.extend(ProxyParser)
|
67
67
|
parser.on(:response, &method(:__http_on_connect))
|
@@ -141,9 +141,9 @@ module HTTPX
|
|
141
141
|
|
142
142
|
module ProxyParser
|
143
143
|
def join_headline(request)
|
144
|
-
return super if request.verb ==
|
144
|
+
return super if request.verb == "CONNECT"
|
145
145
|
|
146
|
-
"#{request.verb
|
146
|
+
"#{request.verb} #{request.uri} HTTP/#{@version.join(".")}"
|
147
147
|
end
|
148
148
|
|
149
149
|
def set_protocol_headers(request)
|
@@ -161,7 +161,7 @@ module HTTPX
|
|
161
161
|
|
162
162
|
class ConnectRequest < Request
|
163
163
|
def initialize(uri, _options)
|
164
|
-
super(
|
164
|
+
super("CONNECT", uri, {})
|
165
165
|
@headers.delete("accept")
|
166
166
|
end
|
167
167
|
|
data/lib/httpx/plugins/proxy.rb
CHANGED
@@ -18,6 +18,43 @@ module HTTPX
|
|
18
18
|
Error = HTTPProxyError
|
19
19
|
PROXY_ERRORS = [TimeoutError, IOError, SystemCallError, Error].freeze
|
20
20
|
|
21
|
+
class << self
|
22
|
+
def configure(klass)
|
23
|
+
klass.plugin(:"proxy/http")
|
24
|
+
klass.plugin(:"proxy/socks4")
|
25
|
+
klass.plugin(:"proxy/socks5")
|
26
|
+
end
|
27
|
+
|
28
|
+
if URI::Generic.methods.include?(:use_proxy?)
|
29
|
+
def use_proxy?(*args)
|
30
|
+
URI::Generic.use_proxy?(*args)
|
31
|
+
end
|
32
|
+
else
|
33
|
+
# https://github.com/ruby/uri/blob/ae07f956a4bea00b4f54a75bd40b8fa918103eed/lib/uri/generic.rb
|
34
|
+
def use_proxy?(hostname, addr, port, no_proxy)
|
35
|
+
hostname = hostname.downcase
|
36
|
+
dothostname = ".#{hostname}"
|
37
|
+
no_proxy.scan(/([^:,\s]+)(?::(\d+))?/) do |p_host, p_port|
|
38
|
+
if !p_port || port == p_port.to_i
|
39
|
+
if p_host.start_with?(".")
|
40
|
+
return false if hostname.end_with?(p_host.downcase)
|
41
|
+
else
|
42
|
+
return false if dothostname.end_with?(".#{p_host.downcase}")
|
43
|
+
end
|
44
|
+
if addr
|
45
|
+
begin
|
46
|
+
return false if IPAddr.new(p_host).include?(addr)
|
47
|
+
rescue IPAddr::InvalidAddressError
|
48
|
+
next
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
true
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
21
58
|
class Parameters
|
22
59
|
attr_reader :uri, :username, :password, :scheme
|
23
60
|
|
@@ -77,14 +114,6 @@ module HTTPX
|
|
77
114
|
end
|
78
115
|
end
|
79
116
|
|
80
|
-
class << self
|
81
|
-
def configure(klass)
|
82
|
-
klass.plugin(:"proxy/http")
|
83
|
-
klass.plugin(:"proxy/socks4")
|
84
|
-
klass.plugin(:"proxy/socks5")
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
117
|
module OptionsMethods
|
89
118
|
def option_proxy(value)
|
90
119
|
value.is_a?(Parameters) ? value : Hash[value]
|
@@ -94,34 +123,39 @@ module HTTPX
|
|
94
123
|
module InstanceMethods
|
95
124
|
private
|
96
125
|
|
97
|
-
def
|
98
|
-
|
99
|
-
uris = options.proxy ? Array(options.proxy[:uri]) : []
|
100
|
-
if uris.empty?
|
101
|
-
uri = URI(uri).find_proxy
|
102
|
-
uris << uri if uri
|
103
|
-
end
|
104
|
-
uris
|
105
|
-
end
|
106
|
-
return if @_proxy_uris.empty?
|
126
|
+
def find_connection(request, connections, options)
|
127
|
+
return super unless options.respond_to?(:proxy)
|
107
128
|
|
108
|
-
|
129
|
+
uri = URI(request.uri)
|
109
130
|
|
110
|
-
|
131
|
+
proxy_opts = if (next_proxy = uri.find_proxy)
|
132
|
+
{ uri: next_proxy }
|
133
|
+
else
|
134
|
+
proxy = options.proxy
|
111
135
|
|
112
|
-
|
113
|
-
proxy_opts = options.proxy.merge(proxy_opts) if options.proxy
|
114
|
-
proxy_opts
|
115
|
-
end
|
136
|
+
return super unless proxy
|
116
137
|
|
117
|
-
|
118
|
-
return super unless options.respond_to?(:proxy)
|
138
|
+
return super(request, connections, options.merge(proxy: nil)) unless proxy.key?(:uri)
|
119
139
|
|
120
|
-
|
121
|
-
|
122
|
-
|
140
|
+
@_proxy_uris ||= Array(proxy[:uri])
|
141
|
+
|
142
|
+
next_proxy = @_proxy_uris.first
|
143
|
+
raise Error, "Failed to connect to proxy" unless next_proxy
|
144
|
+
|
145
|
+
if proxy.key?(:no_proxy)
|
146
|
+
next_proxy = URI(next_proxy)
|
147
|
+
|
148
|
+
no_proxy = proxy[:no_proxy]
|
149
|
+
no_proxy = no_proxy.join(",") if no_proxy.is_a?(Array)
|
150
|
+
|
151
|
+
return super(request, connections, options.merge(proxy: nil)) unless Proxy.use_proxy?(uri.host, next_proxy.host,
|
152
|
+
next_proxy.port, no_proxy)
|
153
|
+
end
|
154
|
+
|
155
|
+
proxy.merge(uri: next_proxy)
|
156
|
+
end
|
123
157
|
|
124
|
-
proxy = Parameters.new(**
|
158
|
+
proxy = Parameters.new(**proxy_opts)
|
125
159
|
|
126
160
|
proxy_options = options.merge(proxy: proxy)
|
127
161
|
connection = pool.find_connection(uri, proxy_options) || build_connection(uri, proxy_options)
|
@@ -284,7 +318,7 @@ module HTTPX
|
|
284
318
|
register_plugin :proxy, Proxy
|
285
319
|
end
|
286
320
|
|
287
|
-
class ProxySSL <
|
321
|
+
class ProxySSL < SSL
|
288
322
|
def initialize(tcp, request_uri, options)
|
289
323
|
@io = tcp.to_io
|
290
324
|
super(request_uri, tcp.addresses, options)
|
@@ -8,7 +8,7 @@ module HTTPX
|
|
8
8
|
# https://gitlab.com/os85/httpx/wikis/Response-Cache
|
9
9
|
#
|
10
10
|
module ResponseCache
|
11
|
-
CACHEABLE_VERBS = %
|
11
|
+
CACHEABLE_VERBS = %w[GET HEAD].freeze
|
12
12
|
CACHEABLE_STATUS_CODES = [200, 203, 206, 300, 301, 410].freeze
|
13
13
|
private_constant :CACHEABLE_VERBS
|
14
14
|
private_constant :CACHEABLE_STATUS_CODES
|
@@ -96,7 +96,7 @@ module HTTPX
|
|
96
96
|
|
97
97
|
module RequestMethods
|
98
98
|
def response_cache_key
|
99
|
-
@response_cache_key ||= Digest::SHA1.hexdigest("httpx-response-cache-#{@verb}
|
99
|
+
@response_cache_key ||= Digest::SHA1.hexdigest("httpx-response-cache-#{@verb}-#{@uri}")
|
100
100
|
end
|
101
101
|
end
|
102
102
|
|
@@ -11,7 +11,7 @@ module HTTPX
|
|
11
11
|
MAX_RETRIES = 3
|
12
12
|
# TODO: pass max_retries in a configure/load block
|
13
13
|
|
14
|
-
IDEMPOTENT_METHODS = %
|
14
|
+
IDEMPOTENT_METHODS = %w[GET OPTIONS HEAD PUT DELETE].freeze
|
15
15
|
RETRYABLE_ERRORS = [
|
16
16
|
IOError,
|
17
17
|
EOFError,
|
@@ -96,7 +96,7 @@ module HTTPX
|
|
96
96
|
)
|
97
97
|
# rubocop:enable Style/MultilineTernaryOperator
|
98
98
|
)
|
99
|
-
|
99
|
+
__try_partial_retry(request, response)
|
100
100
|
log { "failed to get response, #{request.retries} tries to go..." }
|
101
101
|
request.retries -= 1
|
102
102
|
request.transition(:idle)
|
@@ -134,15 +134,62 @@ module HTTPX
|
|
134
134
|
def __retryable_error?(ex)
|
135
135
|
RETRYABLE_ERRORS.any? { |klass| ex.is_a?(klass) }
|
136
136
|
end
|
137
|
+
|
138
|
+
#
|
139
|
+
# Atttempt to set the request to perform a partial range request.
|
140
|
+
# This happens if the peer server accepts byte-range requests, and
|
141
|
+
# the last response contains some body payload.
|
142
|
+
#
|
143
|
+
def __try_partial_retry(request, response)
|
144
|
+
response = response.response if response.is_a?(ErrorResponse)
|
145
|
+
|
146
|
+
return unless response
|
147
|
+
|
148
|
+
unless response.headers.key?("accept-ranges") &&
|
149
|
+
response.headers["accept-ranges"] == "bytes" && # there's nothing else supported though...
|
150
|
+
(original_body = response.body)
|
151
|
+
response.close if response.respond_to?(:close)
|
152
|
+
return
|
153
|
+
end
|
154
|
+
|
155
|
+
request.partial_response = response
|
156
|
+
|
157
|
+
size = original_body.bytesize
|
158
|
+
|
159
|
+
request.headers["range"] = "bytes=#{size}-"
|
160
|
+
end
|
137
161
|
end
|
138
162
|
|
139
163
|
module RequestMethods
|
140
164
|
attr_accessor :retries
|
141
165
|
|
166
|
+
attr_writer :partial_response
|
167
|
+
|
142
168
|
def initialize(*args)
|
143
169
|
super
|
144
170
|
@retries = @options.max_retries
|
145
171
|
end
|
172
|
+
|
173
|
+
def response=(response)
|
174
|
+
if @partial_response
|
175
|
+
if response.is_a?(Response) && response.status == 206
|
176
|
+
response.from_partial_response(@partial_response)
|
177
|
+
else
|
178
|
+
@partial_response.close
|
179
|
+
end
|
180
|
+
@partial_response = nil
|
181
|
+
end
|
182
|
+
|
183
|
+
super
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
module ResponseMethods
|
188
|
+
def from_partial_response(response)
|
189
|
+
@status = response.status
|
190
|
+
@headers = response.headers
|
191
|
+
@body = response.body
|
192
|
+
end
|
146
193
|
end
|
147
194
|
end
|
148
195
|
register_plugin :retries, Retries
|
@@ -10,8 +10,8 @@ module HTTPX
|
|
10
10
|
#
|
11
11
|
module H2
|
12
12
|
class << self
|
13
|
-
def
|
14
|
-
|
13
|
+
def extra_options(options)
|
14
|
+
options.merge(upgrade_handlers: options.upgrade_handlers.merge("h2" => self))
|
15
15
|
end
|
16
16
|
|
17
17
|
def call(connection, _request, _response)
|
@@ -32,7 +32,7 @@ module HTTPX
|
|
32
32
|
|
33
33
|
@parser = Connection::HTTP2.new(@write_buffer, @options)
|
34
34
|
set_parser_callbacks(@parser)
|
35
|
-
@upgrade_protocol =
|
35
|
+
@upgrade_protocol = "h2"
|
36
36
|
|
37
37
|
# what's happening here:
|
38
38
|
# a deviation from the state machine is done to perform the actions when a
|
@@ -15,16 +15,13 @@ module HTTPX
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def extra_options(options)
|
18
|
-
upgrade_handlers
|
19
|
-
extend Registry
|
20
|
-
end
|
21
|
-
options.merge(upgrade_handlers: upgrade_handlers)
|
18
|
+
options.merge(upgrade_handlers: {})
|
22
19
|
end
|
23
20
|
end
|
24
21
|
|
25
22
|
module OptionsMethods
|
26
23
|
def option_upgrade_handlers(value)
|
27
|
-
raise TypeError, ":upgrade_handlers must be a
|
24
|
+
raise TypeError, ":upgrade_handlers must be a Hash" unless value.is_a?(Hash)
|
28
25
|
|
29
26
|
value
|
30
27
|
end
|
@@ -41,9 +38,9 @@ module HTTPX
|
|
41
38
|
|
42
39
|
upgrade_protocol = response.headers["upgrade"].split(/ *, */).first
|
43
40
|
|
44
|
-
return response unless upgrade_protocol && options.upgrade_handlers.
|
41
|
+
return response unless upgrade_protocol && options.upgrade_handlers.key?(upgrade_protocol)
|
45
42
|
|
46
|
-
protocol_handler = options.upgrade_handlers
|
43
|
+
protocol_handler = options.upgrade_handlers[upgrade_protocol]
|
47
44
|
|
48
45
|
return response unless protocol_handler
|
49
46
|
|
data/lib/httpx/plugins/webdav.rb
CHANGED
@@ -10,11 +10,11 @@ module HTTPX
|
|
10
10
|
module WebDav
|
11
11
|
module InstanceMethods
|
12
12
|
def copy(src, dest)
|
13
|
-
request(
|
13
|
+
request("COPY", src, headers: { "destination" => @options.origin.merge(dest) })
|
14
14
|
end
|
15
15
|
|
16
16
|
def move(src, dest)
|
17
|
-
request(
|
17
|
+
request("MOVE", src, headers: { "destination" => @options.origin.merge(dest) })
|
18
18
|
end
|
19
19
|
|
20
20
|
def lock(path, timeout: nil, &blk)
|
@@ -30,7 +30,7 @@ module HTTPX
|
|
30
30
|
"<D:locktype><D:write/></D:locktype>" \
|
31
31
|
"<D:owner>null</D:owner>" \
|
32
32
|
"</D:lockinfo>"
|
33
|
-
response = request(
|
33
|
+
response = request("LOCK", path, headers: headers, xml: xml)
|
34
34
|
|
35
35
|
return response unless response.is_a?(Response)
|
36
36
|
|
@@ -46,11 +46,11 @@ module HTTPX
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def unlock(path, lock_token)
|
49
|
-
request(
|
49
|
+
request("UNLOCK", path, headers: { "lock-token" => lock_token })
|
50
50
|
end
|
51
51
|
|
52
52
|
def mkcol(dir)
|
53
|
-
request(
|
53
|
+
request("MKCOL", dir)
|
54
54
|
end
|
55
55
|
|
56
56
|
def propfind(path, xml = nil)
|
@@ -64,13 +64,13 @@ module HTTPX
|
|
64
64
|
xml
|
65
65
|
end
|
66
66
|
|
67
|
-
request(
|
67
|
+
request("PROPFIND", path, headers: { "depth" => "1" }, xml: body)
|
68
68
|
end
|
69
69
|
|
70
70
|
def proppatch(path, xml)
|
71
71
|
body = "<?xml version=\"1.0\"?>" \
|
72
72
|
"<D:propertyupdate xmlns:D=\"DAV:\" xmlns:Z=\"http://ns.example.com/standards/z39.50/\">#{xml}</D:propertyupdate>"
|
73
|
-
request(
|
73
|
+
request("PROPPATCH", path, xml: body)
|
74
74
|
end
|
75
75
|
# %i[ orderpatch acl report search]
|
76
76
|
end
|
data/lib/httpx/pool.rb
CHANGED
@@ -141,8 +141,9 @@ module HTTPX
|
|
141
141
|
connection.once(:connect_error) do |err|
|
142
142
|
if new_connection.connecting?
|
143
143
|
new_connection.merge(connection)
|
144
|
+
connection.force_reset
|
144
145
|
else
|
145
|
-
connection.handle_error
|
146
|
+
connection.__send__(:handle_error, err)
|
146
147
|
end
|
147
148
|
end
|
148
149
|
|
@@ -156,8 +157,9 @@ module HTTPX
|
|
156
157
|
if connection.connecting?
|
157
158
|
# main connection has the requests
|
158
159
|
connection.merge(new_connection)
|
160
|
+
new_connection.force_reset
|
159
161
|
else
|
160
|
-
new_connection.handle_error
|
162
|
+
new_connection.__send__(:handle_error, err)
|
161
163
|
end
|
162
164
|
end
|
163
165
|
|
@@ -183,6 +185,8 @@ module HTTPX
|
|
183
185
|
end
|
184
186
|
|
185
187
|
def on_resolver_error(connection, error)
|
188
|
+
return connection.emit(:connect_error, error) if connection.connecting? && connection.callbacks_for?(:connect_error)
|
189
|
+
|
186
190
|
connection.emit(:error, error)
|
187
191
|
end
|
188
192
|
|
@@ -240,7 +244,7 @@ module HTTPX
|
|
240
244
|
def find_resolver_for(connection)
|
241
245
|
connection_options = connection.options
|
242
246
|
resolver_type = connection_options.resolver_class
|
243
|
-
resolver_type = Resolver.
|
247
|
+
resolver_type = Resolver.resolver_for(resolver_type)
|
244
248
|
|
245
249
|
@resolvers[resolver_type] ||= begin
|
246
250
|
resolver_manager = if resolver_type.multi?
|
data/lib/httpx/request.rb
CHANGED
@@ -19,7 +19,11 @@ module HTTPX
|
|
19
19
|
def_delegator :@body, :empty?
|
20
20
|
|
21
21
|
def initialize(verb, uri, options = {})
|
22
|
-
|
22
|
+
if verb.is_a?(Symbol)
|
23
|
+
warn "DEPRECATION WARNING: Using symbols for `verb` is deprecated, and will not be supported in httpx 1.0. " \
|
24
|
+
"Use \"#{verb.to_s.upcase}\" instead."
|
25
|
+
end
|
26
|
+
@verb = verb.to_s.upcase
|
23
27
|
@options = Options.new(options)
|
24
28
|
@uri = Utils.to_uri(uri)
|
25
29
|
if @uri.relative?
|
@@ -116,7 +120,7 @@ module HTTPX
|
|
116
120
|
|
117
121
|
query = []
|
118
122
|
if (q = @options.params)
|
119
|
-
query << Transcoder.
|
123
|
+
query << Transcoder::Form.encode(q)
|
120
124
|
end
|
121
125
|
query << @uri.query if @uri.query
|
122
126
|
@query = query.join("&")
|
@@ -138,7 +142,7 @@ module HTTPX
|
|
138
142
|
# :nocov:
|
139
143
|
def inspect
|
140
144
|
"#<HTTPX::Request:#{object_id} " \
|
141
|
-
"#{@verb
|
145
|
+
"#{@verb} " \
|
142
146
|
"#{uri} " \
|
143
147
|
"@headers=#{@headers} " \
|
144
148
|
"@body=#{@body}>"
|
@@ -156,15 +160,7 @@ module HTTPX
|
|
156
160
|
|
157
161
|
def initialize(headers, options)
|
158
162
|
@headers = headers
|
159
|
-
@body =
|
160
|
-
Transcoder.registry("body").encode(options.body)
|
161
|
-
elsif options.form
|
162
|
-
Transcoder.registry("form").encode(options.form)
|
163
|
-
elsif options.json
|
164
|
-
Transcoder.registry("json").encode(options.json)
|
165
|
-
elsif options.xml
|
166
|
-
Transcoder.registry("xml").encode(options.xml)
|
167
|
-
end
|
163
|
+
@body = initialize_body(options)
|
168
164
|
return if @body.nil?
|
169
165
|
|
170
166
|
@headers["content-type"] ||= @body.content_type
|
@@ -207,7 +203,7 @@ module HTTPX
|
|
207
203
|
|
208
204
|
def stream(body)
|
209
205
|
encoded = body
|
210
|
-
encoded = Transcoder.
|
206
|
+
encoded = Transcoder::Chunker.encode(body.enum_for(:each)) if chunked?
|
211
207
|
encoded
|
212
208
|
end
|
213
209
|
|
@@ -231,6 +227,20 @@ module HTTPX
|
|
231
227
|
"#{unbounded_body? ? "stream" : "@bytesize=#{bytesize}"}>"
|
232
228
|
end
|
233
229
|
# :nocov:
|
230
|
+
|
231
|
+
private
|
232
|
+
|
233
|
+
def initialize_body(options)
|
234
|
+
if options.body
|
235
|
+
Transcoder::Body.encode(options.body)
|
236
|
+
elsif options.form
|
237
|
+
Transcoder::Form.encode(options.form)
|
238
|
+
elsif options.json
|
239
|
+
Transcoder::JSON.encode(options.json)
|
240
|
+
elsif options.xml
|
241
|
+
Transcoder::Xml.encode(options.xml)
|
242
|
+
end
|
243
|
+
end
|
234
244
|
end
|
235
245
|
|
236
246
|
def transition(nextstate)
|