httpx 0.15.4 → 0.16.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/doc/release_notes/0_16_0.md +93 -0
- data/lib/httpx.rb +6 -3
- data/lib/httpx/adapters/faraday.rb +3 -11
- data/lib/httpx/buffer.rb +1 -1
- data/lib/httpx/callbacks.rb +1 -1
- data/lib/httpx/chainable.rb +15 -8
- data/lib/httpx/connection.rb +2 -2
- data/lib/httpx/connection/http1.rb +3 -1
- data/lib/httpx/connection/http2.rb +1 -11
- data/lib/httpx/errors.rb +11 -11
- data/lib/httpx/io/ssl.rb +2 -2
- data/lib/httpx/io/tls.rb +1 -1
- data/lib/httpx/options.rb +78 -73
- data/lib/httpx/parser/http1.rb +1 -1
- data/lib/httpx/plugins/aws_sigv4.rb +10 -9
- data/lib/httpx/plugins/compression.rb +12 -11
- data/lib/httpx/plugins/cookies.rb +20 -7
- data/lib/httpx/plugins/cookies/cookie.rb +4 -2
- data/lib/httpx/plugins/cookies/jar.rb +20 -1
- data/lib/httpx/plugins/digest_authentication.rb +15 -11
- data/lib/httpx/plugins/expect.rb +19 -15
- data/lib/httpx/plugins/follow_redirects.rb +9 -9
- data/lib/httpx/plugins/grpc.rb +72 -46
- data/lib/httpx/plugins/grpc/call.rb +4 -1
- data/lib/httpx/plugins/ntlm_authentication.rb +8 -6
- data/lib/httpx/plugins/proxy.rb +4 -6
- data/lib/httpx/plugins/proxy/socks4.rb +2 -1
- data/lib/httpx/plugins/proxy/socks5.rb +2 -1
- data/lib/httpx/plugins/proxy/ssh.rb +9 -9
- data/lib/httpx/plugins/retries.rb +25 -21
- data/lib/httpx/plugins/upgrade.rb +7 -6
- data/lib/httpx/registry.rb +1 -1
- data/lib/httpx/request.rb +4 -12
- data/lib/httpx/resolver/https.rb +0 -2
- data/lib/httpx/response.rb +45 -18
- data/lib/httpx/selector.rb +2 -5
- data/lib/httpx/session.rb +19 -8
- data/lib/httpx/session2.rb +21 -0
- data/lib/httpx/transcoder/body.rb +1 -1
- data/lib/httpx/transcoder/chunker.rb +2 -1
- data/lib/httpx/version.rb +1 -1
- data/sig/buffer.rbs +2 -0
- data/sig/chainable.rbs +24 -28
- data/sig/connection.rbs +20 -8
- data/sig/connection/http1.rbs +3 -3
- data/sig/connection/http2.rbs +1 -1
- data/sig/errors.rbs +35 -1
- data/sig/headers.rbs +5 -5
- data/sig/httpx.rbs +4 -1
- data/sig/loggable.rbs +3 -1
- data/sig/options.rbs +35 -32
- data/sig/plugins/authentication.rbs +1 -1
- data/sig/plugins/aws_sdk_authentication.rbs +5 -1
- data/sig/plugins/aws_sigv4.rbs +1 -2
- data/sig/plugins/basic_authentication.rbs +1 -1
- data/sig/plugins/compression.rbs +4 -6
- data/sig/plugins/cookies.rbs +4 -5
- data/sig/plugins/cookies/cookie.rbs +5 -7
- data/sig/plugins/cookies/jar.rbs +9 -10
- data/sig/plugins/digest_authentication.rbs +2 -3
- data/sig/plugins/expect.rbs +2 -4
- data/sig/plugins/follow_redirects.rbs +3 -5
- data/sig/plugins/grpc.rbs +4 -7
- data/sig/plugins/h2c.rbs +0 -2
- data/sig/plugins/multipart.rbs +2 -4
- data/sig/plugins/ntlm_authentication.rbs +2 -3
- data/sig/plugins/persistent.rbs +3 -8
- data/sig/plugins/proxy.rbs +7 -7
- data/sig/plugins/proxy/ssh.rbs +4 -4
- data/sig/plugins/push_promise.rbs +0 -2
- data/sig/plugins/retries.rbs +4 -8
- data/sig/plugins/stream.rbs +1 -1
- data/sig/plugins/upgrade.rbs +2 -3
- data/sig/pool.rbs +1 -2
- data/sig/registry.rbs +1 -1
- data/sig/request.rbs +2 -2
- data/sig/resolver.rbs +7 -0
- data/sig/resolver/native.rbs +9 -5
- data/sig/resolver/resolver_mixin.rbs +4 -5
- data/sig/resolver/system.rbs +2 -0
- data/sig/response.rbs +17 -11
- data/sig/selector.rbs +6 -6
- data/sig/session.rbs +19 -14
- data/sig/transcoder.rbs +11 -4
- data/sig/transcoder/body.rbs +6 -1
- data/sig/transcoder/chunker.rbs +8 -2
- data/sig/transcoder/form.rbs +2 -1
- data/sig/transcoder/json.rbs +1 -0
- data/sig/utils.rbs +2 -0
- metadata +5 -3
- data/lib/httpx/request2.rb +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 829f24d8bbd078fc042f4b9ff73909708961aa2fcb5813d30680cf069d1d43d0
|
4
|
+
data.tar.gz: 52bb4d7e335d9f7bc82c928632e4bd67c2320210a2e63050902a280dc9ee711b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bf83ea792daf620629aa084eef37ff8cc81ffdf3c99f39bb0ae462d9673a82c941aa2341af766cf81359450d1b59338898f7431e14418e46808d87bf001673cc
|
7
|
+
data.tar.gz: 91b6de1278808c497b08ba273dd2f2de9f41e93b878867ac7cb4aa3bd716fd3a5ec5538722a59a362de0f2c263ab7e32b570546f2d940fa838a262741ad59e95
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# 0.16.0
|
2
|
+
|
3
|
+
## Features
|
4
|
+
|
5
|
+
### Response::Body#to_s does not clear the internal buffer
|
6
|
+
|
7
|
+
It's well documented that the response body should be treated as a file, and that calling `.to_s` on a response should be done only once, and the user should not expect the same call to return the same response body again, while suggesting that the first call should be cached in a variable in case it's needed:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
response = HTTPX.get("https://google.com")
|
11
|
+
body = response.body.to_s #=> "<html ...."
|
12
|
+
response.body.to_s #=> ""
|
13
|
+
|
14
|
+
# thankfully,it's cached in the body var there.
|
15
|
+
```
|
16
|
+
|
17
|
+
The justification for this behaviour probably had to do with avoiding keeping huge payloads around, but it got a bit lost in git history. It became a feature, not a bug.
|
18
|
+
|
19
|
+
However, I got an [issue report](https://gitlab.com/honeyryderchuck/httpx/-/issues/143) that made me change my mind about this behaviour (tl;dr: it broke pattern matching when matching against response bodies more than once).
|
20
|
+
|
21
|
+
So now, you can call `.to_s` how many times you want!
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
response = HTTPX.get("https://google.com")
|
25
|
+
body = response.body.to_s #=> "<html ...."
|
26
|
+
response.body.to_s #=> "<html ....", still here!
|
27
|
+
```
|
28
|
+
|
29
|
+
Some optimizations were done around how the body is carried forward, and bodies buffered in files will now get properly garbage collected and not leak descriptors behind when users forget to call `.close`.
|
30
|
+
|
31
|
+
### grpc plugin improvements
|
32
|
+
|
33
|
+
##### build fully-enabled stub from grpc service
|
34
|
+
|
35
|
+
The `:grpc` plugin can now build fully-loaded stubs from existing GRPC generic services.
|
36
|
+
|
37
|
+
GRPC stubs could be a bit tedious to write when compared to what the `grpc` gem offers, which is, auto-generation from ruby service stubs from protobuf definitions:
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
# service generated from the command:
|
41
|
+
#
|
42
|
+
# > grpc_tools_ruby_protoc -I ../../protos --ruby_out=../lib --grpc_out=../lib ../../protos/route_guide.proto
|
43
|
+
#
|
44
|
+
require "route_guide_services_pb.rb"
|
45
|
+
|
46
|
+
# with httpx, before 0.16
|
47
|
+
stub = HTTPX.plugin(:grpc).build_stub("localhost:#{server_port}", service: "RouteGuide")
|
48
|
+
.rpc(:GetFeature, Point, Feature)
|
49
|
+
.rpc(:ListFeatures, # ... and so on, all hand stitched
|
50
|
+
|
51
|
+
stub.get_feature(# ...
|
52
|
+
|
53
|
+
# with httpx 0.16
|
54
|
+
stub = HTTPX.plugin(:grpc).build_stub("localhost:#{server_port}", service: RouteGuide)
|
55
|
+
# that's it!
|
56
|
+
stub.get_feature(# ...
|
57
|
+
```
|
58
|
+
|
59
|
+
#### no google/protobuf direct dependency
|
60
|
+
|
61
|
+
`"google/protobuf"` is no longer assumed when using the plugin, i.e. you can use other protobuf serializers, such as https://github.com/ruby-protobuf/protobuf , which supports `jruby` (unlike the former).
|
62
|
+
|
63
|
+
### OptionsMethods for plugins
|
64
|
+
|
65
|
+
https://gitlab.com/honeyryderchuck/httpx/-/wikis/Custom-Plugins
|
66
|
+
|
67
|
+
You can now define an `OptionsMethods` module under your custom plugin to define your own methods. The tl;dr is, that, given the following module below, a new `:bar` option will be available (and the method will be used to set it):
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
module CustomPlugin
|
71
|
+
module OptionsMethods
|
72
|
+
def option_bar(x) ; x; end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
HTTPX.plugin(CustomPlugin).with(bar: 2)
|
77
|
+
```
|
78
|
+
|
79
|
+
### cookies plugin: improved jar management
|
80
|
+
|
81
|
+
The behaviour of the cookies jar from the `:cookies` plugin was a bit unpredictable in certain conditions, for instance if a "Cookie" header would be passed directly via `.with(headers: {"Cookie" => "a=1"})` and there'd be a value for it already (in same cases, it'd be fully ignored). This would even get worse, if the session had a jar, and a specific set of cookies would be passed to a request(i.e.: `session_with_cookies.get("http://url.get", headers: {"Cookies" => "..."}`).
|
82
|
+
|
83
|
+
The behaviour was fixed, and is now specced under https://gitlab.com/honeyryderchuck/httpx/-/blob/master/test/support/requests/plugins/cookies.rb .
|
84
|
+
|
85
|
+
## Bugfixes
|
86
|
+
|
87
|
+
* Cookies sorting in the `:cookies` plugin jar was fixed for truffleruby;
|
88
|
+
|
89
|
+
## Chore
|
90
|
+
|
91
|
+
* errors when setting options nnow raise `TypeError` instead of `HTTPX::Error`.
|
92
|
+
* options are now internally frozen by default, which should protect the internals against accidentally updating them;
|
93
|
+
* Fixed optimization around options initialization, to prevent needless allocations;
|
data/lib/httpx.rb
CHANGED
@@ -20,6 +20,7 @@ require "httpx/response"
|
|
20
20
|
require "httpx/options"
|
21
21
|
require "httpx/chainable"
|
22
22
|
|
23
|
+
require "mutex_m"
|
23
24
|
# Top-Level Namespace
|
24
25
|
#
|
25
26
|
module HTTPX
|
@@ -28,15 +29,16 @@ module HTTPX
|
|
28
29
|
#
|
29
30
|
module Plugins
|
30
31
|
@plugins = {}
|
32
|
+
@plugins.extend(Mutex_m)
|
31
33
|
|
32
34
|
# Loads a plugin based on a name. If the plugin hasn't been loaded, tries to load
|
33
35
|
# it from the load path under "httpx/plugins/" directory.
|
34
36
|
#
|
35
37
|
def self.load_plugin(name)
|
36
38
|
h = @plugins
|
37
|
-
unless (plugin = h[name])
|
39
|
+
unless (plugin = h.synchronize { h[name] })
|
38
40
|
require "httpx/plugins/#{name}"
|
39
|
-
raise "Plugin #{name} hasn't been registered" unless (plugin = h[name])
|
41
|
+
raise "Plugin #{name} hasn't been registered" unless (plugin = h.synchronize { h[name] })
|
40
42
|
end
|
41
43
|
plugin
|
42
44
|
end
|
@@ -44,7 +46,8 @@ module HTTPX
|
|
44
46
|
# Registers a plugin (+mod+) in the central store indexed by +name+.
|
45
47
|
#
|
46
48
|
def self.register_plugin(name, mod)
|
47
|
-
|
49
|
+
h = @plugins
|
50
|
+
h.synchronize { h[name] = mod }
|
48
51
|
end
|
49
52
|
end
|
50
53
|
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "delegate"
|
3
4
|
require "httpx"
|
4
5
|
require "faraday"
|
5
6
|
|
@@ -91,11 +92,12 @@ module Faraday
|
|
91
92
|
end
|
92
93
|
|
93
94
|
class ParallelManager
|
94
|
-
class ResponseHandler
|
95
|
+
class ResponseHandler < SimpleDelegator
|
95
96
|
attr_reader :env
|
96
97
|
|
97
98
|
def initialize(env)
|
98
99
|
@env = env
|
100
|
+
super
|
99
101
|
end
|
100
102
|
|
101
103
|
def on_response(&blk)
|
@@ -117,16 +119,6 @@ module Faraday
|
|
117
119
|
@on_complete
|
118
120
|
end
|
119
121
|
end
|
120
|
-
|
121
|
-
def respond_to_missing?(meth)
|
122
|
-
@env.respond_to?(meth) || super
|
123
|
-
end
|
124
|
-
|
125
|
-
def method_missing(meth, *args, &blk)
|
126
|
-
return super unless @env && @env.respond_to?(meth)
|
127
|
-
|
128
|
-
@env.__send__(meth, *args, &blk)
|
129
|
-
end
|
130
122
|
end
|
131
123
|
|
132
124
|
include RequestMixin
|
data/lib/httpx/buffer.rb
CHANGED
data/lib/httpx/callbacks.rb
CHANGED
@@ -19,7 +19,7 @@ module HTTPX
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def emit(type, *args)
|
22
|
-
callbacks(type).delete_if { |pr| :delete == pr
|
22
|
+
callbacks(type).delete_if { |pr| :delete == pr.call(*args) } # rubocop:disable Style/YodaCondition
|
23
23
|
end
|
24
24
|
|
25
25
|
protected
|
data/lib/httpx/chainable.rb
CHANGED
@@ -34,21 +34,21 @@ module HTTPX
|
|
34
34
|
branch(default_options).wrap(&blk)
|
35
35
|
end
|
36
36
|
|
37
|
-
def plugin(
|
37
|
+
def plugin(pl, options = nil, &blk)
|
38
38
|
klass = is_a?(Session) ? self.class : Session
|
39
39
|
klass = Class.new(klass)
|
40
40
|
klass.instance_variable_set(:@default_options, klass.default_options.merge(default_options))
|
41
|
-
klass.plugin(
|
41
|
+
klass.plugin(pl, options, &blk).new
|
42
42
|
end
|
43
43
|
|
44
44
|
# deprecated
|
45
45
|
# :nocov:
|
46
|
-
def plugins(
|
46
|
+
def plugins(pls)
|
47
47
|
warn ":#{__method__} is deprecated, use :plugin instead"
|
48
48
|
klass = is_a?(Session) ? self.class : Session
|
49
49
|
klass = Class.new(klass)
|
50
50
|
klass.instance_variable_set(:@default_options, klass.default_options.merge(default_options))
|
51
|
-
klass.plugins(
|
51
|
+
klass.plugins(pls).new
|
52
52
|
end
|
53
53
|
# :nocov:
|
54
54
|
|
@@ -71,12 +71,19 @@ module HTTPX
|
|
71
71
|
def method_missing(meth, *args, **options)
|
72
72
|
return super unless meth =~ /\Awith_(.+)/
|
73
73
|
|
74
|
-
option = Regexp.last_match(1)
|
75
|
-
|
74
|
+
option = Regexp.last_match(1)
|
75
|
+
|
76
|
+
return super unless option
|
77
|
+
|
78
|
+
with(option.to_sym => (args.first || options))
|
76
79
|
end
|
77
80
|
|
78
|
-
def respond_to_missing?(meth
|
79
|
-
|
81
|
+
def respond_to_missing?(meth)
|
82
|
+
return super unless meth =~ /\Awith_(.+)/
|
83
|
+
|
84
|
+
option = Regexp.last_match(1)
|
85
|
+
|
86
|
+
default_options.respond_to?(option) || super
|
80
87
|
end
|
81
88
|
end
|
82
89
|
end
|
data/lib/httpx/connection.rb
CHANGED
@@ -69,10 +69,10 @@ module HTTPX
|
|
69
69
|
end
|
70
70
|
|
71
71
|
@inflight = 0
|
72
|
-
@keep_alive_timeout = options.timeout[:keep_alive_timeout]
|
72
|
+
@keep_alive_timeout = @options.timeout[:keep_alive_timeout]
|
73
73
|
@keep_alive_timer = nil
|
74
74
|
|
75
|
-
self.addresses = options.addresses if options.addresses
|
75
|
+
self.addresses = @options.addresses if @options.addresses
|
76
76
|
end
|
77
77
|
|
78
78
|
# this is a semi-private method, to be used by the resolver
|
@@ -263,7 +263,9 @@ module HTTPX
|
|
263
263
|
request.chunk!
|
264
264
|
end
|
265
265
|
|
266
|
-
connection =
|
266
|
+
connection = request.headers["connection"]
|
267
|
+
|
268
|
+
connection ||= if request.options.persistent
|
267
269
|
# when in a persistent connection, the request can't be at
|
268
270
|
# the edge of a renegotiation
|
269
271
|
if @requests.index(request) + 1 < @max_requests
|
@@ -11,7 +11,7 @@ module HTTPX
|
|
11
11
|
|
12
12
|
MAX_CONCURRENT_REQUESTS = HTTP2Next::DEFAULT_MAX_CONCURRENT_STREAMS
|
13
13
|
|
14
|
-
Error
|
14
|
+
class Error < Error
|
15
15
|
def initialize(id, code)
|
16
16
|
super("stream #{id} closed with error: #{code}")
|
17
17
|
end
|
@@ -391,16 +391,6 @@ module HTTPX
|
|
391
391
|
emit(:pong)
|
392
392
|
end
|
393
393
|
end
|
394
|
-
|
395
|
-
def respond_to_missing?(meth, *args)
|
396
|
-
@connection.respond_to?(meth, *args) || super
|
397
|
-
end
|
398
|
-
|
399
|
-
def method_missing(meth, *args, &blk)
|
400
|
-
return super unless @connection.respond_to?(meth)
|
401
|
-
|
402
|
-
@connection.__send__(meth, *args, &blk)
|
403
|
-
end
|
404
394
|
end
|
405
395
|
Connection.register "h2", Connection::HTTP2
|
406
396
|
end
|
data/lib/httpx/errors.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module HTTPX
|
4
|
-
Error
|
4
|
+
class Error < StandardError; end
|
5
5
|
|
6
|
-
UnsupportedSchemeError
|
6
|
+
class UnsupportedSchemeError < Error; end
|
7
7
|
|
8
|
-
TimeoutError
|
8
|
+
class TimeoutError < Error
|
9
9
|
attr_reader :timeout
|
10
10
|
|
11
11
|
def initialize(timeout, message)
|
@@ -20,17 +20,17 @@ module HTTPX
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
TotalTimeoutError
|
23
|
+
class TotalTimeoutError < TimeoutError; end
|
24
24
|
|
25
|
-
ConnectTimeoutError
|
25
|
+
class ConnectTimeoutError < TimeoutError; end
|
26
26
|
|
27
|
-
SettingsTimeoutError
|
27
|
+
class SettingsTimeoutError < TimeoutError; end
|
28
28
|
|
29
|
-
ResolveTimeoutError
|
29
|
+
class ResolveTimeoutError < TimeoutError; end
|
30
30
|
|
31
|
-
ResolveError
|
31
|
+
class ResolveError < Error; end
|
32
32
|
|
33
|
-
NativeResolveError
|
33
|
+
class NativeResolveError < ResolveError
|
34
34
|
attr_reader :connection, :host
|
35
35
|
|
36
36
|
def initialize(connection, host, message = "Can't resolve #{host}")
|
@@ -40,7 +40,7 @@ module HTTPX
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
HTTPError
|
43
|
+
class HTTPError < Error
|
44
44
|
attr_reader :response
|
45
45
|
|
46
46
|
def initialize(response)
|
@@ -53,5 +53,5 @@ module HTTPX
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
-
MisdirectedRequestError
|
56
|
+
class MisdirectedRequestError < HTTPError; end
|
57
57
|
end
|
data/lib/httpx/io/ssl.rb
CHANGED
@@ -7,9 +7,9 @@ module HTTPX
|
|
7
7
|
|
8
8
|
class SSL < TCP
|
9
9
|
TLS_OPTIONS = if OpenSSL::SSL::SSLContext.instance_methods.include?(:alpn_protocols)
|
10
|
-
{ alpn_protocols: %w[h2 http/1.1] }
|
10
|
+
{ alpn_protocols: %w[h2 http/1.1].freeze }.freeze
|
11
11
|
else
|
12
|
-
{}
|
12
|
+
{}.freeze
|
13
13
|
end
|
14
14
|
|
15
15
|
def initialize(_, _, options)
|
data/lib/httpx/io/tls.rb
CHANGED
data/lib/httpx/options.rb
CHANGED
@@ -30,6 +30,7 @@ module HTTPX
|
|
30
30
|
:request_body_class => Class.new(Request::Body),
|
31
31
|
:response_body_class => Class.new(Response::Body),
|
32
32
|
:connection_class => Class.new(Connection),
|
33
|
+
:options_class => Class.new(self),
|
33
34
|
:transport => nil,
|
34
35
|
:transport_options => nil,
|
35
36
|
:addresses => nil,
|
@@ -41,39 +42,48 @@ module HTTPX
|
|
41
42
|
class << self
|
42
43
|
def new(options = {})
|
43
44
|
# let enhanced options go through
|
44
|
-
return options if self == Options && options.class
|
45
|
+
return options if self == Options && options.class < self
|
45
46
|
return options if options.is_a?(self)
|
46
47
|
|
47
48
|
super
|
48
49
|
end
|
49
50
|
|
50
|
-
def
|
51
|
-
|
51
|
+
def method_added(meth)
|
52
|
+
super
|
52
53
|
|
53
|
-
|
54
|
-
class_eval(<<-OUT, __FILE__, __LINE__ + 1)
|
55
|
-
def #{name}=(value)
|
56
|
-
return if value.nil?
|
54
|
+
return unless meth =~ /^option_(.+)$/
|
57
55
|
|
58
|
-
|
59
|
-
#{layout}
|
60
|
-
end
|
56
|
+
optname = Regexp.last_match(1).to_sym
|
61
57
|
|
62
|
-
|
63
|
-
|
58
|
+
attr_reader(optname)
|
59
|
+
end
|
60
|
+
|
61
|
+
def def_option(optname, *args, &block)
|
62
|
+
if args.size.zero? && !block_given?
|
63
|
+
class_eval(<<-OUT, __FILE__, __LINE__ + 1)
|
64
|
+
def option_#{optname}(v); v; end
|
64
65
|
OUT
|
66
|
+
return
|
67
|
+
end
|
65
68
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
+
deprecated_def_option(optname, *args, &block)
|
70
|
+
end
|
71
|
+
|
72
|
+
def deprecated_def_option(optname, layout = nil, &interpreter)
|
73
|
+
warn "DEPRECATION WARNING: using `def_option(#{optname})` for setting options is deprecated. " \
|
74
|
+
"Define module OptionsMethods and `def option_#{optname}(val)` instead."
|
69
75
|
|
70
|
-
|
76
|
+
if layout
|
77
|
+
class_eval(<<-OUT, __FILE__, __LINE__ + 1)
|
78
|
+
def option_#{optname}(value)
|
79
|
+
#{layout}
|
80
|
+
end
|
81
|
+
OUT
|
82
|
+
elsif block_given?
|
83
|
+
define_method(:"option_#{optname}") do |value|
|
84
|
+
instance_exec(value, &interpreter)
|
71
85
|
end
|
72
|
-
else
|
73
|
-
attr_writer name
|
74
86
|
end
|
75
|
-
|
76
|
-
protected :"#{name}="
|
77
87
|
end
|
78
88
|
end
|
79
89
|
|
@@ -83,26 +93,24 @@ module HTTPX
|
|
83
93
|
next if v.nil?
|
84
94
|
|
85
95
|
begin
|
86
|
-
__send__(:"#{k}
|
96
|
+
value = __send__(:"option_#{k}", v)
|
97
|
+
instance_variable_set(:"@#{k}", value)
|
87
98
|
rescue NoMethodError
|
88
99
|
raise Error, "unknown option: #{k}"
|
89
100
|
end
|
90
101
|
end
|
102
|
+
freeze
|
91
103
|
end
|
92
104
|
|
93
|
-
|
105
|
+
def option_origin(value)
|
94
106
|
URI(value)
|
95
|
-
|
107
|
+
end
|
96
108
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
else
|
101
|
-
Headers.new(value)
|
102
|
-
end
|
103
|
-
OUT
|
109
|
+
def option_headers(value)
|
110
|
+
Headers.new(value)
|
111
|
+
end
|
104
112
|
|
105
|
-
|
113
|
+
def option_timeout(value)
|
106
114
|
timeouts = Hash[value]
|
107
115
|
|
108
116
|
if timeouts.key?(:loop_timeout)
|
@@ -111,42 +119,43 @@ module HTTPX
|
|
111
119
|
end
|
112
120
|
|
113
121
|
timeouts
|
114
|
-
|
122
|
+
end
|
115
123
|
|
116
|
-
|
117
|
-
raise
|
124
|
+
def option_max_concurrent_requests(value)
|
125
|
+
raise TypeError, ":max_concurrent_requests must be positive" unless value.positive?
|
118
126
|
|
119
127
|
value
|
120
|
-
|
128
|
+
end
|
121
129
|
|
122
|
-
|
123
|
-
raise
|
130
|
+
def option_max_requests(value)
|
131
|
+
raise TypeError, ":max_requests must be positive" unless value.positive?
|
124
132
|
|
125
133
|
value
|
126
|
-
|
134
|
+
end
|
127
135
|
|
128
|
-
|
136
|
+
def option_window_size(value)
|
129
137
|
Integer(value)
|
130
|
-
|
138
|
+
end
|
131
139
|
|
132
|
-
|
140
|
+
def option_body_threshold_size(value)
|
133
141
|
Integer(value)
|
134
|
-
|
142
|
+
end
|
135
143
|
|
136
|
-
|
144
|
+
def option_transport(value)
|
137
145
|
transport = value.to_s
|
138
|
-
raise
|
146
|
+
raise TypeError, "\#{transport} is an unsupported transport type" unless IO.registry.key?(transport)
|
139
147
|
|
140
148
|
transport
|
141
|
-
|
149
|
+
end
|
142
150
|
|
143
|
-
|
151
|
+
def option_addresses(value)
|
144
152
|
Array(value)
|
145
|
-
|
153
|
+
end
|
146
154
|
|
147
155
|
%i[
|
148
156
|
params form json body ssl http2_settings
|
149
|
-
request_class response_class headers_class request_body_class
|
157
|
+
request_class response_class headers_class request_body_class
|
158
|
+
response_body_class connection_class options_class
|
150
159
|
io fallback_protocol debug debug_level transport_options resolver_class resolver_options
|
151
160
|
persistent
|
152
161
|
].each do |method_name|
|
@@ -180,9 +189,8 @@ module HTTPX
|
|
180
189
|
|
181
190
|
return self if h1 == h2
|
182
191
|
|
183
|
-
merged = h1.merge(h2) do |
|
184
|
-
|
185
|
-
when :headers, :ssl, :http2_settings, :timeout
|
192
|
+
merged = h1.merge(h2) do |_k, v1, v2|
|
193
|
+
if v1.respond_to?(:merge) && v2.respond_to?(:merge)
|
186
194
|
v1.merge(v2)
|
187
195
|
else
|
188
196
|
v2
|
@@ -199,28 +207,25 @@ module HTTPX
|
|
199
207
|
Hash[hash_pairs]
|
200
208
|
end
|
201
209
|
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
request_body_class.freeze
|
222
|
-
response_body_class.freeze
|
223
|
-
connection_class.freeze
|
210
|
+
if RUBY_VERSION > "2.4.0"
|
211
|
+
def initialize_dup(other)
|
212
|
+
instance_variables.each do |ivar|
|
213
|
+
instance_variable_set(ivar, other.instance_variable_get(ivar).dup)
|
214
|
+
end
|
215
|
+
end
|
216
|
+
else
|
217
|
+
def initialize_dup(other)
|
218
|
+
instance_variables.each do |ivar|
|
219
|
+
value = other.instance_variable_get(ivar)
|
220
|
+
value = case value
|
221
|
+
when Symbol, Fixnum, TrueClass, FalseClass # rubocop:disable Lint/UnifiedInteger
|
222
|
+
value
|
223
|
+
else
|
224
|
+
value.dup
|
225
|
+
end
|
226
|
+
instance_variable_set(ivar, value)
|
227
|
+
end
|
228
|
+
end
|
224
229
|
end
|
225
230
|
end
|
226
231
|
end
|