async-http 0.78.0 → 0.80.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|