httpx 1.8.4 → 1.9.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/1_9_0.md +75 -0
- data/lib/httpx/adapters/webmock.rb +1 -1
- data/lib/httpx/altsvc.rb +29 -15
- data/lib/httpx/chainable.rb +4 -1
- data/lib/httpx/connection/http1.rb +11 -19
- data/lib/httpx/connection/http2.rb +48 -14
- data/lib/httpx/connection.rb +171 -47
- data/lib/httpx/headers.rb +2 -2
- data/lib/httpx/io/tcp.rb +18 -14
- data/lib/httpx/options.rb +86 -35
- data/lib/httpx/parser/http1.rb +3 -6
- data/lib/httpx/plugins/auth/digest.rb +1 -2
- data/lib/httpx/plugins/auth.rb +11 -2
- data/lib/httpx/plugins/aws_sdk_authentication.rb +7 -3
- data/lib/httpx/plugins/aws_sigv4.rb +1 -0
- data/lib/httpx/plugins/basic_auth.rb +2 -0
- data/lib/httpx/plugins/callbacks.rb +7 -6
- data/lib/httpx/plugins/circuit_breaker.rb +1 -0
- data/lib/httpx/plugins/digest_auth.rb +2 -0
- data/lib/httpx/plugins/expect.rb +2 -0
- data/lib/httpx/plugins/fiber_concurrency.rb +6 -0
- data/lib/httpx/plugins/follow_redirects.rb +1 -1
- data/lib/httpx/plugins/grpc.rb +21 -0
- data/lib/httpx/plugins/hedging.rb +284 -0
- data/lib/httpx/plugins/ntlm_auth.rb +1 -0
- data/lib/httpx/plugins/ntlm_v2_auth.rb +1 -0
- data/lib/httpx/plugins/oauth.rb +1 -1
- data/lib/httpx/plugins/proxy/http.rb +44 -10
- data/lib/httpx/plugins/proxy/ssh.rb +30 -11
- data/lib/httpx/plugins/proxy.rb +62 -41
- data/lib/httpx/plugins/push_promise.rb +4 -2
- data/lib/httpx/plugins/retries.rb +2 -2
- data/lib/httpx/plugins/server_sent_events.rb +1 -0
- data/lib/httpx/plugins/ssrf_filter.rb +1 -1
- data/lib/httpx/plugins/tracing.rb +58 -11
- data/lib/httpx/plugins/upgrade/h2.rb +1 -1
- data/lib/httpx/plugins/upgrade.rb +2 -0
- data/lib/httpx/plugins/webdav.rb +8 -0
- data/lib/httpx/request/body.rb +2 -1
- data/lib/httpx/request.rb +5 -5
- data/lib/httpx/resolver.rb +5 -1
- data/lib/httpx/response.rb +15 -7
- data/lib/httpx/selector.rb +3 -3
- data/lib/httpx/session.rb +36 -10
- data/lib/httpx/version.rb +1 -1
- data/sig/altsvc.rbs +3 -3
- data/sig/callbacks.rbs +1 -0
- data/sig/chainable.rbs +1 -0
- data/sig/connection/http1.rbs +1 -1
- data/sig/connection/http2.rbs +15 -15
- data/sig/connection.rbs +18 -1
- data/sig/headers.rbs +1 -1
- data/sig/httpx.rbs +2 -0
- data/sig/options.rbs +43 -12
- data/sig/parser/http1.rbs +1 -1
- data/sig/plugins/auth/digest.rbs +0 -1
- data/sig/plugins/auth.rbs +12 -5
- data/sig/plugins/hedging.rbs +44 -0
- data/sig/plugins/proxy/http.rbs +6 -1
- data/sig/plugins/proxy.rbs +3 -2
- data/sig/plugins/retries.rbs +2 -2
- data/sig/plugins/tracing.rbs +14 -5
- data/sig/request/body.rbs +1 -1
- data/sig/resolver/entry.rbs +2 -2
- data/sig/response.rbs +1 -2
- data/sig/selector.rbs +2 -2
- data/sig/session.rbs +7 -5
- metadata +5 -1
data/lib/httpx/options.rb
CHANGED
|
@@ -12,12 +12,11 @@ module HTTPX
|
|
|
12
12
|
SETTINGS_TIMEOUT = 10
|
|
13
13
|
CLOSE_HANDSHAKE_TIMEOUT = 10
|
|
14
14
|
CONNECT_TIMEOUT = READ_TIMEOUT = WRITE_TIMEOUT = 60
|
|
15
|
-
REQUEST_TIMEOUT = OPERATION_TIMEOUT = TOTAL_REQUEST_TIMEOUT = nil
|
|
16
15
|
RESOLVER_TYPES = %i[memory file].freeze
|
|
17
16
|
# default value used for "user-agent" header, when not overridden.
|
|
18
17
|
USER_AGENT = "httpx.rb/#{VERSION}".freeze # rubocop:disable Style/RedundantFreeze
|
|
19
18
|
|
|
20
|
-
@options_names = []
|
|
19
|
+
@options_names = Set[]
|
|
21
20
|
|
|
22
21
|
class << self
|
|
23
22
|
attr_reader :options_names
|
|
@@ -199,14 +198,14 @@ module HTTPX
|
|
|
199
198
|
# here, which is to make option objects shareable across ractors,
|
|
200
199
|
# and in most cases debug should be nil, or one of the objects
|
|
201
200
|
# which will eventually be shareable, like STDOUT or STDERR.
|
|
202
|
-
next if ivar
|
|
201
|
+
next if %i[debug io].include?(ivar)
|
|
203
202
|
|
|
204
|
-
|
|
203
|
+
send(ivar).freeze
|
|
205
204
|
end
|
|
206
205
|
super
|
|
207
206
|
end
|
|
208
207
|
|
|
209
|
-
REQUEST_BODY_IVARS = %i[
|
|
208
|
+
REQUEST_BODY_IVARS = %i[headers].freeze
|
|
210
209
|
|
|
211
210
|
# checks whether +other+ matches the same connection-level options
|
|
212
211
|
def connection_options_match?(other, ignore_ivars = nil)
|
|
@@ -214,20 +213,18 @@ module HTTPX
|
|
|
214
213
|
|
|
215
214
|
# headers and other request options do not play a role, as they are
|
|
216
215
|
# relevant only for the request.
|
|
217
|
-
ivars =
|
|
218
|
-
ivars.reject
|
|
219
|
-
ivars.reject! { |iv| ignore_ivars.include?(iv) } if ignore_ivars
|
|
216
|
+
ivars = self.class.options_names.reject { |iv| REQUEST_BODY_IVARS.include?(iv) }
|
|
217
|
+
ivars = ivars.reject { |iv| ignore_ivars.include?(iv) } if ignore_ivars
|
|
220
218
|
|
|
221
|
-
other_ivars = other.
|
|
222
|
-
other_ivars.reject
|
|
223
|
-
other_ivars.reject! { |iv| ignore_ivars.include?(iv) } if ignore_ivars
|
|
219
|
+
other_ivars = other.class.options_names.reject { |iv| REQUEST_BODY_IVARS.include?(iv) }
|
|
220
|
+
other_ivars = other_ivars.reject { |iv| ignore_ivars.include?(iv) } if ignore_ivars
|
|
224
221
|
|
|
225
222
|
return false if ivars.size != other_ivars.size
|
|
226
223
|
|
|
227
|
-
return false if ivars
|
|
224
|
+
return false if ivars != other_ivars
|
|
228
225
|
|
|
229
226
|
ivars.all? do |ivar|
|
|
230
|
-
|
|
227
|
+
send(ivar) == other.send(ivar)
|
|
231
228
|
end
|
|
232
229
|
end
|
|
233
230
|
|
|
@@ -296,6 +293,7 @@ module HTTPX
|
|
|
296
293
|
opts.instance_variable_set(ivar, v)
|
|
297
294
|
end
|
|
298
295
|
|
|
296
|
+
opts.freeze
|
|
299
297
|
opts
|
|
300
298
|
end
|
|
301
299
|
|
|
@@ -455,20 +453,22 @@ module HTTPX
|
|
|
455
453
|
end
|
|
456
454
|
|
|
457
455
|
def option_timeout(value)
|
|
456
|
+
return value if value.is_a?(Timeouts)
|
|
457
|
+
|
|
458
458
|
timeout_hash = Hash[value]
|
|
459
459
|
|
|
460
|
-
default_timeouts =
|
|
460
|
+
default_timeouts = Timeouts.members
|
|
461
461
|
|
|
462
462
|
# Validate keys and values
|
|
463
463
|
timeout_hash.each do |key, val|
|
|
464
|
-
raise TypeError, "invalid timeout: `:#{key}`" unless default_timeouts.
|
|
464
|
+
raise TypeError, "invalid timeout: `:#{key}`" unless default_timeouts.include?(key)
|
|
465
465
|
|
|
466
466
|
next if val.nil?
|
|
467
467
|
|
|
468
468
|
raise TypeError, "`:#{key}` must be numeric" unless val.is_a?(Numeric)
|
|
469
469
|
end
|
|
470
470
|
|
|
471
|
-
timeout_hash
|
|
471
|
+
Timeouts.new(**timeout_hash)
|
|
472
472
|
end
|
|
473
473
|
|
|
474
474
|
def option_supported_compression_formats(value)
|
|
@@ -483,7 +483,14 @@ module HTTPX
|
|
|
483
483
|
end
|
|
484
484
|
|
|
485
485
|
def option_addresses(value)
|
|
486
|
-
|
|
486
|
+
case value
|
|
487
|
+
when Hash
|
|
488
|
+
value.transform_values do |value|
|
|
489
|
+
Array(value).map { |entry| Resolver::Entry.convert(entry) }
|
|
490
|
+
end
|
|
491
|
+
else
|
|
492
|
+
Array(value).map { |entry| Resolver::Entry.convert(entry) }
|
|
493
|
+
end
|
|
487
494
|
end
|
|
488
495
|
|
|
489
496
|
def option_ip_families(value)
|
|
@@ -539,12 +546,67 @@ module HTTPX
|
|
|
539
546
|
end
|
|
540
547
|
end
|
|
541
548
|
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
549
|
+
class Timeouts < Struct.new(
|
|
550
|
+
:connect_timeout, :settings_timeout,
|
|
551
|
+
:read_timeout, :write_timeout,
|
|
552
|
+
:request_timeout, :total_request_timeout,
|
|
553
|
+
:operation_timeout, :keep_alive_timeout, :ping_timeout, :close_handshake_timeout,
|
|
554
|
+
keyword_init: true
|
|
555
|
+
)
|
|
556
|
+
def initialize(
|
|
557
|
+
connect_timeout: nil,
|
|
558
|
+
settings_timeout: nil,
|
|
559
|
+
read_timeout: nil,
|
|
560
|
+
write_timeout: nil,
|
|
561
|
+
request_timeout: nil,
|
|
562
|
+
total_request_timeout: nil,
|
|
563
|
+
operation_timeout: nil,
|
|
564
|
+
close_handshake_timeout: nil,
|
|
565
|
+
keep_alive_timeout: nil,
|
|
566
|
+
ping_timeout: nil
|
|
567
|
+
)
|
|
568
|
+
super
|
|
569
|
+
freeze
|
|
570
|
+
end
|
|
571
|
+
|
|
572
|
+
def connect_timeout
|
|
573
|
+
self[:connect_timeout] || (CONNECT_TIMEOUT unless deadline_timeouts?)
|
|
574
|
+
end
|
|
575
|
+
|
|
576
|
+
def settings_timeout
|
|
577
|
+
self[:settings_timeout] || (SETTINGS_TIMEOUT unless deadline_timeouts?)
|
|
578
|
+
end
|
|
579
|
+
|
|
580
|
+
def read_timeout
|
|
581
|
+
self[:read_timeout] || (READ_TIMEOUT unless deadline_timeouts?)
|
|
582
|
+
end
|
|
583
|
+
|
|
584
|
+
def write_timeout
|
|
585
|
+
self[:write_timeout] || (WRITE_TIMEOUT unless deadline_timeouts?)
|
|
586
|
+
end
|
|
587
|
+
|
|
588
|
+
def close_handshake_timeout
|
|
589
|
+
self[:close_handshake_timeout] || CLOSE_HANDSHAKE_TIMEOUT
|
|
590
|
+
end
|
|
591
|
+
|
|
592
|
+
def keep_alive_timeout
|
|
593
|
+
self[:keep_alive_timeout] || KEEP_ALIVE_TIMEOUT
|
|
594
|
+
end
|
|
595
|
+
|
|
596
|
+
def ping_timeout
|
|
597
|
+
self[:ping_timeout] || PING_TIMEOUT
|
|
598
|
+
end
|
|
599
|
+
|
|
600
|
+
def merge(other)
|
|
601
|
+
other_h = other.to_h
|
|
602
|
+
other_h.compact!
|
|
603
|
+
Timeouts.new(**to_h, **other_h)
|
|
604
|
+
end
|
|
605
|
+
|
|
606
|
+
private
|
|
607
|
+
|
|
608
|
+
def deadline_timeouts?
|
|
609
|
+
request_timeout || total_request_timeout || operation_timeout
|
|
548
610
|
end
|
|
549
611
|
end
|
|
550
612
|
|
|
@@ -572,18 +634,7 @@ module HTTPX
|
|
|
572
634
|
:max_response_headers => 1000,
|
|
573
635
|
:max_response_header_value_size => nil,
|
|
574
636
|
:max_response_body_size => Float::INFINITY,
|
|
575
|
-
:timeout =>
|
|
576
|
-
connect_timeout: CONNECT_TIMEOUT,
|
|
577
|
-
settings_timeout: SETTINGS_TIMEOUT,
|
|
578
|
-
close_handshake_timeout: CLOSE_HANDSHAKE_TIMEOUT,
|
|
579
|
-
operation_timeout: OPERATION_TIMEOUT,
|
|
580
|
-
keep_alive_timeout: KEEP_ALIVE_TIMEOUT,
|
|
581
|
-
ping_timeout: PING_TIMEOUT,
|
|
582
|
-
read_timeout: READ_TIMEOUT,
|
|
583
|
-
write_timeout: WRITE_TIMEOUT,
|
|
584
|
-
request_timeout: REQUEST_TIMEOUT,
|
|
585
|
-
total_request_timeout: TOTAL_REQUEST_TIMEOUT,
|
|
586
|
-
}.freeze,
|
|
637
|
+
:timeout => Timeouts.new,
|
|
587
638
|
:headers_class => Class.new(Headers, &SET_TEMPORARY_NAME),
|
|
588
639
|
:headers => EMPTY_HASH,
|
|
589
640
|
:window_size => WINDOW_SIZE,
|
data/lib/httpx/parser/http1.rb
CHANGED
|
@@ -68,7 +68,7 @@ module HTTPX
|
|
|
68
68
|
version, code, _ = m.captures
|
|
69
69
|
raise(Error, "unsupported HTTP version (HTTP/#{version})") unless version && VERSIONS.include?(version)
|
|
70
70
|
|
|
71
|
-
@http_version = version
|
|
71
|
+
@http_version = version
|
|
72
72
|
@status_code = code.to_i
|
|
73
73
|
raise(Error, "wrong status code (#{@status_code})") unless (100..599).cover?(@status_code)
|
|
74
74
|
|
|
@@ -78,9 +78,7 @@ module HTTPX
|
|
|
78
78
|
|
|
79
79
|
def parse_headers
|
|
80
80
|
headers = @headers
|
|
81
|
-
buffer = @buffer
|
|
82
|
-
|
|
83
|
-
#: @type var buffer: String
|
|
81
|
+
buffer = @buffer #: String
|
|
84
82
|
|
|
85
83
|
while (idx = buffer.index("\n"))
|
|
86
84
|
# @type var line: String
|
|
@@ -114,8 +112,7 @@ module HTTPX
|
|
|
114
112
|
key = line.byteslice(0..(separator_index - 1))
|
|
115
113
|
|
|
116
114
|
key.rstrip! # was lstripped previously!
|
|
117
|
-
|
|
118
|
-
value = line.byteslice((separator_index + 1)..-1)
|
|
115
|
+
value = line.byteslice((separator_index + 1)..-1) #: String
|
|
119
116
|
value.strip!
|
|
120
117
|
raise Error, "wrong header format" if value.nil?
|
|
121
118
|
|
|
@@ -14,7 +14,6 @@ module HTTPX
|
|
|
14
14
|
def initialize(user, password, hashed: false, **)
|
|
15
15
|
@user = user
|
|
16
16
|
@password = password
|
|
17
|
-
@nonce = 0
|
|
18
17
|
@hashed = hashed
|
|
19
18
|
end
|
|
20
19
|
|
|
@@ -137,7 +136,7 @@ module HTTPX
|
|
|
137
136
|
end
|
|
138
137
|
|
|
139
138
|
def next_nonce
|
|
140
|
-
|
|
139
|
+
SecureRandom.random_number(2**32)
|
|
141
140
|
end
|
|
142
141
|
|
|
143
142
|
def raise_format_error
|
data/lib/httpx/plugins/auth.rb
CHANGED
|
@@ -69,14 +69,18 @@ module HTTPX
|
|
|
69
69
|
@skip_auth_header_value = false
|
|
70
70
|
end
|
|
71
71
|
|
|
72
|
+
# returns a new session where requests will be authorized using +token+ (or what the +blk+ yields),
|
|
73
|
+
# using +auth_header_type+ as header value prefix.
|
|
72
74
|
def authorization(token = nil, auth_header_type: nil, &blk)
|
|
73
75
|
with(auth_header_type: auth_header_type, auth_header_value: token || blk)
|
|
74
76
|
end
|
|
75
77
|
|
|
78
|
+
# returns a new session which call #authorize while setting <tt>"Bearer"</tt> as the +auth_header_type+.
|
|
76
79
|
def bearer_auth(token = nil, &blk)
|
|
77
80
|
authorization(token, auth_header_type: "Bearer", &blk)
|
|
78
81
|
end
|
|
79
82
|
|
|
83
|
+
# yields a block where authorization (if available) will be bypassed.
|
|
80
84
|
def skip_auth_header
|
|
81
85
|
@skip_auth_header_value = true
|
|
82
86
|
yield
|
|
@@ -84,6 +88,7 @@ module HTTPX
|
|
|
84
88
|
@skip_auth_header_value = false
|
|
85
89
|
end
|
|
86
90
|
|
|
91
|
+
# resets authorization information.
|
|
87
92
|
def reset_auth_header_value!
|
|
88
93
|
@auth_header_value_mtx.synchronize do
|
|
89
94
|
@auth_header_value = @auth_header_expires_at = nil
|
|
@@ -186,11 +191,15 @@ module HTTPX
|
|
|
186
191
|
auth_error?(response, options) || super
|
|
187
192
|
end
|
|
188
193
|
|
|
189
|
-
def prepare_to_retry(request, response)
|
|
194
|
+
def prepare_to_retry(request, response, retry_after)
|
|
190
195
|
super
|
|
191
196
|
|
|
192
197
|
return unless auth_error?(response, request.options) ||
|
|
193
|
-
(@options.generate_auth_value_on_retry && @options.generate_auth_value_on_retry.call(response))
|
|
198
|
+
(@options.generate_auth_value_on_retry && @options.generate_auth_value_on_retry.call(response)) ||
|
|
199
|
+
(
|
|
200
|
+
(expires_at = @auth_header_expires_at) &&
|
|
201
|
+
expires_at < (Time.now.utc.to_i + (retry_after || 0))
|
|
202
|
+
)
|
|
194
203
|
|
|
195
204
|
# regenerate token before retry, but only if it's the first request from batch failing.
|
|
196
205
|
# otherwise, it means that the first request already passed here, so this request should
|
|
@@ -85,9 +85,13 @@ module HTTPX
|
|
|
85
85
|
|
|
86
86
|
module InstanceMethods
|
|
87
87
|
#
|
|
88
|
-
#
|
|
89
|
-
#
|
|
90
|
-
#
|
|
88
|
+
# returns a session which will use the AWS credentials provided by your AWS system configuration.
|
|
89
|
+
#
|
|
90
|
+
# session = HTTPX.plugin(:aws_sdk_authentication)
|
|
91
|
+
# auth_session = session.aws_authentication
|
|
92
|
+
# # OR
|
|
93
|
+
# auth_session = session.aws_authentication(credentials: Aws::Credentials.new('akid', 'secret'))
|
|
94
|
+
# auth_session.get("http://...")
|
|
91
95
|
#
|
|
92
96
|
def aws_sdk_authentication(
|
|
93
97
|
credentials: AwsSdkAuthentication.credentials(@options.aws_profile),
|
|
@@ -19,6 +19,8 @@ module HTTPX
|
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
module InstanceMethods
|
|
22
|
+
# returns a new session which will authorize requests using HTTP Basic Auth, with
|
|
23
|
+
# +user+ and +password+ as credentials.
|
|
22
24
|
def basic_auth(user, password)
|
|
23
25
|
authorization(Authentication::Basic.new(user, password).authenticate)
|
|
24
26
|
end
|
|
@@ -25,6 +25,7 @@ module HTTPX
|
|
|
25
25
|
|
|
26
26
|
CALLBACKS.each do |meth|
|
|
27
27
|
class_eval(<<-MOD, __FILE__, __LINE__ + 1)
|
|
28
|
+
# sets a <tt>:#{meth}</tt> callback on the session
|
|
28
29
|
def on_#{meth}(&blk) # def on_connection_opened(&blk)
|
|
29
30
|
on(:#{meth}, &blk) # on(:connection_opened, &blk)
|
|
30
31
|
self # self
|
|
@@ -44,6 +45,12 @@ module HTTPX
|
|
|
44
45
|
end
|
|
45
46
|
end
|
|
46
47
|
|
|
48
|
+
def close(*)
|
|
49
|
+
super
|
|
50
|
+
rescue CallbackError => e
|
|
51
|
+
raise e.cause
|
|
52
|
+
end
|
|
53
|
+
|
|
47
54
|
private
|
|
48
55
|
|
|
49
56
|
def branch(options, &blk)
|
|
@@ -114,12 +121,6 @@ module HTTPX
|
|
|
114
121
|
rescue CallbackError => e
|
|
115
122
|
raise e.cause
|
|
116
123
|
end
|
|
117
|
-
|
|
118
|
-
def close(*)
|
|
119
|
-
super
|
|
120
|
-
rescue CallbackError => e
|
|
121
|
-
raise e.cause
|
|
122
|
-
end
|
|
123
124
|
end
|
|
124
125
|
|
|
125
126
|
module RequestMethods
|
|
@@ -34,6 +34,7 @@ module HTTPX
|
|
|
34
34
|
|
|
35
35
|
%i[circuit_open].each do |meth|
|
|
36
36
|
class_eval(<<-MOD, __FILE__, __LINE__ + 1)
|
|
37
|
+
# sets a <tt>:#{meth}</tt> callback on the session.
|
|
37
38
|
def on_#{meth}(&blk) # def on_circuit_open(&blk)
|
|
38
39
|
on(:#{meth}, &blk) # on(:circuit_open, &blk)
|
|
39
40
|
self # self
|
|
@@ -33,6 +33,8 @@ module HTTPX
|
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
module InstanceMethods
|
|
36
|
+
# returns a session which will authenticate requests using HTTP Digest Auth, with
|
|
37
|
+
# +user+ and +password+ as credentials.
|
|
36
38
|
def digest_auth(user, password, hashed: false)
|
|
37
39
|
with(digest: Authentication::Digest.new(user, password, hashed: hashed))
|
|
38
40
|
end
|
data/lib/httpx/plugins/expect.rb
CHANGED
|
@@ -112,6 +112,12 @@ module HTTPX
|
|
|
112
112
|
super
|
|
113
113
|
end
|
|
114
114
|
|
|
115
|
+
def pending_count
|
|
116
|
+
count = @pending.count(&:current_context?)
|
|
117
|
+
count += @parser.pending.count(&:current_context?) if @parser.respond_to?(:pending)
|
|
118
|
+
count
|
|
119
|
+
end
|
|
120
|
+
|
|
115
121
|
private
|
|
116
122
|
|
|
117
123
|
# checks whether the connection has any pending request (which the connection itself may
|
data/lib/httpx/plugins/grpc.rb
CHANGED
|
@@ -69,6 +69,17 @@ module HTTPX
|
|
|
69
69
|
end
|
|
70
70
|
end
|
|
71
71
|
|
|
72
|
+
# adds support for the following options:
|
|
73
|
+
#
|
|
74
|
+
# :grpc_service :: name of the GRPC service service.
|
|
75
|
+
# :grpc_compression :: whether payloads should be GZIP-compressed (<tt>false</tt> by default).
|
|
76
|
+
# :grpc_rpcs :: maps local rpc names to the service RCP information.
|
|
77
|
+
# :grpc_deadline :: sets the service call deadline that the peer should stick to.
|
|
78
|
+
# :call_credentials :: callable which should yield a key-value hash which will be passed in the
|
|
79
|
+
# request HTTP headers.
|
|
80
|
+
#
|
|
81
|
+
# You're recommended not to set any of these options directly, and instead use methods such as
|
|
82
|
+
# InstanceMethods#rpc and InstanceMethods#build_stub.
|
|
72
83
|
module OptionsMethods
|
|
73
84
|
private
|
|
74
85
|
|
|
@@ -125,6 +136,9 @@ module HTTPX
|
|
|
125
136
|
end
|
|
126
137
|
|
|
127
138
|
module InstanceMethods
|
|
139
|
+
# returns a new session which sets the TLS channel credentials (+ca_path+ as the CA file,
|
|
140
|
+
# +key+ and +cert+ as the TLS public key and certificate, as well as other TLS options via
|
|
141
|
+
# +ssl_opts+, which should be compatible with what OpenSSL::SSL::SSLContext#set_params receives).
|
|
128
142
|
def with_channel_credentials(ca_path, key = nil, cert = nil, **ssl_opts)
|
|
129
143
|
# @type var ssl_params: ::Hash[::Symbol, untyped]
|
|
130
144
|
ssl_params = {
|
|
@@ -144,6 +158,8 @@ module HTTPX
|
|
|
144
158
|
with(ssl: ssl_params)
|
|
145
159
|
end
|
|
146
160
|
|
|
161
|
+
# returns a new session with a service RPC identified by +rpc_name+, passing +input+ and +output+ as its
|
|
162
|
+
# input encoder and output decoder respectively; extra options (like <tt>:deadline</tt>) can be passed using +opts+.
|
|
147
163
|
def rpc(rpc_name, input, output, **opts)
|
|
148
164
|
rpc_name = rpc_name.to_s
|
|
149
165
|
raise Error, "rpc #{rpc_name} already defined" if @options.grpc_rpcs.key?(rpc_name)
|
|
@@ -179,6 +195,9 @@ module HTTPX
|
|
|
179
195
|
))
|
|
180
196
|
end
|
|
181
197
|
|
|
198
|
+
# returns a new GRPC Service enabled session pointing to a +origin+ URI; when the
|
|
199
|
+
# +service+ is a GRPC Service object (as the ones provided by the `grpc` gem), it'll
|
|
200
|
+
# automatically generate the RPC methods.
|
|
182
201
|
def build_stub(origin, service: nil, compression: false)
|
|
183
202
|
scheme = @options.ssl.empty? ? "http" : "https"
|
|
184
203
|
|
|
@@ -212,6 +231,8 @@ module HTTPX
|
|
|
212
231
|
session.with(origin: origin, grpc_service: service, grpc_compression: compression)
|
|
213
232
|
end
|
|
214
233
|
|
|
234
|
+
# executes an RPC service identified by +rpc_method+. You're recommended to use the generated
|
|
235
|
+
# RPC methods directly though, in case you're using #build_stub.
|
|
215
236
|
def execute(rpc_method, input,
|
|
216
237
|
deadline: DEADLINE,
|
|
217
238
|
metadata: nil,
|