Skip to content

Commit c011cf8

Browse files
committed
Update trailers interface and handling of headers.
1 parent e649c63 commit c011cf8

File tree

7 files changed

+19
-12
lines changed

7 files changed

+19
-12
lines changed

async-http.gemspec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ Gem::Specification.new do |spec|
2121
spec.add_dependency("async-io", "~> 1.28")
2222
spec.add_dependency("async-pool", "~> 0.2")
2323

24-
spec.add_dependency("protocol-http", "~> 0.17.0")
25-
spec.add_dependency("protocol-http1", "~> 0.11.0")
24+
spec.add_dependency("protocol-http", "~> 0.18.0")
25+
spec.add_dependency("protocol-http1", "~> 0.12.0")
2626
spec.add_dependency("protocol-http2", "~> 0.13.0")
2727

2828
# spec.add_dependency("openssl")

lib/async/http/internet.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def initialize(**options)
3333
@options = options
3434
end
3535

36-
def call(method, url, headers = [], body = nil)
36+
def call(method, url, headers = nil, body = nil)
3737
endpoint = Endpoint.parse(url)
3838
key = host_key(endpoint)
3939

@@ -42,6 +42,7 @@ def call(method, url, headers = [], body = nil)
4242
end
4343

4444
body = Body::Buffered.wrap(body)
45+
headers = ::Protocol::HTTP::Headers[headers]
4546

4647
request = ::Protocol::HTTP::Request.new(client.scheme, endpoint.authority, method, endpoint.path, nil, headers, body)
4748

lib/async/http/protocol/http1/client.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ class Client < Connection
3131
def call(request, task: Task.current)
3232
Async.logger.debug(self) {"#{request.method} #{request.path} #{request.headers.inspect}"}
3333

34+
trailers = request.headers.trailers!
35+
3436
# We carefully interpret https://tools.ietf.org/html/rfc7230#section-6.3.1 to implement this correctly.
3537
begin
3638
write_request(request.authority, request.method, request.path, @version, request.headers)
@@ -39,8 +41,6 @@ def call(request, task: Task.current)
3941
raise RequestFailed
4042
end
4143

42-
request.headers.trailers!
43-
4444
if request.body?
4545
body = request.body
4646

@@ -63,7 +63,7 @@ def call(request, task: Task.current)
6363
subtask.annotate("Streaming body.")
6464

6565
# 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.
66-
write_body(@version, body, false, request.trailers)
66+
write_body(@version, body, false, trailers)
6767
end
6868
end
6969
elsif protocol = request.protocol

lib/async/http/protocol/http1/server.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,9 @@ def each(task: Task.current)
6060
return if @stream.nil? or @stream.closed?
6161

6262
if response
63+
trailers = response.headers.trailers!
64+
6365
write_response(@version, response.status, response.headers)
64-
response.headers.trailers!
6566

6667
body = response.body
6768

@@ -85,7 +86,6 @@ def each(task: Task.current)
8586
body.call(stream)
8687
else
8788
head = request.head?
88-
trailers = response.trailers
8989

9090
request = nil unless body
9191
response = nil

lib/async/http/protocol/http2/request.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,12 @@ def send_response(response)
183183
headers = ::Protocol::HTTP::Headers::Merged.new(protocol_headers, response.headers)
184184

185185
if body = response.body and !self.head?
186+
# This function informs the headers object that any subsequent headers are going to be trailers. Therefore, it must be called *before* sending the headers, to avoid any race conditions.
187+
trailers = response.headers.trailers!
188+
186189
@stream.send_headers(nil, headers)
187-
@stream.send_body(body, response.trailers)
190+
191+
@stream.send_body(body, trailers)
188192
else
189193
# Ensure the response body is closed if we are ending the stream:
190194
response.close

lib/async/http/protocol/http2/response.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,13 +215,16 @@ def send_request(request)
215215
if request.body.nil?
216216
@stream.send_headers(nil, headers, ::Protocol::HTTP2::END_STREAM)
217217
else
218+
# This function informs the headers object that any subsequent headers are going to be trailers. Therefore, it must be called *before* sending the headers, to avoid any race conditions.
219+
trailers = request.headers.trailers!
220+
218221
begin
219222
@stream.send_headers(nil, headers)
220223
rescue
221224
raise RequestFailed
222225
end
223226

224-
@stream.send_body(request.body, request.trailers)
227+
@stream.send_body(request.body, trailers)
225228
end
226229
end
227230
end

lib/async/http/protocol/http2/stream.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,6 @@ def add_header(key, value)
6161
end
6262

6363
def receive_trailing_headers(headers, end_stream)
64-
@headers.trailers!
65-
6664
headers.each do |key, value|
6765
if @trailers.include?(key)
6866
add_header(key, value)
@@ -76,6 +74,7 @@ def process_headers(frame)
7674
if @headers.nil?
7775
@headers = ::Protocol::HTTP::Headers.new
7876
self.receive_initial_headers(super, frame.end_stream?)
77+
7978
@trailers = @headers[TRAILERS]
8079
elsif @trailers and frame.end_stream?
8180
self.receive_trailing_headers(super, frame.end_stream?)

0 commit comments

Comments
 (0)