async-http 0.76.0 → 0.78.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/bake/async/http/h2spec.rb +6 -6
- data/bake/async/http.rb +3 -3
- data/lib/async/http/body/hijack.rb +4 -4
- data/lib/async/http/body/pipe.rb +1 -1
- data/lib/async/http/body/writable.rb +3 -3
- data/lib/async/http/body.rb +3 -3
- data/lib/async/http/client.rb +15 -18
- data/lib/async/http/endpoint.rb +10 -10
- data/lib/async/http/internet/instance.rb +1 -1
- data/lib/async/http/internet.rb +5 -5
- data/lib/async/http/middleware/location_redirector.rb +8 -8
- data/lib/async/http/mock/endpoint.rb +2 -2
- data/lib/async/http/mock.rb +1 -1
- data/lib/async/http/protocol/http.rb +2 -2
- data/lib/async/http/protocol/http1/client.rb +19 -6
- data/lib/async/http/protocol/http1/connection.rb +6 -7
- data/lib/async/http/protocol/http1/finishable.rb +58 -0
- data/lib/async/http/protocol/http1/request.rb +3 -3
- data/lib/async/http/protocol/http1/response.rb +10 -2
- data/lib/async/http/protocol/http1/server.rb +38 -15
- data/lib/async/http/protocol/http1.rb +3 -3
- data/lib/async/http/protocol/http10.rb +1 -1
- data/lib/async/http/protocol/http11.rb +1 -1
- data/lib/async/http/protocol/http2/client.rb +4 -4
- data/lib/async/http/protocol/http2/connection.rb +12 -12
- data/lib/async/http/protocol/http2/input.rb +2 -2
- data/lib/async/http/protocol/http2/output.rb +2 -2
- data/lib/async/http/protocol/http2/request.rb +4 -4
- data/lib/async/http/protocol/http2/response.rb +14 -4
- data/lib/async/http/protocol/http2/server.rb +3 -3
- data/lib/async/http/protocol/http2/stream.rb +12 -4
- data/lib/async/http/protocol/http2.rb +3 -3
- data/lib/async/http/protocol/https.rb +3 -3
- data/lib/async/http/protocol/request.rb +7 -3
- data/lib/async/http/protocol/response.rb +7 -3
- data/lib/async/http/protocol.rb +3 -3
- data/lib/async/http/proxy.rb +4 -3
- data/lib/async/http/reference.rb +2 -2
- data/lib/async/http/relative_location.rb +1 -1
- data/lib/async/http/server.rb +13 -13
- data/lib/async/http/statistics.rb +4 -4
- data/lib/async/http/version.rb +1 -1
- data/lib/async/http.rb +5 -5
- data/readme.md +11 -0
- data/releases.md +11 -0
- data.tar.gz.sig +0 -0
- metadata +7 -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: 76e78af8d20808d557b1c13c850af0a268de5535726ba07708b2012eb8752029
|
4
|
+
data.tar.gz: 53bdf9b950394a03ca8c1fd47befe51e8ba51a5cce82aa47c01111df7efd21b4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 43c49b50bb88955088b74926e3fe33310f38f4b09d9b9ecdc538a9835c9be5b8be0e172e09794324a53db99e09b0102ae96fc179af13578a758f42644d6f4011
|
7
|
+
data.tar.gz: fa1a0d97f326bdd72010f07cfe21004b0da8f75fe4556778bd3b918f42e2e85f22bc41cd07e2a64b4395540e531a879480e634a8fe401ee0d0d7c146af8b61d7
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/bake/async/http/h2spec.rb
CHANGED
@@ -21,12 +21,12 @@ end
|
|
21
21
|
private
|
22
22
|
|
23
23
|
def server
|
24
|
-
require
|
25
|
-
require
|
26
|
-
require
|
27
|
-
require
|
24
|
+
require "async"
|
25
|
+
require "async/container"
|
26
|
+
require "async/http/server"
|
27
|
+
require "io/endpoint/host_endpoint"
|
28
28
|
|
29
|
-
endpoint = IO::Endpoint.tcp(
|
29
|
+
endpoint = IO::Endpoint.tcp("127.0.0.1", 7272)
|
30
30
|
|
31
31
|
container = Async::Container.new
|
32
32
|
|
@@ -34,7 +34,7 @@ def server
|
|
34
34
|
|
35
35
|
container.run(count: 1) do
|
36
36
|
server = Async::HTTP::Server.for(endpoint, protocol: Async::HTTP::Protocol::HTTP2, scheme: "https") do |request|
|
37
|
-
Protocol::HTTP::Response[200, {
|
37
|
+
Protocol::HTTP::Response[200, {"content-type" => "text/plain"}, ["Hello World"]]
|
38
38
|
end
|
39
39
|
|
40
40
|
Async do
|
data/bake/async/http.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
|
-
# Copyright, 2020-
|
4
|
+
# Copyright, 2020-2024, by Samuel Williams.
|
5
5
|
|
6
6
|
# Fetch the specified URL and print the response.
|
7
7
|
# @param url [String] the URL to parse and fetch.
|
8
8
|
# @param method [String] the HTTP method to use.
|
9
9
|
def fetch(url, method:)
|
10
|
-
require
|
11
|
-
require
|
10
|
+
require "async/http/internet"
|
11
|
+
require "kernel/sync"
|
12
12
|
|
13
13
|
terminal = Console::Terminal.for($stdout)
|
14
14
|
terminal[:request] = terminal.style(:blue, nil, :bold)
|
@@ -1,12 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
|
-
# Copyright, 2019-
|
4
|
+
# Copyright, 2019-2024, by Samuel Williams.
|
5
5
|
|
6
|
-
require
|
7
|
-
require
|
6
|
+
require "protocol/http/body/readable"
|
7
|
+
require "protocol/http/body/stream"
|
8
8
|
|
9
|
-
require_relative
|
9
|
+
require_relative "writable"
|
10
10
|
|
11
11
|
module Async
|
12
12
|
module HTTP
|
data/lib/async/http/body/pipe.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
|
-
# Copyright, 2018-
|
4
|
+
# Copyright, 2018-2024, by Samuel Williams.
|
5
5
|
|
6
|
-
require
|
7
|
-
require
|
6
|
+
require "protocol/http/body/writable"
|
7
|
+
require "async/queue"
|
8
8
|
|
9
9
|
module Async
|
10
10
|
module HTTP
|
data/lib/async/http/body.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
|
-
# Copyright, 2018-
|
4
|
+
# Copyright, 2018-2024, by Samuel Williams.
|
5
5
|
|
6
|
-
require
|
7
|
-
require_relative
|
6
|
+
require "protocol/http/body/buffered"
|
7
|
+
require_relative "body/writable"
|
8
8
|
|
9
9
|
module Async
|
10
10
|
module HTTP
|
data/lib/async/http/client.rb
CHANGED
@@ -4,16 +4,16 @@
|
|
4
4
|
# Copyright, 2017-2024, by Samuel Williams.
|
5
5
|
# Copyright, 2022, by Ian Ker-Seymer.
|
6
6
|
|
7
|
-
require
|
7
|
+
require "io/endpoint"
|
8
8
|
|
9
|
-
require
|
9
|
+
require "async/pool/controller"
|
10
10
|
|
11
|
-
require
|
12
|
-
require
|
11
|
+
require "protocol/http/body/completable"
|
12
|
+
require "protocol/http/methods"
|
13
13
|
|
14
|
-
require
|
14
|
+
require "traces/provider"
|
15
15
|
|
16
|
-
require_relative
|
16
|
+
require_relative "protocol"
|
17
17
|
|
18
18
|
module Async
|
19
19
|
module HTTP
|
@@ -140,7 +140,7 @@ module Async
|
|
140
140
|
def inspect
|
141
141
|
"#<#{self.class} authority=#{@authority.inspect}>"
|
142
142
|
end
|
143
|
-
|
143
|
+
|
144
144
|
Traces::Provider(self) do
|
145
145
|
def call(request)
|
146
146
|
attributes = {
|
@@ -151,30 +151,30 @@ module Async
|
|
151
151
|
}
|
152
152
|
|
153
153
|
if protocol = request.protocol
|
154
|
-
attributes[
|
154
|
+
attributes["http.protocol"] = protocol
|
155
155
|
end
|
156
156
|
|
157
157
|
if length = request.body&.length
|
158
|
-
attributes[
|
158
|
+
attributes["http.request.length"] = length
|
159
159
|
end
|
160
160
|
|
161
|
-
Traces.trace(
|
161
|
+
Traces.trace("async.http.client.call", attributes: attributes) do |span|
|
162
162
|
if context = Traces.trace_context
|
163
|
-
request.headers[
|
163
|
+
request.headers["traceparent"] = context.to_s
|
164
164
|
# request.headers['tracestate'] = context.state
|
165
165
|
end
|
166
166
|
|
167
167
|
super.tap do |response|
|
168
168
|
if version = response&.version
|
169
|
-
span[
|
169
|
+
span["http.version"] = version
|
170
170
|
end
|
171
171
|
|
172
172
|
if status = response&.status
|
173
|
-
span[
|
173
|
+
span["http.status_code"] = status
|
174
174
|
end
|
175
175
|
|
176
176
|
if length = response.body&.length
|
177
|
-
span[
|
177
|
+
span["http.response.length"] = length
|
178
178
|
end
|
179
179
|
end
|
180
180
|
end
|
@@ -186,10 +186,7 @@ module Async
|
|
186
186
|
def make_response(request, connection)
|
187
187
|
response = request.call(connection)
|
188
188
|
|
189
|
-
|
190
|
-
::Protocol::HTTP::Body::Completable.wrap(response) do
|
191
|
-
@pool.release(connection)
|
192
|
-
end
|
189
|
+
response.pool = @pool
|
193
190
|
|
194
191
|
return response
|
195
192
|
end
|
data/lib/async/http/endpoint.rb
CHANGED
@@ -7,22 +7,22 @@
|
|
7
7
|
# Copyright, 2024, by Igor Sidorov.
|
8
8
|
# Copyright, 2024, by Hal Brodigan.
|
9
9
|
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
10
|
+
require "io/endpoint"
|
11
|
+
require "io/endpoint/host_endpoint"
|
12
|
+
require "io/endpoint/ssl_endpoint"
|
13
13
|
|
14
|
-
require_relative
|
15
|
-
require_relative
|
14
|
+
require_relative "protocol/http"
|
15
|
+
require_relative "protocol/https"
|
16
16
|
|
17
17
|
module Async
|
18
18
|
module HTTP
|
19
19
|
# Represents a way to connect to a remote HTTP server.
|
20
20
|
class Endpoint < ::IO::Endpoint::Generic
|
21
21
|
SCHEMES = {
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
"http" => URI::HTTP,
|
23
|
+
"https" => URI::HTTPS,
|
24
|
+
"ws" => URI::WS,
|
25
|
+
"wss" => URI::WSS,
|
26
26
|
}
|
27
27
|
|
28
28
|
def self.parse(string, endpoint = nil, **options)
|
@@ -102,7 +102,7 @@ module Async
|
|
102
102
|
end
|
103
103
|
|
104
104
|
def secure?
|
105
|
-
[
|
105
|
+
["https", "wss"].include?(self.scheme)
|
106
106
|
end
|
107
107
|
|
108
108
|
def protocol
|
data/lib/async/http/internet.rb
CHANGED
@@ -4,12 +4,12 @@
|
|
4
4
|
# Copyright, 2018-2024, by Samuel Williams.
|
5
5
|
# Copyright, 2024, by Igor Sidorov.
|
6
6
|
|
7
|
-
require_relative
|
8
|
-
require_relative
|
7
|
+
require_relative "client"
|
8
|
+
require_relative "endpoint"
|
9
9
|
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
10
|
+
require "protocol/http/middleware"
|
11
|
+
require "protocol/http/body/buffered"
|
12
|
+
require "protocol/http/accept_encoding"
|
13
13
|
|
14
14
|
module Async
|
15
15
|
module HTTP
|
@@ -3,10 +3,10 @@
|
|
3
3
|
# Released under the MIT License.
|
4
4
|
# Copyright, 2024, by Samuel Williams.
|
5
5
|
|
6
|
-
require_relative
|
6
|
+
require_relative "../reference"
|
7
7
|
|
8
|
-
require
|
9
|
-
require
|
8
|
+
require "protocol/http/middleware"
|
9
|
+
require "protocol/http/body/rewindable"
|
10
10
|
|
11
11
|
module Async
|
12
12
|
module HTTP
|
@@ -34,10 +34,10 @@ module Async
|
|
34
34
|
|
35
35
|
# Header keys which should be deleted when changing a request from a POST to a GET as defined by <https://fetch.spec.whatwg.org/#request-body-header-name>.
|
36
36
|
PROHIBITED_GET_HEADERS = [
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
37
|
+
"content-encoding",
|
38
|
+
"content-language",
|
39
|
+
"content-location",
|
40
|
+
"content-type",
|
41
41
|
]
|
42
42
|
|
43
43
|
# maximum_hops is the max number of redirects. Set to 0 to allow 1 request with no redirects.
|
@@ -91,7 +91,7 @@ module Async
|
|
91
91
|
hops += 1
|
92
92
|
|
93
93
|
# Get the redirect location:
|
94
|
-
unless location = response.headers[
|
94
|
+
unless location = response.headers["location"]
|
95
95
|
return response
|
96
96
|
end
|
97
97
|
|
data/lib/async/http/mock.rb
CHANGED
@@ -3,18 +3,32 @@
|
|
3
3
|
# Released under the MIT License.
|
4
4
|
# Copyright, 2018-2024, by Samuel Williams.
|
5
5
|
|
6
|
-
require_relative
|
6
|
+
require_relative "connection"
|
7
7
|
|
8
8
|
module Async
|
9
9
|
module HTTP
|
10
10
|
module Protocol
|
11
11
|
module HTTP1
|
12
12
|
class Client < Connection
|
13
|
+
def initialize(...)
|
14
|
+
super
|
15
|
+
|
16
|
+
@pool = nil
|
17
|
+
end
|
18
|
+
|
19
|
+
attr_accessor :pool
|
20
|
+
|
21
|
+
def closed!
|
22
|
+
super
|
23
|
+
|
24
|
+
if pool = @pool
|
25
|
+
@pool = nil
|
26
|
+
pool.release(self)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
13
30
|
# Used by the client to send requests to the remote server.
|
14
31
|
def call(request, task: Task.current)
|
15
|
-
# We need to keep track of connections which are not in the initial "ready" state.
|
16
|
-
@ready = false
|
17
|
-
|
18
32
|
Console.logger.debug(self) {"#{request.method} #{request.path} #{request.headers.inspect}"}
|
19
33
|
|
20
34
|
# Mark the start of the trailers:
|
@@ -54,12 +68,11 @@ module Async
|
|
54
68
|
end
|
55
69
|
|
56
70
|
response = Response.read(self, request)
|
57
|
-
@ready = true
|
58
71
|
|
59
72
|
return response
|
60
73
|
rescue
|
61
74
|
# This will ensure that #reusable? returns false.
|
62
|
-
|
75
|
+
self.close
|
63
76
|
|
64
77
|
raise
|
65
78
|
end
|
@@ -3,10 +3,10 @@
|
|
3
3
|
# Released under the MIT License.
|
4
4
|
# Copyright, 2018-2024, by Samuel Williams.
|
5
5
|
|
6
|
-
require
|
6
|
+
require "protocol/http1"
|
7
7
|
|
8
|
-
require_relative
|
9
|
-
require_relative
|
8
|
+
require_relative "request"
|
9
|
+
require_relative "response"
|
10
10
|
|
11
11
|
module Async
|
12
12
|
module HTTP
|
@@ -16,12 +16,11 @@ module Async
|
|
16
16
|
def initialize(stream, version)
|
17
17
|
super(stream)
|
18
18
|
|
19
|
-
@ready = true
|
20
19
|
@version = version
|
21
20
|
end
|
22
21
|
|
23
22
|
def to_s
|
24
|
-
"\#<#{self.class} negotiated #{@version},
|
23
|
+
"\#<#{self.class} negotiated #{@version}, #{@state}>"
|
25
24
|
end
|
26
25
|
|
27
26
|
def as_json(...)
|
@@ -62,11 +61,11 @@ module Async
|
|
62
61
|
|
63
62
|
# Can we use this connection to make requests?
|
64
63
|
def viable?
|
65
|
-
|
64
|
+
self.idle? && @stream&.readable?
|
66
65
|
end
|
67
66
|
|
68
67
|
def reusable?
|
69
|
-
@
|
68
|
+
@persistent && @stream && !@stream.closed?
|
70
69
|
end
|
71
70
|
end
|
72
71
|
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2024, by Samuel Williams.
|
5
|
+
|
6
|
+
require "protocol/http/body/wrapper"
|
7
|
+
require "async/variable"
|
8
|
+
|
9
|
+
module Async
|
10
|
+
module HTTP
|
11
|
+
module Protocol
|
12
|
+
module HTTP1
|
13
|
+
# Keeps track of whether a body is being read, and if so, waits for it to be closed.
|
14
|
+
class Finishable < ::Protocol::HTTP::Body::Wrapper
|
15
|
+
def initialize(body)
|
16
|
+
super(body)
|
17
|
+
|
18
|
+
@closed = Async::Variable.new
|
19
|
+
@error = nil
|
20
|
+
|
21
|
+
@reading = false
|
22
|
+
end
|
23
|
+
|
24
|
+
def reading?
|
25
|
+
@reading
|
26
|
+
end
|
27
|
+
|
28
|
+
def read
|
29
|
+
@reading = true
|
30
|
+
|
31
|
+
super
|
32
|
+
end
|
33
|
+
|
34
|
+
def close(error = nil)
|
35
|
+
unless @closed.resolved?
|
36
|
+
@error = error
|
37
|
+
@closed.value = true
|
38
|
+
end
|
39
|
+
|
40
|
+
super
|
41
|
+
end
|
42
|
+
|
43
|
+
def wait
|
44
|
+
if @reading
|
45
|
+
@closed.wait
|
46
|
+
else
|
47
|
+
self.discard
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def inspect
|
52
|
+
"#<#{self.class} closed=#{@closed} error=#{@error}> | #{super}"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
# Released under the MIT License.
|
4
4
|
# Copyright, 2018-2024, by Samuel Williams.
|
5
5
|
|
6
|
-
require_relative
|
6
|
+
require_relative "../request"
|
7
7
|
|
8
8
|
module Async
|
9
9
|
module HTTP
|
@@ -16,13 +16,13 @@ module Async
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
UPGRADE =
|
19
|
+
UPGRADE = "upgrade"
|
20
20
|
|
21
21
|
def initialize(connection, authority, method, path, version, headers, body)
|
22
22
|
@connection = connection
|
23
23
|
|
24
24
|
# HTTP/1 requests with an upgrade header (which can contain zero or more values) are extracted into the protocol field of the request, and we expect a response to select one of those protocols with a status code of 101 Switching Protocols.
|
25
|
-
protocol = headers.delete(
|
25
|
+
protocol = headers.delete("upgrade")
|
26
26
|
|
27
27
|
super(nil, authority, method, path, version, headers, body, protocol, self.public_method(:write_interim_response))
|
28
28
|
end
|
@@ -4,7 +4,7 @@
|
|
4
4
|
# Copyright, 2018-2024, by Samuel Williams.
|
5
5
|
# Copyright, 2023, by Josh Huber.
|
6
6
|
|
7
|
-
require_relative
|
7
|
+
require_relative "../response"
|
8
8
|
|
9
9
|
module Async
|
10
10
|
module HTTP
|
@@ -23,7 +23,7 @@ module Async
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
UPGRADE =
|
26
|
+
UPGRADE = "upgrade"
|
27
27
|
|
28
28
|
# @attribute [String] The HTTP response line reason.
|
29
29
|
attr :reason
|
@@ -39,6 +39,14 @@ module Async
|
|
39
39
|
super(version, status, headers, body, protocol)
|
40
40
|
end
|
41
41
|
|
42
|
+
def pool=(pool)
|
43
|
+
if @connection.idle? or @connection.closed?
|
44
|
+
pool.release(@connection)
|
45
|
+
else
|
46
|
+
@connection.pool = pool
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
42
50
|
def connection
|
43
51
|
@connection
|
44
52
|
end
|
@@ -6,24 +6,43 @@
|
|
6
6
|
# Copyright, 2023, by Thomas Morgan.
|
7
7
|
# Copyright, 2024, by Anton Zhuravsky.
|
8
8
|
|
9
|
-
require_relative
|
10
|
-
|
9
|
+
require_relative "connection"
|
10
|
+
require_relative "finishable"
|
11
|
+
|
12
|
+
require "console/event/failure"
|
11
13
|
|
12
14
|
module Async
|
13
15
|
module HTTP
|
14
16
|
module Protocol
|
15
17
|
module HTTP1
|
16
18
|
class Server < Connection
|
19
|
+
def initialize(...)
|
20
|
+
super
|
21
|
+
|
22
|
+
@ready = Async::Notification.new
|
23
|
+
end
|
24
|
+
|
25
|
+
def closed!
|
26
|
+
super
|
27
|
+
|
28
|
+
@ready.signal
|
29
|
+
end
|
30
|
+
|
17
31
|
def fail_request(status)
|
18
32
|
@persistent = false
|
19
33
|
write_response(@version, status, {})
|
20
34
|
write_body(@version, nil)
|
21
35
|
rescue => error
|
22
36
|
# At this point, there is very little we can do to recover:
|
23
|
-
Console::Event::Failure.for(error).emit(self, "Failed to write failure response
|
37
|
+
Console::Event::Failure.for(error).emit(self, "Failed to write failure response!", severity: :debug)
|
24
38
|
end
|
25
39
|
|
26
40
|
def next_request
|
41
|
+
# Wait for the connection to become idle before reading the next request:
|
42
|
+
unless idle?
|
43
|
+
@ready.wait
|
44
|
+
end
|
45
|
+
|
27
46
|
# The default is true.
|
28
47
|
return unless @persistent
|
29
48
|
|
@@ -35,7 +54,7 @@ module Async
|
|
35
54
|
end
|
36
55
|
|
37
56
|
return request
|
38
|
-
rescue ::Protocol::HTTP1::BadRequest
|
57
|
+
rescue ::Protocol::HTTP1::BadRequest => error
|
39
58
|
fail_request(400)
|
40
59
|
# Conceivably we could retry here, but we don't really know how bad the error is, so it's better to just fail:
|
41
60
|
raise
|
@@ -46,7 +65,13 @@ module Async
|
|
46
65
|
task.annotate("Reading #{self.version} requests for #{self.class}.")
|
47
66
|
|
48
67
|
while request = next_request
|
68
|
+
if body = request.body
|
69
|
+
finishable = Finishable.new(body)
|
70
|
+
request.body = finishable
|
71
|
+
end
|
72
|
+
|
49
73
|
response = yield(request, self)
|
74
|
+
version = request.version
|
50
75
|
body = response&.body
|
51
76
|
|
52
77
|
if hijacked?
|
@@ -77,7 +102,7 @@ module Async
|
|
77
102
|
# 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.
|
78
103
|
write_response(@version, response.status, response.headers)
|
79
104
|
|
80
|
-
stream = write_tunnel_body(
|
105
|
+
stream = write_tunnel_body(version)
|
81
106
|
|
82
107
|
# Same as above:
|
83
108
|
request = nil
|
@@ -89,7 +114,7 @@ module Async
|
|
89
114
|
write_response(@version, response.status, response.headers)
|
90
115
|
|
91
116
|
if request.connect? and response.success?
|
92
|
-
stream = write_tunnel_body(
|
117
|
+
stream = write_tunnel_body(version)
|
93
118
|
|
94
119
|
# Same as above:
|
95
120
|
request = nil
|
@@ -99,29 +124,27 @@ module Async
|
|
99
124
|
return body.call(stream)
|
100
125
|
else
|
101
126
|
head = request.head?
|
102
|
-
version = request.version
|
103
127
|
|
104
128
|
# Same as above:
|
105
|
-
request = nil
|
129
|
+
request = nil
|
106
130
|
response = nil
|
107
131
|
|
108
132
|
write_body(version, body, head, trailer)
|
109
133
|
end
|
110
134
|
end
|
111
135
|
|
112
|
-
# We are done with the body
|
136
|
+
# We are done with the body:
|
113
137
|
body = nil
|
114
138
|
else
|
115
139
|
# If the request failed to generate a response, it was an internal server error:
|
116
140
|
write_response(@version, 500, {})
|
117
|
-
write_body(
|
141
|
+
write_body(version, nil)
|
142
|
+
|
143
|
+
request&.finish
|
118
144
|
end
|
119
145
|
|
120
|
-
#
|
121
|
-
|
122
|
-
|
123
|
-
# This ensures we yield at least once every iteration of the loop and allow other fibers to execute.
|
124
|
-
task.yield
|
146
|
+
# Discard or wait for the input body to be consumed:
|
147
|
+
finishable&.wait
|
125
148
|
rescue => error
|
126
149
|
raise
|
127
150
|
ensure
|