httpx 0.15.4 → 0.18.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/doc/release_notes/0_16_1.md +5 -0
- data/doc/release_notes/0_17_0.md +49 -0
- data/doc/release_notes/0_18_0.md +69 -0
- data/lib/httpx/adapters/datadog.rb +1 -1
- data/lib/httpx/adapters/faraday.rb +8 -14
- data/lib/httpx/adapters/webmock.rb +9 -3
- data/lib/httpx/altsvc.rb +2 -2
- data/lib/httpx/buffer.rb +1 -1
- data/lib/httpx/callbacks.rb +1 -1
- data/lib/httpx/chainable.rb +18 -11
- data/lib/httpx/connection/http1.rb +21 -13
- data/lib/httpx/connection/http2.rb +20 -25
- data/lib/httpx/connection.rb +73 -77
- data/lib/httpx/domain_name.rb +1 -1
- data/lib/httpx/errors.rb +11 -11
- data/lib/httpx/extensions.rb +50 -4
- data/lib/httpx/headers.rb +1 -1
- data/lib/httpx/io/ssl.rb +3 -3
- data/lib/httpx/io/tls.rb +8 -8
- data/lib/httpx/loggable.rb +5 -5
- data/lib/httpx/options.rb +108 -81
- data/lib/httpx/parser/http1.rb +11 -7
- data/lib/httpx/plugins/aws_sdk_authentication.rb +42 -18
- data/lib/httpx/plugins/aws_sigv4.rb +19 -20
- data/lib/httpx/plugins/compression.rb +17 -14
- data/lib/httpx/plugins/cookies/cookie.rb +4 -2
- data/lib/httpx/plugins/cookies/jar.rb +21 -2
- data/lib/httpx/plugins/cookies.rb +20 -7
- data/lib/httpx/plugins/digest_authentication.rb +19 -15
- data/lib/httpx/plugins/expect.rb +26 -18
- data/lib/httpx/plugins/follow_redirects.rb +9 -9
- data/lib/httpx/plugins/grpc/call.rb +4 -1
- data/lib/httpx/plugins/grpc/message.rb +2 -2
- data/lib/httpx/plugins/grpc.rb +72 -46
- data/lib/httpx/plugins/h2c.rb +7 -3
- data/lib/httpx/plugins/internal_telemetry.rb +8 -8
- data/lib/httpx/plugins/multipart/decoder.rb +187 -0
- data/lib/httpx/plugins/multipart/mime_type_detector.rb +3 -3
- data/lib/httpx/plugins/multipart/part.rb +2 -2
- data/lib/httpx/plugins/multipart.rb +16 -2
- data/lib/httpx/plugins/ntlm_authentication.rb +12 -10
- 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 +20 -13
- data/lib/httpx/plugins/proxy.rb +10 -10
- data/lib/httpx/plugins/response_cache/store.rb +55 -0
- data/lib/httpx/plugins/response_cache.rb +88 -0
- data/lib/httpx/plugins/retries.rb +46 -23
- data/lib/httpx/plugins/stream.rb +3 -4
- data/lib/httpx/plugins/upgrade.rb +7 -6
- data/lib/httpx/pool.rb +39 -13
- data/lib/httpx/registry.rb +2 -2
- data/lib/httpx/request.rb +16 -25
- data/lib/httpx/resolver/https.rb +4 -8
- data/lib/httpx/resolver/native.rb +19 -5
- data/lib/httpx/resolver/resolver_mixin.rb +2 -1
- data/lib/httpx/resolver/system.rb +2 -0
- data/lib/httpx/resolver.rb +2 -2
- data/lib/httpx/response.rb +91 -48
- data/lib/httpx/selector.rb +11 -24
- data/lib/httpx/session.rb +41 -23
- data/lib/httpx/session2.rb +23 -0
- data/lib/httpx/timers.rb +84 -0
- data/lib/httpx/transcoder/body.rb +3 -2
- data/lib/httpx/transcoder/chunker.rb +2 -1
- data/lib/httpx/transcoder/form.rb +20 -0
- data/lib/httpx/transcoder/json.rb +12 -0
- data/lib/httpx/transcoder.rb +62 -1
- data/lib/httpx/utils.rb +10 -2
- data/lib/httpx/version.rb +1 -1
- data/lib/httpx.rb +7 -3
- data/sig/buffer.rbs +3 -1
- data/sig/chainable.rbs +31 -29
- data/sig/connection/http1.rbs +11 -5
- data/sig/connection/http2.rbs +16 -5
- data/sig/connection.rbs +31 -13
- data/sig/errors.rbs +35 -1
- data/sig/headers.rbs +20 -19
- data/sig/httpx.rbs +4 -1
- data/sig/loggable.rbs +3 -1
- data/sig/options.rbs +45 -34
- data/sig/parser/http1.rbs +3 -3
- data/sig/plugins/authentication.rbs +1 -1
- data/sig/plugins/aws_sdk_authentication.rbs +25 -3
- data/sig/plugins/aws_sigv4.rbs +13 -5
- data/sig/plugins/basic_authentication.rbs +1 -1
- data/sig/plugins/compression.rbs +4 -6
- data/sig/plugins/cookies/cookie.rbs +5 -7
- data/sig/plugins/cookies/jar.rbs +9 -10
- data/sig/plugins/cookies.rbs +4 -5
- 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 +64 -10
- data/sig/plugins/ntlm_authentication.rbs +2 -3
- data/sig/plugins/persistent.rbs +3 -8
- data/sig/plugins/proxy/ssh.rbs +4 -4
- data/sig/plugins/proxy.rbs +13 -13
- data/sig/plugins/push_promise.rbs +0 -2
- data/sig/plugins/response_cache.rbs +35 -0
- data/sig/plugins/retries.rbs +7 -8
- data/sig/plugins/stream.rbs +1 -1
- data/sig/plugins/upgrade.rbs +2 -3
- data/sig/pool.rbs +7 -2
- data/sig/registry.rbs +1 -1
- data/sig/request.rbs +11 -8
- data/sig/resolver/native.rbs +10 -5
- data/sig/resolver/resolver_mixin.rbs +4 -5
- data/sig/resolver/system.rbs +4 -0
- data/sig/resolver.rbs +7 -0
- data/sig/response.rbs +26 -13
- data/sig/selector.rbs +11 -9
- data/sig/session.rbs +22 -23
- data/sig/timers.rbs +32 -0
- data/sig/transcoder/body.rbs +6 -1
- data/sig/transcoder/chunker.rbs +8 -2
- data/sig/transcoder/form.rbs +3 -1
- data/sig/transcoder/json.rbs +2 -0
- data/sig/transcoder.rbs +13 -5
- data/sig/utils.rbs +6 -0
- metadata +18 -18
- data/lib/httpx/request2.rb +0 -14
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]
|
73
|
-
@
|
72
|
+
@keep_alive_timeout = @options.timeout[:keep_alive_timeout]
|
73
|
+
@total_timeout = @options.timeout[:total_timeout]
|
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
|
@@ -200,11 +200,9 @@ module HTTPX
|
|
200
200
|
end
|
201
201
|
|
202
202
|
def close
|
203
|
-
|
204
|
-
return unless @keep_alive_timer
|
203
|
+
transition(:active) if @state == :inactive
|
205
204
|
|
206
|
-
@
|
207
|
-
remove_instance_variable(:@keep_alive_timer)
|
205
|
+
@parser.close if @parser
|
208
206
|
end
|
209
207
|
|
210
208
|
def reset
|
@@ -216,26 +214,40 @@ module HTTPX
|
|
216
214
|
def send(request)
|
217
215
|
if @parser && !@write_buffer.full?
|
218
216
|
request.headers["alt-used"] = @origin.authority if match_altsvcs?(request.uri)
|
219
|
-
|
217
|
+
|
218
|
+
if @response_received_at && @keep_alive_timeout &&
|
219
|
+
Utils.elapsed_time(@response_received_at) > @keep_alive_timeout
|
220
220
|
# when pushing a request into an existing connection, we have to check whether there
|
221
221
|
# is the possibility that the connection might have extended the keep alive timeout.
|
222
222
|
# for such cases, we want to ping for availability before deciding to shovel requests.
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
end
|
228
|
-
|
229
|
-
@keep_alive_timer.pause
|
223
|
+
@pending << request
|
224
|
+
parser.ping
|
225
|
+
transition(:active) if @state == :inactive
|
226
|
+
return
|
230
227
|
end
|
231
|
-
|
232
|
-
|
228
|
+
|
229
|
+
send_request_to_parser(request)
|
233
230
|
else
|
234
231
|
@pending << request
|
235
232
|
end
|
236
233
|
end
|
237
234
|
|
238
235
|
def timeout
|
236
|
+
if @total_timeout
|
237
|
+
return @total_timeout unless @connected_at
|
238
|
+
|
239
|
+
elapsed_time = @total_timeout - Utils.elapsed_time(@connected_at)
|
240
|
+
|
241
|
+
if elapsed_time.negative?
|
242
|
+
ex = TotalTimeoutError.new(@total_timeout, "Timed out after #{@total_timeout} seconds")
|
243
|
+
ex.set_backtrace(caller)
|
244
|
+
on_error(@total_timeout)
|
245
|
+
return
|
246
|
+
end
|
247
|
+
|
248
|
+
return elapsed_time
|
249
|
+
end
|
250
|
+
|
239
251
|
return @timeout if defined?(@timeout)
|
240
252
|
|
241
253
|
return @options.timeout[:connect_timeout] if @state == :idle
|
@@ -243,6 +255,14 @@ module HTTPX
|
|
243
255
|
@options.timeout[:operation_timeout]
|
244
256
|
end
|
245
257
|
|
258
|
+
def deactivate
|
259
|
+
transition(:inactive)
|
260
|
+
end
|
261
|
+
|
262
|
+
def open?
|
263
|
+
@state == :open || @state == :inactive
|
264
|
+
end
|
265
|
+
|
246
266
|
private
|
247
267
|
|
248
268
|
def connect
|
@@ -313,7 +333,7 @@ module HTTPX
|
|
313
333
|
|
314
334
|
# exit #consume altogether if all outstanding requests have been dealt with
|
315
335
|
return if @pending.size.zero? && @inflight.zero?
|
316
|
-
end unless (interests.nil? ||
|
336
|
+
end unless ((ints = interests).nil? || ints == :w || @state == :closing) && !epiped
|
317
337
|
|
318
338
|
#
|
319
339
|
# tight write loop.
|
@@ -360,19 +380,18 @@ module HTTPX
|
|
360
380
|
break if interests == :r || @state == :closing || @state == :closed
|
361
381
|
|
362
382
|
write_drained = false
|
363
|
-
end unless interests == :r
|
383
|
+
end unless (ints = interests) == :r
|
364
384
|
|
365
385
|
send_pending if @state == :open
|
366
386
|
|
367
387
|
# return if socket is drained
|
368
|
-
next unless (
|
369
|
-
(interests != :w || write_drained)
|
388
|
+
next unless (ints != :r || read_drained) && (ints != :w || write_drained)
|
370
389
|
|
371
390
|
# gotta go back to the event loop. It happens when:
|
372
391
|
#
|
373
392
|
# * the socket is drained of bytes or it's not the interest of the conn to read;
|
374
393
|
# * theres nothing more to write, or it's not in the interest of the conn to write;
|
375
|
-
log(level: 3) { "(#{
|
394
|
+
log(level: 3) { "(#{ints}): WAITING FOR EVENTS..." }
|
376
395
|
return
|
377
396
|
end
|
378
397
|
end
|
@@ -380,9 +399,7 @@ module HTTPX
|
|
380
399
|
|
381
400
|
def send_pending
|
382
401
|
while !@write_buffer.full? && (request = @pending.shift)
|
383
|
-
|
384
|
-
@keep_alive_timer.pause if @keep_alive_timer
|
385
|
-
parser.send(request)
|
402
|
+
send_request_to_parser(request)
|
386
403
|
end
|
387
404
|
end
|
388
405
|
|
@@ -390,6 +407,15 @@ module HTTPX
|
|
390
407
|
@parser ||= build_parser
|
391
408
|
end
|
392
409
|
|
410
|
+
def send_request_to_parser(request)
|
411
|
+
@inflight += 1
|
412
|
+
parser.send(request)
|
413
|
+
|
414
|
+
return unless @state == :inactive
|
415
|
+
|
416
|
+
transition(:active)
|
417
|
+
end
|
418
|
+
|
393
419
|
def build_parser(protocol = @io.protocol)
|
394
420
|
parser = registry(protocol).new(@write_buffer, @options)
|
395
421
|
set_parser_callbacks(parser)
|
@@ -401,7 +427,8 @@ module HTTPX
|
|
401
427
|
AltSvc.emit(request, response) do |alt_origin, origin, alt_params|
|
402
428
|
emit(:altsvc, alt_origin, origin, alt_params)
|
403
429
|
end
|
404
|
-
|
430
|
+
@response_received_at = Utils.now
|
431
|
+
@inflight -= 1
|
405
432
|
request.emit(:response, response)
|
406
433
|
end
|
407
434
|
parser.on(:altsvc) do |alt_origin, origin, alt_params|
|
@@ -421,7 +448,7 @@ module HTTPX
|
|
421
448
|
end
|
422
449
|
parser.on(:close) do |force|
|
423
450
|
transition(:closing)
|
424
|
-
if force
|
451
|
+
if force || @state == :idle
|
425
452
|
transition(:closed)
|
426
453
|
emit(:close)
|
427
454
|
end
|
@@ -467,15 +494,17 @@ module HTTPX
|
|
467
494
|
when :open
|
468
495
|
return if @state == :closed
|
469
496
|
|
470
|
-
total_timeout
|
471
|
-
|
472
497
|
@io.connect
|
473
498
|
return unless @io.connected?
|
474
499
|
|
500
|
+
@connected_at = Utils.now
|
501
|
+
|
475
502
|
send_pending
|
476
503
|
|
477
504
|
@timeout = @current_timeout = parser.timeout
|
478
505
|
emit(:open)
|
506
|
+
when :inactive
|
507
|
+
return unless @state == :open
|
479
508
|
when :closing
|
480
509
|
return unless @state == :open
|
481
510
|
|
@@ -483,15 +512,15 @@ module HTTPX
|
|
483
512
|
return unless @state == :closing
|
484
513
|
return unless @write_buffer.empty?
|
485
514
|
|
486
|
-
if @total_timeout
|
487
|
-
@total_timeout.cancel
|
488
|
-
remove_instance_variable(:@total_timeout)
|
489
|
-
end
|
490
|
-
|
491
515
|
purge_after_closed
|
492
516
|
when :already_open
|
493
517
|
nextstate = :open
|
494
518
|
send_pending
|
519
|
+
when :active
|
520
|
+
return unless @state == :inactive
|
521
|
+
|
522
|
+
nextstate = :open
|
523
|
+
emit(:activate)
|
495
524
|
end
|
496
525
|
@state = nextstate
|
497
526
|
rescue Errno::ECONNREFUSED,
|
@@ -507,44 +536,24 @@ module HTTPX
|
|
507
536
|
def purge_after_closed
|
508
537
|
@io.close if @io
|
509
538
|
@read_buffer.clear
|
510
|
-
if @keep_alive_timer
|
511
|
-
@keep_alive_timer.cancel
|
512
|
-
remove_instance_variable(:@keep_alive_timer)
|
513
|
-
end
|
514
|
-
|
515
539
|
remove_instance_variable(:@timeout) if defined?(@timeout)
|
516
540
|
end
|
517
541
|
|
518
|
-
def handle_response
|
519
|
-
@inflight -= 1
|
520
|
-
return unless @inflight.zero?
|
521
|
-
|
522
|
-
if @keep_alive_timer
|
523
|
-
@keep_alive_timer.resume
|
524
|
-
@keep_alive_timer.reset
|
525
|
-
else
|
526
|
-
@keep_alive_timer = @timers.after(@keep_alive_timeout) do
|
527
|
-
unless @inflight.zero?
|
528
|
-
log { "(#{@origin}): keep alive timeout expired" }
|
529
|
-
parser.ping
|
530
|
-
end
|
531
|
-
end
|
532
|
-
end
|
533
|
-
end
|
534
|
-
|
535
542
|
def on_error(error)
|
536
543
|
if error.instance_of?(TimeoutError)
|
537
|
-
if @timeout
|
538
|
-
@timeout -= error.timeout
|
539
|
-
return unless @timeout <= 0
|
540
|
-
end
|
541
544
|
|
542
|
-
if @total_timeout && @
|
543
|
-
|
545
|
+
if @total_timeout && @connected_at &&
|
546
|
+
Utils.elapsed_time(@connected_at) > @total_timeout
|
547
|
+
ex = TotalTimeoutError.new(@total_timeout, "Timed out after #{@total_timeout} seconds")
|
544
548
|
ex.set_backtrace(error.backtrace)
|
545
549
|
error = ex
|
546
|
-
|
547
|
-
|
550
|
+
else
|
551
|
+
if @timeout
|
552
|
+
@timeout -= error.timeout
|
553
|
+
return unless @timeout <= 0
|
554
|
+
end
|
555
|
+
|
556
|
+
error = error.to_connection_error if connecting?
|
548
557
|
end
|
549
558
|
end
|
550
559
|
handle_error(error)
|
@@ -559,18 +568,5 @@ module HTTPX
|
|
559
568
|
request.emit(:response, response)
|
560
569
|
end
|
561
570
|
end
|
562
|
-
|
563
|
-
def total_timeout
|
564
|
-
total = @options.timeout[:total_timeout]
|
565
|
-
|
566
|
-
return unless total
|
567
|
-
|
568
|
-
@total_timeout ||= @timers.after(total) do
|
569
|
-
ex = TotalTimeoutError.new(total, "Timed out after #{total} seconds")
|
570
|
-
ex.set_backtrace(caller)
|
571
|
-
on_error(ex)
|
572
|
-
@parser.close if @parser
|
573
|
-
end
|
574
|
-
end
|
575
571
|
end
|
576
572
|
end
|
data/lib/httpx/domain_name.rb
CHANGED
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/extensions.rb
CHANGED
@@ -54,6 +54,51 @@ module HTTPX
|
|
54
54
|
Numeric.__send__(:include, NegMethods)
|
55
55
|
end
|
56
56
|
|
57
|
+
module HashExtensions
|
58
|
+
refine Hash do
|
59
|
+
def compact
|
60
|
+
h = {}
|
61
|
+
each do |key, value|
|
62
|
+
h[key] = value unless value == nil
|
63
|
+
end
|
64
|
+
h
|
65
|
+
end unless Hash.method_defined?(:compact)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
module ArrayExtensions
|
70
|
+
refine Array do
|
71
|
+
|
72
|
+
def filter_map
|
73
|
+
return to_enum(:filter_map) unless block_given?
|
74
|
+
|
75
|
+
each_with_object([]) do |item, res|
|
76
|
+
processed = yield(item)
|
77
|
+
res << processed if processed
|
78
|
+
end
|
79
|
+
end unless Array.method_defined?(:filter_map)
|
80
|
+
|
81
|
+
def sum(accumulator = 0, &block)
|
82
|
+
values = block_given? ? map(&block) : self
|
83
|
+
values.inject(accumulator, :+)
|
84
|
+
end unless Array.method_defined?(:sum)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
module IOExtensions
|
89
|
+
refine IO do
|
90
|
+
# provides a fallback for rubies where IO#wait isn't implemented,
|
91
|
+
# but IO#wait_readable and IO#wait_writable are.
|
92
|
+
def wait(timeout = nil, _mode = :read_write)
|
93
|
+
r, w = IO.select([self], [self], nil, timeout)
|
94
|
+
|
95
|
+
return unless r || w
|
96
|
+
|
97
|
+
self
|
98
|
+
end unless IO.method_defined?(:wait) && IO.instance_method(:wait).arity == 2
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
57
102
|
module RegexpExtensions
|
58
103
|
# If you wonder why this is there: the oauth feature uses a refinement to enhance the
|
59
104
|
# Regexp class locally with #match? , but this is never tested, because ActiveSupport
|
@@ -77,13 +122,14 @@ module HTTPX
|
|
77
122
|
end
|
78
123
|
|
79
124
|
def authority
|
80
|
-
|
81
|
-
|
82
|
-
|
125
|
+
return host if port == default_port
|
126
|
+
|
127
|
+
"#{host}:#{port}"
|
128
|
+
end unless URI::HTTP.method_defined?(:authority)
|
83
129
|
|
84
130
|
def origin
|
85
131
|
"#{scheme}://#{authority}"
|
86
|
-
end
|
132
|
+
end unless URI::HTTP.method_defined?(:origin)
|
87
133
|
|
88
134
|
def altsvc_match?(uri)
|
89
135
|
uri = URI.parse(uri)
|
data/lib/httpx/headers.rb
CHANGED
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)
|
@@ -134,7 +134,7 @@ module HTTPX
|
|
134
134
|
server_cert = @io.peer_cert
|
135
135
|
|
136
136
|
"#{super}\n\n" \
|
137
|
-
|
137
|
+
"SSL connection using #{@io.ssl_version} / #{Array(@io.cipher).first}\n" \
|
138
138
|
"ALPN, server accepted to use #{protocol}\n" \
|
139
139
|
"Server certificate:\n" \
|
140
140
|
" subject: #{server_cert.subject}\n" \
|
data/lib/httpx/io/tls.rb
CHANGED
@@ -4,7 +4,7 @@ require "openssl"
|
|
4
4
|
|
5
5
|
module HTTPX
|
6
6
|
class TLS < TCP
|
7
|
-
Error
|
7
|
+
class Error < StandardError; end
|
8
8
|
|
9
9
|
def initialize(_, _, options)
|
10
10
|
super
|
@@ -194,15 +194,15 @@ module HTTPX
|
|
194
194
|
server_cert = @peer_cert
|
195
195
|
|
196
196
|
"#{super}\n\n" \
|
197
|
-
|
198
|
-
|
197
|
+
"SSL connection using #{@ctx.ssl_version} / #{Array(@ctx.cipher).first}\n" \
|
198
|
+
"ALPN, server accepted to use #{protocol}\n" +
|
199
199
|
(if server_cert
|
200
200
|
"Server certificate:\n" \
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
201
|
+
" subject: #{server_cert.subject}\n" \
|
202
|
+
" start date: #{server_cert.not_before}\n" \
|
203
|
+
" expire date: #{server_cert.not_after}\n" \
|
204
|
+
" issuer: #{server_cert.issuer}\n" \
|
205
|
+
" SSL certificate verify ok."
|
206
206
|
else
|
207
207
|
"SSL certificate verify failed."
|
208
208
|
end
|
data/lib/httpx/loggable.rb
CHANGED
@@ -24,15 +24,13 @@ module HTTPX
|
|
24
24
|
debug_stream << message
|
25
25
|
end
|
26
26
|
|
27
|
-
if
|
27
|
+
if Exception.instance_methods.include?(:full_message)
|
28
28
|
|
29
29
|
def log_exception(ex, level: @options.debug_level, color: nil)
|
30
30
|
return unless @options.debug
|
31
31
|
return unless @options.debug_level >= level
|
32
32
|
|
33
|
-
|
34
|
-
message << "\n" << ex.backtrace.join("\n") unless ex.backtrace.nil?
|
35
|
-
log(level: level, color: color) { message }
|
33
|
+
log(level: level, color: color) { ex.full_message }
|
36
34
|
end
|
37
35
|
|
38
36
|
else
|
@@ -41,7 +39,9 @@ module HTTPX
|
|
41
39
|
return unless @options.debug
|
42
40
|
return unless @options.debug_level >= level
|
43
41
|
|
44
|
-
|
42
|
+
message = +"#{ex.message} (#{ex.class})"
|
43
|
+
message << "\n" << ex.backtrace.join("\n") unless ex.backtrace.nil?
|
44
|
+
log(level: level, color: color) { message }
|
45
45
|
end
|
46
46
|
|
47
47
|
end
|