httpx 0.24.5 → 1.0.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/LICENSE.txt +0 -48
- data/README.md +4 -13
- data/doc/release_notes/0_24_4.md +3 -3
- data/doc/release_notes/0_24_6.md +5 -0
- data/doc/release_notes/1_0_0.md +60 -0
- data/lib/httpx/adapters/datadog.rb +28 -97
- data/lib/httpx/adapters/faraday.rb +9 -52
- data/lib/httpx/adapters/webmock.rb +2 -7
- data/lib/httpx/altsvc.rb +4 -22
- data/lib/httpx/base64.rb +27 -0
- data/lib/httpx/chainable.rb +2 -25
- data/lib/httpx/connection.rb +11 -32
- data/lib/httpx/domain_name.rb +5 -12
- data/lib/httpx/errors.rb +0 -2
- data/lib/httpx/extensions.rb +0 -124
- data/lib/httpx/io/ssl.rb +26 -59
- data/lib/httpx/io/tcp.rb +27 -68
- data/lib/httpx/io/udp.rb +13 -48
- data/lib/httpx/io/unix.rb +1 -8
- data/lib/httpx/loggable.rb +4 -19
- data/lib/httpx/options.rb +24 -84
- data/lib/httpx/plugins/{authentication → auth}/basic.rb +1 -5
- data/lib/httpx/plugins/{authentication → auth}/digest.rb +2 -5
- data/lib/httpx/plugins/{authentication → auth}/ntlm.rb +1 -3
- data/lib/httpx/plugins/{authentication → auth}/socks5.rb +0 -2
- data/lib/httpx/plugins/auth.rb +25 -0
- data/lib/httpx/plugins/aws_sigv4.rb +0 -1
- data/lib/httpx/plugins/{basic_authentication.rb → basic_auth.rb} +5 -6
- data/lib/httpx/plugins/brotli.rb +50 -0
- data/lib/httpx/plugins/circuit_breaker/circuit.rb +40 -16
- data/lib/httpx/plugins/circuit_breaker/circuit_store.rb +16 -5
- data/lib/httpx/plugins/circuit_breaker.rb +11 -4
- data/lib/httpx/plugins/cookies/set_cookie_parser.rb +0 -2
- data/lib/httpx/plugins/cookies.rb +1 -1
- data/lib/httpx/plugins/{digest_authentication.rb → digest_auth.rb} +5 -5
- data/lib/httpx/plugins/follow_redirects.rb +21 -24
- data/lib/httpx/plugins/grpc/grpc_encoding.rb +82 -0
- data/lib/httpx/plugins/grpc/message.rb +7 -39
- data/lib/httpx/plugins/grpc.rb +15 -21
- data/lib/httpx/plugins/h2c.rb +0 -1
- data/lib/httpx/plugins/{ntlm_authentication.rb → ntlm_auth.rb} +5 -5
- data/lib/httpx/plugins/oauth.rb +2 -2
- data/lib/httpx/plugins/proxy/http.rb +0 -2
- data/lib/httpx/plugins/proxy/socks4.rb +0 -4
- data/lib/httpx/plugins/proxy/socks5.rb +1 -5
- data/lib/httpx/plugins/proxy.rb +3 -32
- data/lib/httpx/plugins/retries.rb +3 -4
- data/lib/httpx/plugins/stream.rb +4 -6
- data/lib/httpx/punycode.rb +9 -291
- data/lib/httpx/request/body.rb +145 -0
- data/lib/httpx/request.rb +2 -119
- data/lib/httpx/resolver/https.rb +1 -1
- data/lib/httpx/resolver/native.rb +6 -14
- data/lib/httpx/resolver/resolver.rb +1 -1
- data/lib/httpx/resolver/system.rb +11 -9
- data/lib/httpx/response/body.rb +206 -0
- data/lib/httpx/response/buffer.rb +90 -0
- data/lib/httpx/response.rb +5 -208
- data/lib/httpx/selector.rb +0 -2
- data/lib/httpx/session.rb +3 -10
- data/lib/httpx/transcoder/body.rb +0 -1
- data/lib/httpx/transcoder/deflate.rb +37 -0
- data/lib/httpx/transcoder/form.rb +52 -32
- data/lib/httpx/transcoder/gzip.rb +74 -0
- data/lib/httpx/transcoder/json.rb +2 -4
- data/lib/httpx/transcoder/multipart/decoder.rb +139 -0
- data/lib/httpx/{plugins → transcoder}/multipart/encoder.rb +3 -3
- data/lib/httpx/{plugins → transcoder}/multipart/mime_type_detector.rb +1 -1
- data/lib/httpx/{plugins → transcoder}/multipart/part.rb +3 -2
- data/lib/httpx/transcoder/multipart.rb +17 -0
- data/lib/httpx/transcoder/utils/body_reader.rb +46 -0
- data/lib/httpx/transcoder/utils/deflater.rb +72 -0
- data/lib/httpx/transcoder/xml.rb +0 -2
- data/lib/httpx/transcoder.rb +2 -2
- data/lib/httpx/utils.rb +10 -20
- data/lib/httpx/version.rb +1 -1
- data/lib/httpx.rb +0 -8
- data/sig/chainable.rbs +5 -6
- data/sig/connection.rbs +0 -1
- data/sig/errors.rbs +0 -3
- data/sig/httpx.rbs +2 -1
- data/sig/io/unix.rbs +1 -1
- data/sig/options.rbs +12 -8
- data/sig/plugins/{authentication → auth}/basic.rbs +0 -2
- data/sig/plugins/auth.rbs +13 -0
- data/sig/plugins/{basic_authentication.rbs → basic_auth.rbs} +2 -2
- data/sig/plugins/brotli.rbs +22 -0
- data/sig/plugins/circuit_breaker.rbs +7 -3
- data/sig/plugins/compression.rbs +0 -2
- data/sig/plugins/{digest_authentication.rbs → digest_auth.rbs} +2 -2
- data/sig/plugins/follow_redirects.rbs +0 -1
- data/sig/plugins/grpc/call.rbs +19 -0
- data/sig/plugins/grpc/grpc_encoding.rbs +33 -0
- data/sig/plugins/grpc/message.rbs +17 -0
- data/sig/plugins/grpc.rbs +2 -32
- data/sig/plugins/{ntlm_authentication.rbs → ntlm_auth.rbs} +2 -2
- data/sig/plugins/oauth.rbs +1 -1
- data/sig/plugins/proxy/socks4.rbs +2 -3
- data/sig/plugins/proxy/socks5.rbs +0 -1
- data/sig/plugins/proxy/ssh.rbs +1 -1
- data/sig/plugins/response_cache.rbs +5 -2
- data/sig/request/body.rbs +42 -0
- data/sig/request.rbs +1 -27
- data/sig/resolver/resolver.rbs +1 -1
- data/sig/response/body.rbs +52 -0
- data/sig/response/buffer.rbs +24 -0
- data/sig/response.rbs +0 -39
- data/sig/session.rbs +2 -0
- data/sig/transcoder/body.rbs +4 -3
- data/sig/transcoder/deflate.rbs +11 -0
- data/sig/transcoder/form.rbs +5 -3
- data/sig/transcoder/gzip.rbs +24 -0
- data/sig/transcoder/json.rbs +4 -2
- data/sig/{plugins → transcoder}/multipart.rbs +3 -10
- data/sig/transcoder/utils/body_reader.rbs +15 -0
- data/sig/transcoder/utils/deflater.rbs +29 -0
- data/sig/transcoder.rbs +18 -2
- metadata +52 -34
- data/lib/httpx/plugins/authentication.rb +0 -24
- data/lib/httpx/plugins/compression/brotli.rb +0 -54
- data/lib/httpx/plugins/compression/deflate.rb +0 -54
- data/lib/httpx/plugins/compression/gzip.rb +0 -90
- data/lib/httpx/plugins/compression.rb +0 -165
- data/lib/httpx/plugins/multipart/decoder.rb +0 -137
- data/lib/httpx/plugins/multipart.rb +0 -96
- data/sig/plugins/authentication.rbs +0 -13
- data/sig/plugins/compression/brotli.rbs +0 -21
- data/sig/plugins/compression/deflate.rbs +0 -17
- data/sig/plugins/compression/gzip.rbs +0 -29
- /data/sig/plugins/{authentication → auth}/digest.rbs +0 -0
- /data/sig/plugins/{authentication → auth}/ntlm.rbs +0 -0
- /data/sig/plugins/{authentication → auth}/socks5.rbs +0 -0
data/lib/httpx/connection.rb
CHANGED
|
@@ -33,7 +33,6 @@ module HTTPX
|
|
|
33
33
|
include Callbacks
|
|
34
34
|
|
|
35
35
|
using URIExtensions
|
|
36
|
-
using NumericExtensions
|
|
37
36
|
|
|
38
37
|
require "httpx/connection/http2"
|
|
39
38
|
require "httpx/connection/http1"
|
|
@@ -70,7 +69,6 @@ module HTTPX
|
|
|
70
69
|
|
|
71
70
|
@inflight = 0
|
|
72
71
|
@keep_alive_timeout = @options.timeout[:keep_alive_timeout]
|
|
73
|
-
@total_timeout = @options.timeout[:total_timeout]
|
|
74
72
|
|
|
75
73
|
self.addresses = @options.addresses if @options.addresses
|
|
76
74
|
end
|
|
@@ -270,21 +268,6 @@ module HTTPX
|
|
|
270
268
|
end
|
|
271
269
|
|
|
272
270
|
def timeout
|
|
273
|
-
if @total_timeout
|
|
274
|
-
return @total_timeout unless @connected_at
|
|
275
|
-
|
|
276
|
-
elapsed_time = @total_timeout - Utils.elapsed_time(@connected_at)
|
|
277
|
-
|
|
278
|
-
if elapsed_time.negative?
|
|
279
|
-
ex = TotalTimeoutError.new(@total_timeout, "Timed out after #{@total_timeout} seconds")
|
|
280
|
-
ex.set_backtrace(caller)
|
|
281
|
-
on_error(ex)
|
|
282
|
-
return
|
|
283
|
-
end
|
|
284
|
-
|
|
285
|
-
return elapsed_time
|
|
286
|
-
end
|
|
287
|
-
|
|
288
271
|
return @timeout if defined?(@timeout)
|
|
289
272
|
|
|
290
273
|
return @options.timeout[:connect_timeout] if @state == :idle
|
|
@@ -604,6 +587,9 @@ module HTTPX
|
|
|
604
587
|
purge_after_closed
|
|
605
588
|
when :already_open
|
|
606
589
|
nextstate = :open
|
|
590
|
+
# the first check for given io readiness must still use a timeout.
|
|
591
|
+
# connect is the reasonable choice in such a case.
|
|
592
|
+
@timeout = @options.timeout[:connect_timeout]
|
|
607
593
|
send_pending
|
|
608
594
|
when :active
|
|
609
595
|
return unless @state == :inactive
|
|
@@ -643,23 +629,16 @@ module HTTPX
|
|
|
643
629
|
def on_error(error)
|
|
644
630
|
if error.instance_of?(TimeoutError)
|
|
645
631
|
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
ex.set_backtrace(error.backtrace)
|
|
650
|
-
error = ex
|
|
651
|
-
else
|
|
652
|
-
# inactive connections do not contribute to the select loop, therefore
|
|
653
|
-
# they should not fail due to such errors.
|
|
654
|
-
return if @state == :inactive
|
|
632
|
+
# inactive connections do not contribute to the select loop, therefore
|
|
633
|
+
# they should not fail due to such errors.
|
|
634
|
+
return if @state == :inactive
|
|
655
635
|
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
end
|
|
660
|
-
|
|
661
|
-
error = error.to_connection_error if connecting?
|
|
636
|
+
if @timeout
|
|
637
|
+
@timeout -= error.timeout
|
|
638
|
+
return unless @timeout <= 0
|
|
662
639
|
end
|
|
640
|
+
|
|
641
|
+
error = error.to_connection_error if connecting?
|
|
663
642
|
end
|
|
664
643
|
handle_error(error)
|
|
665
644
|
reset
|
data/lib/httpx/domain_name.rb
CHANGED
|
@@ -51,8 +51,6 @@ module HTTPX
|
|
|
51
51
|
# non-canonical domain.
|
|
52
52
|
attr_reader :domain
|
|
53
53
|
|
|
54
|
-
DOT = "." # :nodoc:
|
|
55
|
-
|
|
56
54
|
class << self
|
|
57
55
|
def new(domain)
|
|
58
56
|
return domain if domain.is_a?(self)
|
|
@@ -63,7 +61,7 @@ module HTTPX
|
|
|
63
61
|
# Normalizes a _domain_ using the Punycode algorithm as necessary.
|
|
64
62
|
# The result will be a downcased, ASCII-only string.
|
|
65
63
|
def normalize(domain)
|
|
66
|
-
domain = domain.chomp(
|
|
64
|
+
domain = domain.chomp(".").unicode_normalize(:nfc) unless domain.ascii_only?
|
|
67
65
|
Punycode.encode_hostname(domain).downcase
|
|
68
66
|
end
|
|
69
67
|
end
|
|
@@ -73,7 +71,7 @@ module HTTPX
|
|
|
73
71
|
def initialize(hostname)
|
|
74
72
|
hostname = String(hostname)
|
|
75
73
|
|
|
76
|
-
raise ArgumentError, "domain name must not start with a dot: #{hostname}" if hostname.start_with?(
|
|
74
|
+
raise ArgumentError, "domain name must not start with a dot: #{hostname}" if hostname.start_with?(".")
|
|
77
75
|
|
|
78
76
|
begin
|
|
79
77
|
@ipaddr = IPAddr.new(hostname)
|
|
@@ -84,7 +82,7 @@ module HTTPX
|
|
|
84
82
|
end
|
|
85
83
|
|
|
86
84
|
@hostname = DomainName.normalize(hostname)
|
|
87
|
-
tld = if (last_dot = @hostname.rindex(
|
|
85
|
+
tld = if (last_dot = @hostname.rindex("."))
|
|
88
86
|
@hostname[(last_dot + 1)..-1]
|
|
89
87
|
else
|
|
90
88
|
@hostname
|
|
@@ -94,7 +92,7 @@ module HTTPX
|
|
|
94
92
|
@domain = if last_dot
|
|
95
93
|
# fallback - accept cookies down to second level
|
|
96
94
|
# cf. http://www.dkim-reputation.org/regdom-libs/
|
|
97
|
-
if (penultimate_dot = @hostname.rindex(
|
|
95
|
+
if (penultimate_dot = @hostname.rindex(".", last_dot - 1))
|
|
98
96
|
@hostname[(penultimate_dot + 1)..-1]
|
|
99
97
|
else
|
|
100
98
|
@hostname
|
|
@@ -126,17 +124,12 @@ module HTTPX
|
|
|
126
124
|
@domain && self <= domain && domain <= @domain
|
|
127
125
|
end
|
|
128
126
|
|
|
129
|
-
# def ==(other)
|
|
130
|
-
# other = DomainName.new(other)
|
|
131
|
-
# other.hostname == @hostname
|
|
132
|
-
# end
|
|
133
|
-
|
|
134
127
|
def <=>(other)
|
|
135
128
|
other = DomainName.new(other)
|
|
136
129
|
othername = other.hostname
|
|
137
130
|
if othername == @hostname
|
|
138
131
|
0
|
|
139
|
-
elsif @hostname.end_with?(othername) && @hostname[-othername.size - 1, 1] ==
|
|
132
|
+
elsif @hostname.end_with?(othername) && @hostname[-othername.size - 1, 1] == "."
|
|
140
133
|
# The other is higher
|
|
141
134
|
-1
|
|
142
135
|
else
|
data/lib/httpx/errors.rb
CHANGED
data/lib/httpx/extensions.rb
CHANGED
|
@@ -3,96 +3,6 @@
|
|
|
3
3
|
require "uri"
|
|
4
4
|
|
|
5
5
|
module HTTPX
|
|
6
|
-
unless Method.method_defined?(:curry)
|
|
7
|
-
|
|
8
|
-
# Backport
|
|
9
|
-
#
|
|
10
|
-
# Ruby 2.1 and lower implement curry only for Procs.
|
|
11
|
-
#
|
|
12
|
-
# Why not using Refinements? Because they don't work for Method (tested with ruby 2.1.9).
|
|
13
|
-
#
|
|
14
|
-
module CurryMethods
|
|
15
|
-
# Backport for the Method#curry method, which is part of ruby core since 2.2 .
|
|
16
|
-
#
|
|
17
|
-
def curry(*args)
|
|
18
|
-
to_proc.curry(*args)
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
Method.__send__(:include, CurryMethods)
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
unless String.method_defined?(:+@)
|
|
25
|
-
# Backport for +"", to initialize unfrozen strings from the string literal.
|
|
26
|
-
#
|
|
27
|
-
module LiteralStringExtensions
|
|
28
|
-
def +@
|
|
29
|
-
frozen? ? dup : self
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
String.__send__(:include, LiteralStringExtensions)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
unless Numeric.method_defined?(:positive?)
|
|
36
|
-
# Ruby 2.3 Backport (Numeric#positive?)
|
|
37
|
-
#
|
|
38
|
-
module PosMethods
|
|
39
|
-
def positive?
|
|
40
|
-
self > 0
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
Numeric.__send__(:include, PosMethods)
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
unless Numeric.method_defined?(:negative?)
|
|
47
|
-
# Ruby 2.3 Backport (Numeric#negative?)
|
|
48
|
-
#
|
|
49
|
-
module NegMethods
|
|
50
|
-
def negative?
|
|
51
|
-
self < 0
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
Numeric.__send__(:include, NegMethods)
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
module NumericExtensions
|
|
58
|
-
# Ruby 2.4 backport
|
|
59
|
-
refine Numeric do
|
|
60
|
-
def infinite?
|
|
61
|
-
self == Float::INFINITY
|
|
62
|
-
end unless Numeric.method_defined?(:infinite?)
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
module StringExtensions
|
|
67
|
-
refine String do
|
|
68
|
-
# Ruby 2.5 backport
|
|
69
|
-
def delete_suffix!(suffix)
|
|
70
|
-
suffix = Backports.coerce_to_str(suffix)
|
|
71
|
-
chomp! if frozen?
|
|
72
|
-
len = suffix.length
|
|
73
|
-
if len > 0 && index(suffix, -len)
|
|
74
|
-
self[-len..-1] = ''
|
|
75
|
-
self
|
|
76
|
-
else
|
|
77
|
-
nil
|
|
78
|
-
end
|
|
79
|
-
end unless String.method_defined?(:delete_suffix!)
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
module HashExtensions
|
|
84
|
-
refine Hash do
|
|
85
|
-
# Ruby 2.4 backport
|
|
86
|
-
def compact
|
|
87
|
-
h = {}
|
|
88
|
-
each do |key, value|
|
|
89
|
-
h[key] = value unless value == nil
|
|
90
|
-
end
|
|
91
|
-
h
|
|
92
|
-
end unless Hash.method_defined?(:compact)
|
|
93
|
-
end
|
|
94
|
-
end
|
|
95
|
-
|
|
96
6
|
module ArrayExtensions
|
|
97
7
|
module FilterMap
|
|
98
8
|
refine Array do
|
|
@@ -108,16 +18,6 @@ module HTTPX
|
|
|
108
18
|
end unless Array.method_defined?(:filter_map)
|
|
109
19
|
end
|
|
110
20
|
|
|
111
|
-
module Sum
|
|
112
|
-
refine Array do
|
|
113
|
-
# Ruby 2.6 backport
|
|
114
|
-
def sum(accumulator = 0, &block)
|
|
115
|
-
values = block_given? ? map(&block) : self
|
|
116
|
-
values.inject(accumulator, :+)
|
|
117
|
-
end
|
|
118
|
-
end unless Array.method_defined?(:sum)
|
|
119
|
-
end
|
|
120
|
-
|
|
121
21
|
module Intersect
|
|
122
22
|
refine Array do
|
|
123
23
|
# Ruby 3.1 backport
|
|
@@ -133,30 +33,6 @@ module HTTPX
|
|
|
133
33
|
end
|
|
134
34
|
end
|
|
135
35
|
|
|
136
|
-
module IOExtensions
|
|
137
|
-
refine IO do
|
|
138
|
-
# Ruby 2.3 backport
|
|
139
|
-
# provides a fallback for rubies where IO#wait isn't implemented,
|
|
140
|
-
# but IO#wait_readable and IO#wait_writable are.
|
|
141
|
-
def wait(timeout = nil, _mode = :read_write)
|
|
142
|
-
r, w = IO.select([self], [self], nil, timeout)
|
|
143
|
-
|
|
144
|
-
return unless r || w
|
|
145
|
-
|
|
146
|
-
self
|
|
147
|
-
end unless IO.method_defined?(:wait) && IO.instance_method(:wait).arity == 2
|
|
148
|
-
end
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
module RegexpExtensions
|
|
152
|
-
refine(Regexp) do
|
|
153
|
-
# Ruby 2.4 backport
|
|
154
|
-
def match?(*args)
|
|
155
|
-
!match(*args).nil?
|
|
156
|
-
end
|
|
157
|
-
end
|
|
158
|
-
end
|
|
159
|
-
|
|
160
36
|
module URIExtensions
|
|
161
37
|
# uri 0.11 backport, ships with ruby 3.1
|
|
162
38
|
refine URI::Generic do
|
data/lib/httpx/io/ssl.rb
CHANGED
|
@@ -6,15 +6,11 @@ module HTTPX
|
|
|
6
6
|
TLSError = OpenSSL::SSL::SSLError
|
|
7
7
|
|
|
8
8
|
class SSL < TCP
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
TLS_OPTIONS = if OpenSSL::SSL::SSLContext.instance_methods.include?(:alpn_protocols)
|
|
12
|
-
{ alpn_protocols: %w[h2 http/1.1].freeze }
|
|
13
|
-
else
|
|
14
|
-
{}
|
|
15
|
-
end
|
|
9
|
+
# rubocop:disable Style/MutableConstant
|
|
10
|
+
TLS_OPTIONS = { alpn_protocols: %w[h2 http/1.1].freeze }
|
|
16
11
|
# https://github.com/jruby/jruby-openssl/issues/284
|
|
17
12
|
TLS_OPTIONS[:verify_hostname] = true if RUBY_ENGINE == "jruby"
|
|
13
|
+
# rubocop:enable Style/MutableConstant
|
|
18
14
|
TLS_OPTIONS.freeze
|
|
19
15
|
|
|
20
16
|
attr_writer :ssl_session
|
|
@@ -58,6 +54,20 @@ module HTTPX
|
|
|
58
54
|
super
|
|
59
55
|
end
|
|
60
56
|
|
|
57
|
+
if RUBY_ENGINE == "jruby"
|
|
58
|
+
# in jruby, alpn_protocol may return ""
|
|
59
|
+
# https://github.com/jruby/jruby-openssl/issues/287
|
|
60
|
+
def protocol
|
|
61
|
+
proto = @io.alpn_protocol
|
|
62
|
+
|
|
63
|
+
return super if proto.nil? || proto.empty?
|
|
64
|
+
|
|
65
|
+
proto
|
|
66
|
+
rescue StandardError
|
|
67
|
+
super
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
61
71
|
def can_verify_peer?
|
|
62
72
|
@ctx.verify_mode == OpenSSL::SSL::VERIFY_PEER
|
|
63
73
|
end
|
|
@@ -103,61 +113,18 @@ module HTTPX
|
|
|
103
113
|
try_ssl_connect
|
|
104
114
|
end
|
|
105
115
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
@io.connect_nonblock
|
|
110
|
-
@io.post_connection_check(@sni_hostname) if @ctx.verify_mode != OpenSSL::SSL::VERIFY_NONE && @verify_hostname
|
|
111
|
-
transition(:negotiated)
|
|
112
|
-
@interests = :w
|
|
113
|
-
rescue ::IO::WaitReadable
|
|
116
|
+
def try_ssl_connect
|
|
117
|
+
case @io.connect_nonblock(exception: false)
|
|
118
|
+
when :wait_readable
|
|
114
119
|
@interests = :r
|
|
115
|
-
|
|
120
|
+
return
|
|
121
|
+
when :wait_writable
|
|
116
122
|
@interests = :w
|
|
123
|
+
return
|
|
117
124
|
end
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
rescue ::IO::WaitWritable
|
|
122
|
-
buffer.clear
|
|
123
|
-
0
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
def write(*)
|
|
127
|
-
super
|
|
128
|
-
rescue ::IO::WaitReadable
|
|
129
|
-
0
|
|
130
|
-
end
|
|
131
|
-
# :nocov:
|
|
132
|
-
else
|
|
133
|
-
def try_ssl_connect
|
|
134
|
-
case @io.connect_nonblock(exception: false)
|
|
135
|
-
when :wait_readable
|
|
136
|
-
@interests = :r
|
|
137
|
-
return
|
|
138
|
-
when :wait_writable
|
|
139
|
-
@interests = :w
|
|
140
|
-
return
|
|
141
|
-
end
|
|
142
|
-
@io.post_connection_check(@sni_hostname) if @ctx.verify_mode != OpenSSL::SSL::VERIFY_NONE && @verify_hostname
|
|
143
|
-
transition(:negotiated)
|
|
144
|
-
@interests = :w
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
# :nocov:
|
|
148
|
-
if OpenSSL::VERSION < "2.0.6"
|
|
149
|
-
def read(size, buffer)
|
|
150
|
-
@io.read_nonblock(size, buffer)
|
|
151
|
-
buffer.bytesize
|
|
152
|
-
rescue ::IO::WaitReadable,
|
|
153
|
-
::IO::WaitWritable
|
|
154
|
-
buffer.clear
|
|
155
|
-
0
|
|
156
|
-
rescue EOFError
|
|
157
|
-
nil
|
|
158
|
-
end
|
|
159
|
-
end
|
|
160
|
-
# :nocov:
|
|
125
|
+
@io.post_connection_check(@sni_hostname) if @ctx.verify_mode != OpenSSL::SSL::VERIFY_NONE && @verify_hostname
|
|
126
|
+
transition(:negotiated)
|
|
127
|
+
@interests = :w
|
|
161
128
|
end
|
|
162
129
|
|
|
163
130
|
private
|
data/lib/httpx/io/tcp.rb
CHANGED
|
@@ -94,84 +94,43 @@ module HTTPX
|
|
|
94
94
|
retry
|
|
95
95
|
end
|
|
96
96
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
@io.connect_nonblock(Socket.sockaddr_in(@port, @ip.to_s))
|
|
101
|
-
rescue ::IO::WaitWritable, Errno::EALREADY
|
|
102
|
-
@interests = :w
|
|
103
|
-
rescue ::IO::WaitReadable
|
|
97
|
+
def try_connect
|
|
98
|
+
case @io.connect_nonblock(Socket.sockaddr_in(@port, @ip.to_s), exception: false)
|
|
99
|
+
when :wait_readable
|
|
104
100
|
@interests = :r
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
@interests = :w
|
|
108
|
-
else
|
|
109
|
-
transition(:connected)
|
|
101
|
+
return
|
|
102
|
+
when :wait_writable
|
|
110
103
|
@interests = :w
|
|
104
|
+
return
|
|
111
105
|
end
|
|
112
|
-
|
|
106
|
+
transition(:connected)
|
|
107
|
+
@interests = :w
|
|
108
|
+
rescue Errno::EALREADY
|
|
109
|
+
@interests = :w
|
|
110
|
+
end
|
|
111
|
+
private :try_connect
|
|
113
112
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
buffer.bytesize
|
|
118
|
-
rescue ::IO::WaitReadable
|
|
113
|
+
def read(size, buffer)
|
|
114
|
+
ret = @io.read_nonblock(size, buffer, exception: false)
|
|
115
|
+
if ret == :wait_readable
|
|
119
116
|
buffer.clear
|
|
120
|
-
0
|
|
121
|
-
rescue EOFError
|
|
122
|
-
nil
|
|
117
|
+
return 0
|
|
123
118
|
end
|
|
119
|
+
return if ret.nil?
|
|
124
120
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
buffer.shift!(siz)
|
|
129
|
-
siz
|
|
130
|
-
rescue ::IO::WaitWritable
|
|
131
|
-
0
|
|
132
|
-
rescue EOFError
|
|
133
|
-
nil
|
|
134
|
-
end
|
|
135
|
-
# :nocov:
|
|
136
|
-
else
|
|
137
|
-
def try_connect
|
|
138
|
-
case @io.connect_nonblock(Socket.sockaddr_in(@port, @ip.to_s), exception: false)
|
|
139
|
-
when :wait_readable
|
|
140
|
-
@interests = :r
|
|
141
|
-
return
|
|
142
|
-
when :wait_writable
|
|
143
|
-
@interests = :w
|
|
144
|
-
return
|
|
145
|
-
end
|
|
146
|
-
transition(:connected)
|
|
147
|
-
@interests = :w
|
|
148
|
-
rescue Errno::EALREADY
|
|
149
|
-
@interests = :w
|
|
150
|
-
end
|
|
151
|
-
private :try_connect
|
|
152
|
-
|
|
153
|
-
def read(size, buffer)
|
|
154
|
-
ret = @io.read_nonblock(size, buffer, exception: false)
|
|
155
|
-
if ret == :wait_readable
|
|
156
|
-
buffer.clear
|
|
157
|
-
return 0
|
|
158
|
-
end
|
|
159
|
-
return if ret.nil?
|
|
160
|
-
|
|
161
|
-
log { "READ: #{buffer.bytesize} bytes..." }
|
|
162
|
-
buffer.bytesize
|
|
163
|
-
end
|
|
121
|
+
log { "READ: #{buffer.bytesize} bytes..." }
|
|
122
|
+
buffer.bytesize
|
|
123
|
+
end
|
|
164
124
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
125
|
+
def write(buffer)
|
|
126
|
+
siz = @io.write_nonblock(buffer, exception: false)
|
|
127
|
+
return 0 if siz == :wait_writable
|
|
128
|
+
return if siz.nil?
|
|
169
129
|
|
|
170
|
-
|
|
130
|
+
log { "WRITE: #{siz} bytes..." }
|
|
171
131
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
end
|
|
132
|
+
buffer.shift!(siz)
|
|
133
|
+
siz
|
|
175
134
|
end
|
|
176
135
|
|
|
177
136
|
def close
|
data/lib/httpx/io/udp.rb
CHANGED
|
@@ -23,45 +23,19 @@ module HTTPX
|
|
|
23
23
|
true
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
def close
|
|
29
|
-
@io.close
|
|
30
|
-
rescue StandardError
|
|
31
|
-
nil
|
|
32
|
-
end
|
|
33
|
-
# :nocov:
|
|
34
|
-
else
|
|
35
|
-
def close
|
|
36
|
-
@io.close
|
|
37
|
-
end
|
|
26
|
+
def close
|
|
27
|
+
@io.close
|
|
38
28
|
end
|
|
39
29
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
RUBY_VERSION < "2.3"
|
|
30
|
+
if RUBY_ENGINE == "jruby"
|
|
31
|
+
# In JRuby, sendmsg_nonblock is not implemented
|
|
43
32
|
def write(buffer)
|
|
44
|
-
siz = @io.
|
|
33
|
+
siz = @io.send(buffer.to_s, 0, @host, @port)
|
|
45
34
|
log { "WRITE: #{siz} bytes..." }
|
|
46
35
|
buffer.shift!(siz)
|
|
47
36
|
siz
|
|
48
|
-
rescue ::IO::WaitWritable
|
|
49
|
-
0
|
|
50
|
-
rescue EOFError
|
|
51
|
-
nil
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def read(size, buffer)
|
|
55
|
-
data, _ = @io.recvfrom_nonblock(size)
|
|
56
|
-
buffer.replace(data)
|
|
57
|
-
log { "READ: #{buffer.bytesize} bytes..." }
|
|
58
|
-
buffer.bytesize
|
|
59
|
-
rescue ::IO::WaitReadable
|
|
60
|
-
0
|
|
61
|
-
rescue IOError
|
|
62
37
|
end
|
|
63
38
|
else
|
|
64
|
-
|
|
65
39
|
def write(buffer)
|
|
66
40
|
siz = @io.sendmsg_nonblock(buffer.to_s, 0, Socket.sockaddr_in(@port, @host.to_s), exception: false)
|
|
67
41
|
return 0 if siz == :wait_writable
|
|
@@ -72,26 +46,17 @@ module HTTPX
|
|
|
72
46
|
buffer.shift!(siz)
|
|
73
47
|
siz
|
|
74
48
|
end
|
|
49
|
+
end
|
|
75
50
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
51
|
+
def read(size, buffer)
|
|
52
|
+
ret = @io.recvfrom_nonblock(size, 0, buffer, exception: false)
|
|
53
|
+
return 0 if ret == :wait_readable
|
|
54
|
+
return if ret.nil?
|
|
80
55
|
|
|
81
|
-
|
|
56
|
+
log { "READ: #{buffer.bytesize} bytes..." }
|
|
82
57
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
end
|
|
58
|
+
buffer.bytesize
|
|
59
|
+
rescue IOError
|
|
86
60
|
end
|
|
87
|
-
|
|
88
|
-
# In JRuby, sendmsg_nonblock is not implemented
|
|
89
|
-
def write(buffer)
|
|
90
|
-
siz = @io.send(buffer.to_s, 0, @host, @port)
|
|
91
|
-
log { "WRITE: #{siz} bytes..." }
|
|
92
|
-
buffer.shift!(siz)
|
|
93
|
-
siz
|
|
94
|
-
end if RUBY_ENGINE == "jruby"
|
|
95
|
-
# :nocov:
|
|
96
61
|
end
|
|
97
62
|
end
|
data/lib/httpx/io/unix.rb
CHANGED
|
@@ -27,14 +27,7 @@ module HTTPX
|
|
|
27
27
|
@keep_open = true
|
|
28
28
|
@state = :connected
|
|
29
29
|
else
|
|
30
|
-
|
|
31
|
-
# :nocov:
|
|
32
|
-
warn ":transport_options is deprecated, use :addresses instead"
|
|
33
|
-
@path = @options.transport_options[:path]
|
|
34
|
-
# :nocov:
|
|
35
|
-
else
|
|
36
|
-
@path = addresses.first
|
|
37
|
-
end
|
|
30
|
+
@path = addresses.first
|
|
38
31
|
end
|
|
39
32
|
@io ||= build_socket
|
|
40
33
|
end
|
data/lib/httpx/loggable.rb
CHANGED
|
@@ -24,26 +24,11 @@ module HTTPX
|
|
|
24
24
|
debug_stream << message
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
return unless @options.debug
|
|
31
|
-
return unless @options.debug_level >= level
|
|
32
|
-
|
|
33
|
-
log(level: level, color: color) { ex.full_message }
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
else
|
|
37
|
-
|
|
38
|
-
def log_exception(ex, level: @options.debug_level, color: nil)
|
|
39
|
-
return unless @options.debug
|
|
40
|
-
return unless @options.debug_level >= level
|
|
41
|
-
|
|
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
|
-
end
|
|
27
|
+
def log_exception(ex, level: @options.debug_level, color: nil)
|
|
28
|
+
return unless @options.debug
|
|
29
|
+
return unless @options.debug_level >= level
|
|
46
30
|
|
|
31
|
+
log(level: level, color: color) { ex.full_message }
|
|
47
32
|
end
|
|
48
33
|
end
|
|
49
34
|
end
|