httpx 1.4.2 → 1.4.4
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_4_3.md +11 -0
- data/doc/release_notes/1_4_4.md +14 -0
- data/lib/httpx/adapters/webmock.rb +4 -0
- data/lib/httpx/connection/http2.rb +31 -16
- data/lib/httpx/connection.rb +10 -5
- data/lib/httpx/errors.rb +0 -4
- data/lib/httpx/io/ssl.rb +6 -3
- data/lib/httpx/loggable.rb +5 -5
- data/lib/httpx/plugins/internal_telemetry.rb +21 -1
- data/lib/httpx/plugins/retries.rb +2 -2
- data/lib/httpx/plugins/stream.rb +42 -18
- data/lib/httpx/request.rb +18 -4
- data/lib/httpx/response.rb +9 -4
- data/lib/httpx/session.rb +3 -6
- data/lib/httpx/transcoder/multipart/encoder.rb +2 -1
- data/lib/httpx/version.rb +1 -1
- data/sig/connection/http2.rbs +4 -0
- data/sig/errors.rbs +0 -3
- data/sig/loggable.rbs +2 -2
- data/sig/plugins/stream.rbs +3 -0
- data/sig/pool.rbs +2 -0
- data/sig/request.rbs +9 -0
- data/sig/response.rbs +8 -3
- data/sig/transcoder/json.rbs +1 -1
- data/sig/transcoder/multipart.rbs +1 -1
- data/sig/transcoder/utils/deflater.rbs +0 -1
- metadata +7 -9
- data/lib/httpx/session2.rb +0 -23
- data/lib/httpx/transcoder/utils/inflater.rb +0 -21
- data/sig/transcoder/utils/inflater.rbs +0 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4aa5b1cfd43d05f50fc7246219d6a90cb5591e11c8bfeee1f1cf62ffa91993fc
|
4
|
+
data.tar.gz: 58f96325ac13b8caddb708464a75ee6dafcfe7b8284f0825803ac3d0c4d8ccc1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 43a032f78a86df04428af78f32077483b8c01500ebb001ec97100ac3923b4915a28b299cadb8b47fab8fa875c3897732c21eec63769ad98dfd98b901f006b051
|
7
|
+
data.tar.gz: dfff14a83428e2472ff53a50cadf5dd7a270f09523eca4c5aa66e7a3093ca8bd096c9c3d12070ed6a54ef1ddaec4966efd456653e666429f0ce47f04fe68e35a
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# 1.4.3
|
2
|
+
|
3
|
+
## Bugfixes
|
4
|
+
|
5
|
+
* `webmock` adapter: reassign headers to signature after callbacks are called (these may change the headers before virtual send).
|
6
|
+
* do not close request (and its body) right after sending, instead only on response close
|
7
|
+
* prevents retries from failing under the `:retries` plugin
|
8
|
+
* fixes issue when using `faraday-multipart` request bodies
|
9
|
+
* retry request with HTTP/1 when receiving an HTTP/2 GOAWAY frame with `HTTP_1_1_REQUIRED` error code.
|
10
|
+
* fix wrong method call on HTTP/2 PING frame with unrecognized code.
|
11
|
+
* fix EOFError issues on connection termination for long running connections which may have already been terminated by peer and were wrongly trying to complete the HTTP/2 termination handshake.
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# 1.4.4
|
2
|
+
|
3
|
+
## Improvements
|
4
|
+
|
5
|
+
* `:stream` plugin: response will now be partially buffered in order to i.e. inspect response status or headers on the response body without buffering the full response
|
6
|
+
* this fixes an issue in the `down` gem integration when used with the `:max_size` option.
|
7
|
+
* do not unnecessarily probe for connection liveness if no more requests are inflight, including failed ones.
|
8
|
+
* when using persistent connections, do not probe for liveness right after reconnecting after a keep alive timeout.
|
9
|
+
|
10
|
+
## Bugfixes
|
11
|
+
|
12
|
+
* `:persistent` plugin: do not exhaust retry attempts when probing for (and failing) connection liveness.
|
13
|
+
* since the introduction of per-session connection pools, and consequentially due to the possibility of multiple inactive connections for the same origin being in the pool, which may have been terminated by the peer server, requests would fail before being able to establish a new connection.
|
14
|
+
* prevent retrying to connect the TCP socket object when an SSLSocket object is already in place and connecting.
|
@@ -58,6 +58,8 @@ module WebMock
|
|
58
58
|
super
|
59
59
|
|
60
60
|
connection.once(:unmock_connection) do
|
61
|
+
next unless connection.current_session == self
|
62
|
+
|
61
63
|
unless connection.addresses
|
62
64
|
# reset Happy Eyeballs, fail early
|
63
65
|
connection.sibling = nil
|
@@ -122,6 +124,8 @@ module WebMock
|
|
122
124
|
request.transition(:done)
|
123
125
|
request.response = response
|
124
126
|
request.emit(:response, response)
|
127
|
+
request_signature.headers = request.headers.to_h
|
128
|
+
|
125
129
|
response << mock_response.body.dup unless response.is_a?(HTTPX::ErrorResponse)
|
126
130
|
elsif WebMock.net_connect_allowed?(request_signature.uri)
|
127
131
|
if WebMock::CallbackRegistry.any_callbacks?
|
@@ -16,6 +16,12 @@ module HTTPX
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
+
class PingError < Error
|
20
|
+
def initialize
|
21
|
+
super(0, :ping_error)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
19
25
|
class GoawayError < Error
|
20
26
|
def initialize
|
21
27
|
super(0, :no_error)
|
@@ -311,17 +317,20 @@ module HTTPX
|
|
311
317
|
@streams.delete(request)
|
312
318
|
|
313
319
|
if error
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
320
|
+
case error
|
321
|
+
when :http_1_1_required
|
322
|
+
emit(:error, request, error)
|
323
|
+
else
|
324
|
+
ex = Error.new(stream.id, error)
|
325
|
+
ex.set_backtrace(caller)
|
326
|
+
response = ErrorResponse.new(request, ex)
|
327
|
+
request.response = response
|
328
|
+
emit(:response, request, response)
|
329
|
+
end
|
319
330
|
else
|
320
331
|
response = request.response
|
321
332
|
if response && response.is_a?(Response) && response.status == 421
|
322
|
-
|
323
|
-
ex.set_backtrace(caller)
|
324
|
-
emit(:error, request, ex)
|
333
|
+
emit(:error, request, :http_1_1_required)
|
325
334
|
else
|
326
335
|
emit(:response, request, response)
|
327
336
|
end
|
@@ -352,7 +361,12 @@ module HTTPX
|
|
352
361
|
is_connection_closed = @connection.state == :closed
|
353
362
|
if error
|
354
363
|
@buffer.clear if is_connection_closed
|
355
|
-
|
364
|
+
case error
|
365
|
+
when :http_1_1_required
|
366
|
+
while (request = @pending.shift)
|
367
|
+
emit(:error, request, error)
|
368
|
+
end
|
369
|
+
when :no_error
|
356
370
|
ex = GoawayError.new
|
357
371
|
@pending.unshift(*@streams.keys)
|
358
372
|
@drains.clear
|
@@ -360,8 +374,11 @@ module HTTPX
|
|
360
374
|
else
|
361
375
|
ex = Error.new(0, error)
|
362
376
|
end
|
363
|
-
|
364
|
-
|
377
|
+
|
378
|
+
if ex
|
379
|
+
ex.set_backtrace(caller)
|
380
|
+
handle_error(ex)
|
381
|
+
end
|
365
382
|
end
|
366
383
|
return unless is_connection_closed && @streams.empty?
|
367
384
|
|
@@ -403,11 +420,9 @@ module HTTPX
|
|
403
420
|
end
|
404
421
|
|
405
422
|
def on_pong(ping)
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
close(:protocol_error, "ping payload did not match")
|
410
|
-
end
|
423
|
+
raise PingError unless @pings.delete(ping.to_s)
|
424
|
+
|
425
|
+
emit(:pong)
|
411
426
|
end
|
412
427
|
end
|
413
428
|
end
|
data/lib/httpx/connection.rb
CHANGED
@@ -296,6 +296,7 @@ module HTTPX
|
|
296
296
|
@pending << request
|
297
297
|
transition(:active) if @state == :inactive
|
298
298
|
parser.ping
|
299
|
+
request.ping!
|
299
300
|
return
|
300
301
|
end
|
301
302
|
|
@@ -423,6 +424,8 @@ module HTTPX
|
|
423
424
|
siz = @io.read(@window_size, @read_buffer)
|
424
425
|
log(level: 3, color: :cyan) { "IO READ: #{siz} bytes... (wsize: #{@window_size}, rbuffer: #{@read_buffer.bytesize})" }
|
425
426
|
unless siz
|
427
|
+
@write_buffer.clear
|
428
|
+
|
426
429
|
ex = EOFError.new("descriptor closed")
|
427
430
|
ex.set_backtrace(caller)
|
428
431
|
on_error(ex)
|
@@ -610,9 +613,9 @@ module HTTPX
|
|
610
613
|
parser.on(:timeout) do |tout|
|
611
614
|
@timeout = tout
|
612
615
|
end
|
613
|
-
parser.on(:error) do |request,
|
614
|
-
case
|
615
|
-
when
|
616
|
+
parser.on(:error) do |request, error|
|
617
|
+
case error
|
618
|
+
when :http_1_1_required
|
616
619
|
current_session = @current_session
|
617
620
|
current_selector = @current_selector
|
618
621
|
parser.close
|
@@ -628,7 +631,8 @@ module HTTPX
|
|
628
631
|
next unless request.active_timeouts.empty?
|
629
632
|
end
|
630
633
|
|
631
|
-
|
634
|
+
@inflight -= 1
|
635
|
+
response = ErrorResponse.new(request, error)
|
632
636
|
request.response = response
|
633
637
|
request.emit(:response, response)
|
634
638
|
end
|
@@ -668,7 +672,7 @@ module HTTPX
|
|
668
672
|
when :idle
|
669
673
|
@timeout = @current_timeout = @options.timeout[:connect_timeout]
|
670
674
|
|
671
|
-
@connected_at = nil
|
675
|
+
@connected_at = @response_received_at = nil
|
672
676
|
when :open
|
673
677
|
return if @state == :closed
|
674
678
|
|
@@ -841,6 +845,7 @@ module HTTPX
|
|
841
845
|
|
842
846
|
return unless request
|
843
847
|
|
848
|
+
@inflight -= 1
|
844
849
|
response = ErrorResponse.new(request, error)
|
845
850
|
request.response = response
|
846
851
|
request.emit(:response, response)
|
data/lib/httpx/errors.rb
CHANGED
@@ -115,8 +115,4 @@ module HTTPX
|
|
115
115
|
@response.status
|
116
116
|
end
|
117
117
|
end
|
118
|
-
|
119
|
-
# error raised when a request was sent a server which can't reproduce a response, and
|
120
|
-
# has therefore returned an HTTP response using the 421 status code.
|
121
|
-
class MisdirectedRequestError < HTTPError; end
|
122
118
|
end
|
data/lib/httpx/io/ssl.rb
CHANGED
@@ -92,9 +92,12 @@ module HTTPX
|
|
92
92
|
end
|
93
93
|
|
94
94
|
def connect
|
95
|
-
|
96
|
-
|
97
|
-
|
95
|
+
return if @state == :negotiated
|
96
|
+
|
97
|
+
unless @state == :connected
|
98
|
+
super
|
99
|
+
return unless @state == :connected
|
100
|
+
end
|
98
101
|
|
99
102
|
unless @io.is_a?(OpenSSL::SSL::SSLSocket)
|
100
103
|
if (hostname_is_ip = (@ip == @sni_hostname))
|
data/lib/httpx/loggable.rb
CHANGED
@@ -15,10 +15,10 @@ module HTTPX
|
|
15
15
|
|
16
16
|
USE_DEBUG_LOG = ENV.key?("HTTPX_DEBUG")
|
17
17
|
|
18
|
-
def log(level: @options.debug_level, color: nil, &msg)
|
19
|
-
return unless
|
18
|
+
def log(level: @options.debug_level, color: nil, debug_level: @options.debug_level, debug: @options.debug, &msg)
|
19
|
+
return unless debug_level >= level
|
20
20
|
|
21
|
-
debug_stream =
|
21
|
+
debug_stream = debug || ($stderr if USE_DEBUG_LOG)
|
22
22
|
|
23
23
|
return unless debug_stream
|
24
24
|
|
@@ -34,8 +34,8 @@ module HTTPX
|
|
34
34
|
debug_stream << message
|
35
35
|
end
|
36
36
|
|
37
|
-
def log_exception(ex, level: @options.debug_level, color: nil)
|
38
|
-
log(level: level, color: color) { ex.full_message }
|
37
|
+
def log_exception(ex, level: @options.debug_level, color: nil, debug_level: @options.debug_level, debug: @options.debug)
|
38
|
+
log(level: level, color: color, debug_level: debug_level, debug: debug) { ex.full_message }
|
39
39
|
end
|
40
40
|
end
|
41
41
|
end
|
@@ -13,6 +13,12 @@ module HTTPX
|
|
13
13
|
# by the end user in $http_init_time, different diff metrics can be shown. The "point of time" is calculated
|
14
14
|
# using the monotonic clock.
|
15
15
|
module InternalTelemetry
|
16
|
+
DEBUG_LEVEL = 3
|
17
|
+
|
18
|
+
def self.extra_options(options)
|
19
|
+
options.merge(debug_level: 3)
|
20
|
+
end
|
21
|
+
|
16
22
|
module TrackTimeMethods
|
17
23
|
private
|
18
24
|
|
@@ -28,7 +34,19 @@ module HTTPX
|
|
28
34
|
after_time = Process.clock_gettime(Process::CLOCK_MONOTONIC, :millisecond)
|
29
35
|
# $http_init_time = after_time
|
30
36
|
elapsed = after_time - prev_time
|
31
|
-
|
37
|
+
# klass = self.class
|
38
|
+
|
39
|
+
# until (class_name = klass.name)
|
40
|
+
# klass = klass.superclass
|
41
|
+
# end
|
42
|
+
log(
|
43
|
+
level: DEBUG_LEVEL,
|
44
|
+
color: :red,
|
45
|
+
debug_level: @options ? @options.debug_level : DEBUG_LEVEL,
|
46
|
+
debug: nil
|
47
|
+
) do
|
48
|
+
"[ELAPSED TIME]: #{label}: #{elapsed} (ms)" << "\e[0m"
|
49
|
+
end
|
32
50
|
end
|
33
51
|
end
|
34
52
|
|
@@ -88,6 +106,7 @@ module HTTPX
|
|
88
106
|
|
89
107
|
module RequestMethods
|
90
108
|
def self.included(klass)
|
109
|
+
klass.prepend Loggable
|
91
110
|
klass.prepend TrackTimeMethods
|
92
111
|
super
|
93
112
|
end
|
@@ -114,6 +133,7 @@ module HTTPX
|
|
114
133
|
|
115
134
|
module PoolMethods
|
116
135
|
def self.included(klass)
|
136
|
+
klass.prepend Loggable
|
117
137
|
klass.prepend TrackTimeMethods
|
118
138
|
super
|
119
139
|
end
|
@@ -110,7 +110,7 @@ module HTTPX
|
|
110
110
|
)
|
111
111
|
__try_partial_retry(request, response)
|
112
112
|
log { "failed to get response, #{request.retries} tries to go..." }
|
113
|
-
request.retries -= 1
|
113
|
+
request.retries -= 1 unless request.ping? # do not exhaust retries on connection liveness probes
|
114
114
|
request.transition(:idle)
|
115
115
|
|
116
116
|
retry_after = options.retry_after
|
@@ -167,7 +167,7 @@ module HTTPX
|
|
167
167
|
unless response.headers.key?("accept-ranges") &&
|
168
168
|
response.headers["accept-ranges"] == "bytes" && # there's nothing else supported though...
|
169
169
|
(original_body = response.body)
|
170
|
-
response.
|
170
|
+
response.body.close
|
171
171
|
return
|
172
172
|
end
|
173
173
|
|
data/lib/httpx/plugins/stream.rb
CHANGED
@@ -4,27 +4,39 @@ module HTTPX
|
|
4
4
|
class StreamResponse
|
5
5
|
def initialize(request, session)
|
6
6
|
@request = request
|
7
|
+
@options = @request.options
|
7
8
|
@session = session
|
8
|
-
@
|
9
|
+
@response_enum = nil
|
10
|
+
@buffered_chunks = []
|
9
11
|
end
|
10
12
|
|
11
13
|
def each(&block)
|
12
14
|
return enum_for(__method__) unless block
|
13
15
|
|
16
|
+
if (response_enum = @response_enum)
|
17
|
+
@response_enum = nil
|
18
|
+
# streaming already started, let's finish it
|
19
|
+
|
20
|
+
while (chunk = @buffered_chunks.shift)
|
21
|
+
block.call(chunk)
|
22
|
+
end
|
23
|
+
|
24
|
+
# consume enum til the end
|
25
|
+
begin
|
26
|
+
while (chunk = response_enum.next)
|
27
|
+
block.call(chunk)
|
28
|
+
end
|
29
|
+
rescue StopIteration
|
30
|
+
return
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
14
34
|
@request.stream = self
|
15
35
|
|
16
36
|
begin
|
17
37
|
@on_chunk = block
|
18
38
|
|
19
|
-
|
20
|
-
# if we've already started collecting the payload, yield it first
|
21
|
-
# before proceeding.
|
22
|
-
body = @request.response.body
|
23
|
-
|
24
|
-
body.each do |chunk|
|
25
|
-
on_chunk(chunk)
|
26
|
-
end
|
27
|
-
end
|
39
|
+
response = @session.request(@request)
|
28
40
|
|
29
41
|
response.raise_for_status
|
30
42
|
ensure
|
@@ -64,27 +76,39 @@ module HTTPX
|
|
64
76
|
# :nocov:
|
65
77
|
|
66
78
|
def to_s
|
67
|
-
response
|
79
|
+
if @request.response
|
80
|
+
@request.response.to_s
|
81
|
+
else
|
82
|
+
@buffered_chunks.join
|
83
|
+
end
|
68
84
|
end
|
69
85
|
|
70
86
|
private
|
71
87
|
|
72
88
|
def response
|
73
|
-
return @response if @response
|
74
|
-
|
75
89
|
@request.response || begin
|
76
|
-
|
90
|
+
response_enum = each
|
91
|
+
while (chunk = response_enum.next)
|
92
|
+
@buffered_chunks << chunk
|
93
|
+
break if @request.response
|
94
|
+
end
|
95
|
+
@response_enum = response_enum
|
96
|
+
@request.response
|
77
97
|
end
|
78
98
|
end
|
79
99
|
|
80
|
-
def respond_to_missing?(meth,
|
81
|
-
response.
|
100
|
+
def respond_to_missing?(meth, include_private)
|
101
|
+
if (response = @request.response)
|
102
|
+
response.respond_to_missing?(meth, include_private)
|
103
|
+
else
|
104
|
+
@options.response_class.method_defined?(meth) || (include_private && @options.response_class.private_method_defined?(meth))
|
105
|
+
end || super
|
82
106
|
end
|
83
107
|
|
84
|
-
def method_missing(meth, *args, &block)
|
108
|
+
def method_missing(meth, *args, **kwargs, &block)
|
85
109
|
return super unless response.respond_to?(meth)
|
86
110
|
|
87
|
-
response.__send__(meth, *args, &block)
|
111
|
+
response.__send__(meth, *args, **kwargs, &block)
|
88
112
|
end
|
89
113
|
end
|
90
114
|
|
data/lib/httpx/request.rb
CHANGED
@@ -50,6 +50,9 @@ module HTTPX
|
|
50
50
|
# will be +true+ when request body has been completely flushed.
|
51
51
|
def_delegator :@body, :empty?
|
52
52
|
|
53
|
+
# closes the body
|
54
|
+
def_delegator :@body, :close
|
55
|
+
|
53
56
|
# initializes the instance with the given +verb+ (an upppercase String, ex. 'GEt'),
|
54
57
|
# an absolute or relative +uri+ (either as String or URI::HTTP object), the
|
55
58
|
# request +options+ (instance of HTTPX::Options) and an optional Hash of +params+.
|
@@ -101,21 +104,32 @@ module HTTPX
|
|
101
104
|
@state = :idle
|
102
105
|
@response = nil
|
103
106
|
@peer_address = nil
|
107
|
+
@ping = false
|
104
108
|
@persistent = @options.persistent
|
105
109
|
@active_timeouts = []
|
106
110
|
end
|
107
111
|
|
108
|
-
#
|
112
|
+
# whether request has been buffered with a ping
|
113
|
+
def ping?
|
114
|
+
@ping
|
115
|
+
end
|
116
|
+
|
117
|
+
# marks the request as having been buffered with a ping
|
118
|
+
def ping!
|
119
|
+
@ping = true
|
120
|
+
end
|
121
|
+
|
122
|
+
# the read timeout defined for this request.
|
109
123
|
def read_timeout
|
110
124
|
@options.timeout[:read_timeout]
|
111
125
|
end
|
112
126
|
|
113
|
-
# the write timeout defined for this
|
127
|
+
# the write timeout defined for this request.
|
114
128
|
def write_timeout
|
115
129
|
@options.timeout[:write_timeout]
|
116
130
|
end
|
117
131
|
|
118
|
-
# the request timeout defined for this
|
132
|
+
# the request timeout defined for this request.
|
119
133
|
def request_timeout
|
120
134
|
@options.timeout[:request_timeout]
|
121
135
|
end
|
@@ -246,6 +260,7 @@ module HTTPX
|
|
246
260
|
case nextstate
|
247
261
|
when :idle
|
248
262
|
@body.rewind
|
263
|
+
@ping = false
|
249
264
|
@response = nil
|
250
265
|
@drainer = nil
|
251
266
|
@active_timeouts.clear
|
@@ -273,7 +288,6 @@ module HTTPX
|
|
273
288
|
when :done
|
274
289
|
return if @state == :expect
|
275
290
|
|
276
|
-
@body.close
|
277
291
|
end
|
278
292
|
@state = nextstate
|
279
293
|
emit(@state, self)
|
data/lib/httpx/response.rb
CHANGED
@@ -52,9 +52,6 @@ module HTTPX
|
|
52
52
|
# copies the response body to a different location.
|
53
53
|
def_delegator :@body, :copy_to
|
54
54
|
|
55
|
-
# closes the body.
|
56
|
-
def_delegator :@body, :close
|
57
|
-
|
58
55
|
# the corresponding request uri.
|
59
56
|
def_delegator :@request, :uri
|
60
57
|
|
@@ -74,6 +71,12 @@ module HTTPX
|
|
74
71
|
@content_type = nil
|
75
72
|
end
|
76
73
|
|
74
|
+
# closes the respective +@request+ and +@body+.
|
75
|
+
def close
|
76
|
+
@request.close
|
77
|
+
@body.close
|
78
|
+
end
|
79
|
+
|
77
80
|
# merges headers defined in +h+ into the response headers.
|
78
81
|
def merge_headers(h)
|
79
82
|
@headers = @headers.merge(h)
|
@@ -264,7 +267,7 @@ module HTTPX
|
|
264
267
|
|
265
268
|
# closes the error resources.
|
266
269
|
def close
|
267
|
-
@response.close if @response
|
270
|
+
@response.close if @response
|
268
271
|
end
|
269
272
|
|
270
273
|
# always true for error responses.
|
@@ -279,6 +282,8 @@ module HTTPX
|
|
279
282
|
|
280
283
|
# buffers lost chunks to error response
|
281
284
|
def <<(data)
|
285
|
+
return unless @response
|
286
|
+
|
282
287
|
@response << data
|
283
288
|
end
|
284
289
|
end
|
data/lib/httpx/session.rb
CHANGED
@@ -188,14 +188,9 @@ module HTTPX
|
|
188
188
|
else
|
189
189
|
pin_connection(connection, selector)
|
190
190
|
end
|
191
|
-
when :closed
|
191
|
+
when :closing, :closed
|
192
192
|
connection.idling
|
193
193
|
select_connection(connection, selector)
|
194
|
-
when :closing
|
195
|
-
connection.once(:close) do
|
196
|
-
connection.idling
|
197
|
-
select_connection(connection, selector)
|
198
|
-
end
|
199
194
|
else
|
200
195
|
pin_connection(connection, selector)
|
201
196
|
end
|
@@ -371,6 +366,8 @@ module HTTPX
|
|
371
366
|
coalesce_connections(found_connection, connection, selector, from_pool)
|
372
367
|
else
|
373
368
|
found_connection.once(:open) do
|
369
|
+
next unless found_connection.current_session == self
|
370
|
+
|
374
371
|
coalesce_connections(found_connection, connection, selector, from_pool)
|
375
372
|
end
|
376
373
|
end
|
@@ -11,6 +11,7 @@ module HTTPX
|
|
11
11
|
@buffer = "".b
|
12
12
|
|
13
13
|
@form = form
|
14
|
+
@bytesize = 0
|
14
15
|
@parts = to_parts(form)
|
15
16
|
end
|
16
17
|
|
@@ -42,6 +43,7 @@ module HTTPX
|
|
42
43
|
aux << [key, val]
|
43
44
|
end
|
44
45
|
@form = form
|
46
|
+
@bytesize = 0
|
45
47
|
@parts = to_parts(form)
|
46
48
|
@part_index = 0
|
47
49
|
end
|
@@ -49,7 +51,6 @@ module HTTPX
|
|
49
51
|
private
|
50
52
|
|
51
53
|
def to_parts(form)
|
52
|
-
@bytesize = 0
|
53
54
|
params = form.each_with_object([]) do |(key, val), aux|
|
54
55
|
Transcoder.normalize_keys(key, val, MULTIPART_VALUE_COND) do |k, v|
|
55
56
|
next if v.nil?
|
data/lib/httpx/version.rb
CHANGED
data/sig/connection/http2.rbs
CHANGED
@@ -8,6 +8,7 @@ module HTTPX
|
|
8
8
|
attr_reader streams: Hash[Request, ::HTTP2::Stream]
|
9
9
|
attr_reader pending: Array[Request]
|
10
10
|
|
11
|
+
@connection: HTTP2::Client
|
11
12
|
@options: Options
|
12
13
|
@settings: Hash[Symbol, Integer | bool]
|
13
14
|
@max_concurrent_requests: Integer
|
@@ -95,5 +96,8 @@ module HTTPX
|
|
95
96
|
|
96
97
|
class GoawayError < Error
|
97
98
|
end
|
99
|
+
|
100
|
+
class PingError < Error
|
101
|
+
end
|
98
102
|
end
|
99
103
|
end
|
data/sig/errors.rbs
CHANGED
data/sig/loggable.rbs
CHANGED
@@ -8,8 +8,8 @@ module HTTPX
|
|
8
8
|
|
9
9
|
COLORS: Hash[Symbol, Integer]
|
10
10
|
|
11
|
-
def log: (?level: Integer?, ?color: Symbol?) { () -> String } -> void
|
11
|
+
def log: (?level: Integer?, ?color: Symbol?, ?debug_level: Integer, ?debug: _IOLogger?) { () -> String } -> void
|
12
12
|
|
13
|
-
def log_exception: (Exception error, ?level: Integer, ?color: Symbol) -> void
|
13
|
+
def log_exception: (Exception error, ?level: Integer, ?color: Symbol, ?debug_level: Integer, ?debug: _IOLogger?) -> void
|
14
14
|
end
|
15
15
|
end
|
data/sig/plugins/stream.rbs
CHANGED
@@ -27,7 +27,10 @@ module HTTPX
|
|
27
27
|
type streamRequest = Request & Plugins::Stream::RequestMethods
|
28
28
|
|
29
29
|
@request: streamRequest
|
30
|
+
@options: Options
|
30
31
|
@session: Plugins::sessionStream
|
32
|
+
@response_enum: Enumerator[String]?
|
33
|
+
@buffered_chunks: Array[String]
|
31
34
|
@on_chunk: ^(String) -> void | nil
|
32
35
|
|
33
36
|
def each: () { (String) -> void } -> void
|
data/sig/pool.rbs
CHANGED
data/sig/request.rbs
CHANGED
@@ -20,6 +20,7 @@ module HTTPX
|
|
20
20
|
|
21
21
|
attr_writer persistent: bool
|
22
22
|
|
23
|
+
@ping: bool
|
23
24
|
@query_params: Hash[interned, untyped]?
|
24
25
|
@trailers: Headers?
|
25
26
|
@informational_status: Integer?
|
@@ -28,6 +29,14 @@ module HTTPX
|
|
28
29
|
|
29
30
|
def initialize: (Symbol | String verb, generic_uri uri, Options options, ?request_params params) -> untyped
|
30
31
|
|
32
|
+
def ping?: () -> bool
|
33
|
+
|
34
|
+
def ping!: () -> void
|
35
|
+
|
36
|
+
def empty?: () -> bool
|
37
|
+
|
38
|
+
def close: () -> void
|
39
|
+
|
31
40
|
def interests: () -> (:r | :w)
|
32
41
|
|
33
42
|
def merge_headers: (_Each[[String, headers_value]]) -> void
|
data/sig/response.rbs
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
module HTTPX
|
2
2
|
interface _Response
|
3
|
+
def <<: (String data) -> void
|
4
|
+
|
3
5
|
def finished?: () -> bool
|
4
6
|
|
5
7
|
def raise_for_status: () -> self
|
@@ -23,6 +25,7 @@ module HTTPX
|
|
23
25
|
@options: Options
|
24
26
|
@request: Request
|
25
27
|
@content_type: ContentType
|
28
|
+
@finished: bool
|
26
29
|
|
27
30
|
def copy_to: (_ToPath | _Writer destination) -> void
|
28
31
|
|
@@ -38,9 +41,11 @@ module HTTPX
|
|
38
41
|
|
39
42
|
def content_type: () -> ContentType
|
40
43
|
|
44
|
+
def finish!: () -> void
|
45
|
+
|
41
46
|
def complete?: () -> bool
|
42
47
|
|
43
|
-
def json: (?
|
48
|
+
def json: (?JSON::options opts) -> untyped
|
44
49
|
|
45
50
|
def form: () -> Hash[String, untyped]
|
46
51
|
|
@@ -77,9 +82,9 @@ module HTTPX
|
|
77
82
|
@options: Options
|
78
83
|
@error: Exception
|
79
84
|
|
80
|
-
attr_reader request: Request
|
85
|
+
%a{pure} attr_reader request: Request
|
81
86
|
|
82
|
-
attr_reader response: Response?
|
87
|
+
%a{pure} attr_reader response: Response?
|
83
88
|
|
84
89
|
def status: () -> (Integer | _ToS)
|
85
90
|
|
data/sig/transcoder/json.rbs
CHANGED
@@ -5,7 +5,7 @@ module HTTPX::Transcoder
|
|
5
5
|
def self?.encode: (_ToJson json) -> Encoder
|
6
6
|
def self?.decode: (HTTPX::Response response) -> _Decoder
|
7
7
|
|
8
|
-
def self?.json_load: (string source, ?
|
8
|
+
def self?.json_load: (string source, ?JSON::options) -> untyped
|
9
9
|
def self?.json_dump: (_ToJson obj, *untyped) -> String
|
10
10
|
|
11
11
|
class Encoder
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: httpx
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.4.
|
4
|
+
version: 1.4.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tiago Cardoso
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date: 2025-03
|
10
|
+
date: 2025-04-03 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: http-2
|
@@ -152,6 +151,8 @@ extra_rdoc_files:
|
|
152
151
|
- doc/release_notes/1_4_0.md
|
153
152
|
- doc/release_notes/1_4_1.md
|
154
153
|
- doc/release_notes/1_4_2.md
|
154
|
+
- doc/release_notes/1_4_3.md
|
155
|
+
- doc/release_notes/1_4_4.md
|
155
156
|
files:
|
156
157
|
- LICENSE.txt
|
157
158
|
- README.md
|
@@ -275,6 +276,8 @@ files:
|
|
275
276
|
- doc/release_notes/1_4_0.md
|
276
277
|
- doc/release_notes/1_4_1.md
|
277
278
|
- doc/release_notes/1_4_2.md
|
279
|
+
- doc/release_notes/1_4_3.md
|
280
|
+
- doc/release_notes/1_4_4.md
|
278
281
|
- lib/httpx.rb
|
279
282
|
- lib/httpx/adapters/datadog.rb
|
280
283
|
- lib/httpx/adapters/faraday.rb
|
@@ -363,7 +366,6 @@ files:
|
|
363
366
|
- lib/httpx/response/buffer.rb
|
364
367
|
- lib/httpx/selector.rb
|
365
368
|
- lib/httpx/session.rb
|
366
|
-
- lib/httpx/session2.rb
|
367
369
|
- lib/httpx/session_extensions.rb
|
368
370
|
- lib/httpx/timers.rb
|
369
371
|
- lib/httpx/transcoder.rb
|
@@ -380,7 +382,6 @@ files:
|
|
380
382
|
- lib/httpx/transcoder/multipart/part.rb
|
381
383
|
- lib/httpx/transcoder/utils/body_reader.rb
|
382
384
|
- lib/httpx/transcoder/utils/deflater.rb
|
383
|
-
- lib/httpx/transcoder/utils/inflater.rb
|
384
385
|
- lib/httpx/utils.rb
|
385
386
|
- lib/httpx/version.rb
|
386
387
|
- sig/altsvc.rbs
|
@@ -468,7 +469,6 @@ files:
|
|
468
469
|
- sig/transcoder/multipart.rbs
|
469
470
|
- sig/transcoder/utils/body_reader.rbs
|
470
471
|
- sig/transcoder/utils/deflater.rbs
|
471
|
-
- sig/transcoder/utils/inflater.rbs
|
472
472
|
- sig/utils.rbs
|
473
473
|
homepage: https://gitlab.com/os85/httpx
|
474
474
|
licenses:
|
@@ -480,7 +480,6 @@ metadata:
|
|
480
480
|
source_code_uri: https://gitlab.com/os85/httpx
|
481
481
|
homepage_uri: https://honeyryderchuck.gitlab.io/httpx/
|
482
482
|
rubygems_mfa_required: 'true'
|
483
|
-
post_install_message:
|
484
483
|
rdoc_options: []
|
485
484
|
require_paths:
|
486
485
|
- lib
|
@@ -495,8 +494,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
495
494
|
- !ruby/object:Gem::Version
|
496
495
|
version: '0'
|
497
496
|
requirements: []
|
498
|
-
rubygems_version: 3.
|
499
|
-
signing_key:
|
497
|
+
rubygems_version: 3.6.2
|
500
498
|
specification_version: 4
|
501
499
|
summary: HTTPX, to the future, and beyond
|
502
500
|
test_files: []
|
data/lib/httpx/session2.rb
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "session"
|
4
|
-
module HTTPX
|
5
|
-
class Session
|
6
|
-
def initialize(options = EMPTY, &blk)
|
7
|
-
@options = self.class.default_options.merge(options)
|
8
|
-
@responses = {}
|
9
|
-
@persistent = @options.persistent
|
10
|
-
wrap(&blk) if blk
|
11
|
-
end
|
12
|
-
|
13
|
-
def wrap
|
14
|
-
begin
|
15
|
-
prev_persistent = @persistent
|
16
|
-
@persistent = true
|
17
|
-
yield self
|
18
|
-
ensure
|
19
|
-
@persistent = prev_persistent
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module HTTPX
|
4
|
-
module Transcoder
|
5
|
-
class Inflater
|
6
|
-
def initialize(bytesize)
|
7
|
-
@bytesize = bytesize
|
8
|
-
end
|
9
|
-
|
10
|
-
def call(chunk)
|
11
|
-
buffer = @inflater.inflate(chunk)
|
12
|
-
@bytesize -= chunk.bytesize
|
13
|
-
if @bytesize <= 0
|
14
|
-
buffer << @inflater.finish
|
15
|
-
@inflater.close
|
16
|
-
end
|
17
|
-
buffer
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|