async-http 0.78.0 → 0.80.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
- checksums.yaml.gz.sig +0 -0
- data/lib/async/http/protocol/http1/client.rb +12 -9
- data/lib/async/http/protocol/http1/connection.rb +2 -0
- data/lib/async/http/protocol/http1/finishable.rb +8 -4
- data/lib/async/http/protocol/http1/server.rb +25 -20
- data/lib/async/http/protocol/http2/output.rb +16 -6
- data/lib/async/http/protocol/http2/stream.rb +8 -6
- data/lib/async/http/version.rb +1 -1
- data.tar.gz.sig +1 -4
- metadata +6 -6
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5a73103da274cc4cac5838409d95a05f1c8a746e0b58dcee062031886061ffb7
|
4
|
+
data.tar.gz: da1d5991f78d71c2ab1a3c8ace1d0d8c53831b545bdcfe2f3e93d095bd6389bd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4169f9f110a07db5f27b6e083b09b1c6d3f0940269b1d423150993a491c4f3d46dfa4ae227712502b07d4cf949b0186e1e838fa3b77cead2809ee73c30e4500c
|
7
|
+
data.tar.gz: a85d33bd88881433c1c33b369027d6ff4f1c095b26ecac5b583b865fe2f8011c6ee7bba6c6f9857c5b1cf1697c4298a5e4c6506da3584d0215682bd4beea9858
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
@@ -18,11 +18,12 @@ module Async
|
|
18
18
|
|
19
19
|
attr_accessor :pool
|
20
20
|
|
21
|
-
def closed
|
21
|
+
def closed(error = nil)
|
22
22
|
super
|
23
23
|
|
24
24
|
if pool = @pool
|
25
25
|
@pool = nil
|
26
|
+
# If the connection is not reusable, this will retire it from the connection pool and invoke `#close`.
|
26
27
|
pool.release(self)
|
27
28
|
end
|
28
29
|
end
|
@@ -50,30 +51,32 @@ module Async
|
|
50
51
|
task.async(annotation: "Upgrading request...") do
|
51
52
|
# If this fails, this connection will be closed.
|
52
53
|
write_upgrade_body(protocol, body)
|
54
|
+
rescue => error
|
55
|
+
self.close(error)
|
53
56
|
end
|
54
57
|
elsif request.connect?
|
55
58
|
task.async(annotation: "Tunnneling request...") do
|
56
59
|
write_tunnel_body(@version, body)
|
60
|
+
rescue => error
|
61
|
+
self.close(error)
|
57
62
|
end
|
58
63
|
else
|
59
64
|
task.async(annotation: "Streaming request...") do
|
60
65
|
# Once we start writing the body, we can't recover if the request fails. That's because the body might be generated dynamically, streaming, etc.
|
61
66
|
write_body(@version, body, false, trailer)
|
67
|
+
rescue => error
|
68
|
+
self.close(error)
|
62
69
|
end
|
63
70
|
end
|
64
71
|
elsif protocol = request.protocol
|
65
72
|
write_upgrade_body(protocol)
|
66
73
|
else
|
67
|
-
write_body(@version, body, false, trailer)
|
74
|
+
write_body(@version, request.body, false, trailer)
|
68
75
|
end
|
69
76
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
rescue
|
74
|
-
# This will ensure that #reusable? returns false.
|
75
|
-
self.close
|
76
|
-
|
77
|
+
return Response.read(self, request)
|
78
|
+
rescue => error
|
79
|
+
self.close(error)
|
77
80
|
raise
|
78
81
|
end
|
79
82
|
end
|
@@ -32,19 +32,23 @@ module Async
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def close(error = nil)
|
35
|
+
super
|
36
|
+
|
35
37
|
unless @closed.resolved?
|
36
38
|
@error = error
|
37
39
|
@closed.value = true
|
38
40
|
end
|
39
|
-
|
40
|
-
super
|
41
41
|
end
|
42
42
|
|
43
|
-
def wait
|
43
|
+
def wait(persistent = true)
|
44
44
|
if @reading
|
45
45
|
@closed.wait
|
46
|
-
|
46
|
+
elsif persistent
|
47
|
+
# If the connection can be reused, let's gracefully discard the body:
|
47
48
|
self.discard
|
49
|
+
else
|
50
|
+
# Else, we don't care about the body, so we can close it immediately:
|
51
|
+
self.close
|
48
52
|
end
|
49
53
|
end
|
50
54
|
|
@@ -22,7 +22,7 @@ module Async
|
|
22
22
|
@ready = Async::Notification.new
|
23
23
|
end
|
24
24
|
|
25
|
-
def closed
|
25
|
+
def closed(error = nil)
|
26
26
|
super
|
27
27
|
|
28
28
|
@ready.signal
|
@@ -38,14 +38,12 @@ module Async
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def next_request
|
41
|
-
|
42
|
-
|
41
|
+
if closed?
|
42
|
+
return nil
|
43
|
+
elsif !idle?
|
43
44
|
@ready.wait
|
44
45
|
end
|
45
46
|
|
46
|
-
# The default is true.
|
47
|
-
return unless @persistent
|
48
|
-
|
49
47
|
# Read an incoming request:
|
50
48
|
return unless request = Request.read(self)
|
51
49
|
|
@@ -90,38 +88,41 @@ module Async
|
|
90
88
|
# We force a 101 response if the protocol is upgraded - HTTP/2 CONNECT will return 200 for success, but this won't be understood by HTTP/1 clients:
|
91
89
|
write_response(@version, 101, response.headers)
|
92
90
|
|
93
|
-
stream = write_upgrade_body(protocol)
|
94
|
-
|
95
91
|
# At this point, the request body is hijacked, so we don't want to call #finish below.
|
96
92
|
request = nil
|
97
93
|
response = nil
|
98
94
|
|
99
|
-
|
100
|
-
|
95
|
+
if body.stream?
|
96
|
+
return body.call(write_upgrade_body(protocol))
|
97
|
+
else
|
98
|
+
write_upgrade_body(protocol, body)
|
99
|
+
end
|
101
100
|
elsif response.status == 101
|
102
101
|
# This code path is to support legacy behavior where the response status is set to 101, but the protocol is not upgraded. This may not be a valid use case, but it is supported for compatibility. We expect the response headers to contain the `upgrade` header.
|
103
102
|
write_response(@version, response.status, response.headers)
|
104
103
|
|
105
|
-
stream = write_tunnel_body(version)
|
106
|
-
|
107
104
|
# Same as above:
|
108
105
|
request = nil
|
109
106
|
response = nil
|
110
107
|
|
111
|
-
|
112
|
-
|
108
|
+
if body.stream?
|
109
|
+
return body.call(write_tunnel_body(version))
|
110
|
+
else
|
111
|
+
write_tunnel_body(version, body)
|
112
|
+
end
|
113
113
|
else
|
114
114
|
write_response(@version, response.status, response.headers)
|
115
115
|
|
116
116
|
if request.connect? and response.success?
|
117
|
-
stream = write_tunnel_body(version)
|
118
|
-
|
119
117
|
# Same as above:
|
120
118
|
request = nil
|
121
119
|
response = nil
|
122
120
|
|
123
|
-
|
124
|
-
|
121
|
+
if body.stream?
|
122
|
+
return body.call(write_tunnel_body(version))
|
123
|
+
else
|
124
|
+
write_tunnel_body(version, body)
|
125
|
+
end
|
125
126
|
else
|
126
127
|
head = request.head?
|
127
128
|
|
@@ -143,8 +144,12 @@ module Async
|
|
143
144
|
request&.finish
|
144
145
|
end
|
145
146
|
|
146
|
-
|
147
|
-
|
147
|
+
if finishable
|
148
|
+
finishable.wait(@persistent)
|
149
|
+
else
|
150
|
+
# Do not remove this line or you will unleash the gods of concurrency hell.
|
151
|
+
task.yield
|
152
|
+
end
|
148
153
|
rescue => error
|
149
154
|
raise
|
150
155
|
ensure
|
@@ -17,7 +17,8 @@ module Async
|
|
17
17
|
|
18
18
|
@task = nil
|
19
19
|
|
20
|
-
@
|
20
|
+
@guard = ::Mutex.new
|
21
|
+
@window_updated = ::ConditionVariable.new
|
21
22
|
end
|
22
23
|
|
23
24
|
attr :trailer
|
@@ -33,17 +34,26 @@ module Async
|
|
33
34
|
end
|
34
35
|
|
35
36
|
def window_updated(size)
|
36
|
-
@
|
37
|
+
@guard.synchronize do
|
38
|
+
@window_updated.signal
|
39
|
+
end
|
37
40
|
end
|
38
41
|
|
39
42
|
def write(chunk)
|
40
43
|
until chunk.empty?
|
41
44
|
maximum_size = @stream.available_frame_size
|
42
45
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
46
|
+
# We try to avoid synchronization if possible:
|
47
|
+
if maximum_size <= 0
|
48
|
+
@guard.synchronize do
|
49
|
+
maximum_size = @stream.available_frame_size
|
50
|
+
|
51
|
+
while maximum_size <= 0
|
52
|
+
@window_updated.wait(@guard)
|
53
|
+
|
54
|
+
maximum_size = @stream.available_frame_size
|
55
|
+
end
|
56
|
+
end
|
47
57
|
end
|
48
58
|
|
49
59
|
break unless chunk = send_data(chunk, maximum_size)
|
@@ -62,9 +62,9 @@ module Async
|
|
62
62
|
end
|
63
63
|
|
64
64
|
# TODO this might need to be in an ensure block:
|
65
|
-
if @input and frame.end_stream?
|
66
|
-
@input.close_write
|
65
|
+
if input = @input and frame.end_stream?
|
67
66
|
@input = nil
|
67
|
+
input.close_write
|
68
68
|
end
|
69
69
|
rescue ::Protocol::HTTP2::HeaderError => error
|
70
70
|
Console.logger.debug(self, error)
|
@@ -123,6 +123,8 @@ module Async
|
|
123
123
|
|
124
124
|
# Called when the output terminates normally.
|
125
125
|
def finish_output(error = nil)
|
126
|
+
return if self.closed?
|
127
|
+
|
126
128
|
trailer = @output&.trailer
|
127
129
|
|
128
130
|
@output = nil
|
@@ -152,14 +154,14 @@ module Async
|
|
152
154
|
def closed(error)
|
153
155
|
super
|
154
156
|
|
155
|
-
if @input
|
156
|
-
@input.close_write(error)
|
157
|
+
if input = @input
|
157
158
|
@input = nil
|
159
|
+
input.close_write(error)
|
158
160
|
end
|
159
161
|
|
160
|
-
if @output
|
161
|
-
@output.stop(error)
|
162
|
+
if output = @output
|
162
163
|
@output = nil
|
164
|
+
output.stop(error)
|
163
165
|
end
|
164
166
|
|
165
167
|
if pool = @pool and @connection
|
data/lib/async/http/version.rb
CHANGED
data.tar.gz.sig
CHANGED
@@ -1,4 +1 @@
|
|
1
|
-
|
2
|
-
^�Ƶ=U���Z��'�cOt3JlLO�K6�4�1:$�t��6�ݚ���)�[y��q��^�a7��.x쥃��U�ɀ�N�*5�T�Y������
|
3
|
-
h%!5��c;Z[j�sX�L�����}>m}7e��p|9"̕$�4������k'Me_�{s1�?8/Li�Na���-ZI�4���1��G�$a]��ŋ��*���~-N�D8��&�����"��pr:���P;2��:a[��UB�� )|�}4[��ق�`����lq
|
4
|
-
��8=�5���Si/�ﻲH���^ �fO
|
1
|
+
ug;oFa�l��C�7vt}}�5�X�n��l�Q�6�^h��:tQ[���3d9%���@:B�/�1�����0�K�J�� �LU����o'y� O�{��.醠K\/���|�k<{p*P��)X��"k���1�c��`~!�V�7=��m�){3BT>���0��6+B�B�Q�w�q3��'ˇ%�.nYZ8�7��q�����u�]���`C4<C��ѿߨ!_���=YE�!�w��DŽ��ǒ�:X8�SL+�59����b��Ձ���,����2D?F���|\;�S����?����q��\������Ӝ2n���rP�7YVUԠ,z���xs��
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: async-http
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.80.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
@@ -58,7 +58,7 @@ cert_chain:
|
|
58
58
|
Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
|
59
59
|
voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
|
60
60
|
-----END CERTIFICATE-----
|
61
|
-
date: 2024-
|
61
|
+
date: 2024-10-02 00:00:00.000000000 Z
|
62
62
|
dependencies:
|
63
63
|
- !ruby/object:Gem::Dependency
|
64
64
|
name: async
|
@@ -136,28 +136,28 @@ dependencies:
|
|
136
136
|
requirements:
|
137
137
|
- - "~>"
|
138
138
|
- !ruby/object:Gem::Version
|
139
|
-
version: '0.
|
139
|
+
version: '0.27'
|
140
140
|
type: :runtime
|
141
141
|
prerelease: false
|
142
142
|
version_requirements: !ruby/object:Gem::Requirement
|
143
143
|
requirements:
|
144
144
|
- - "~>"
|
145
145
|
- !ruby/object:Gem::Version
|
146
|
-
version: '0.
|
146
|
+
version: '0.27'
|
147
147
|
- !ruby/object:Gem::Dependency
|
148
148
|
name: protocol-http2
|
149
149
|
requirement: !ruby/object:Gem::Requirement
|
150
150
|
requirements:
|
151
151
|
- - "~>"
|
152
152
|
- !ruby/object:Gem::Version
|
153
|
-
version: '0.
|
153
|
+
version: '0.19'
|
154
154
|
type: :runtime
|
155
155
|
prerelease: false
|
156
156
|
version_requirements: !ruby/object:Gem::Requirement
|
157
157
|
requirements:
|
158
158
|
- - "~>"
|
159
159
|
- !ruby/object:Gem::Version
|
160
|
-
version: '0.
|
160
|
+
version: '0.19'
|
161
161
|
- !ruby/object:Gem::Dependency
|
162
162
|
name: traces
|
163
163
|
requirement: !ruby/object:Gem::Requirement
|
metadata.gz.sig
CHANGED
Binary file
|