Skip to content

Commit d20c764

Browse files
committed
Send stream reset on invalid trailer.
1 parent b0113cc commit d20c764

File tree

4 files changed

+77
-1
lines changed

4 files changed

+77
-1
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ def process_headers(frame)
6464
if @input and frame.end_stream?
6565
@input.close_write
6666
end
67+
rescue ::Protocol::HTTP::InvalidTrailerError => error
68+
Console.warn(self, error)
69+
70+
send_reset_stream(::Protocol::HTTP2::Error::PROTOCOL_ERROR)
6771
rescue ::Protocol::HTTP2::HeaderError => error
6872
Console.debug(self, "Error while processing headers!", error)
6973

releases.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## v0.92.2
44

5-
- Better handling of trailers.
5+
- Better handling of trailers. If invalid trailers are received, the connection (HTTP/1) or stream (HTTP/2) is reset.
66

77
## v0.92.0
88

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# frozen_string_literal: true
2+
3+
# Released under the MIT License.
4+
# Copyright, 2026, by Samuel Williams.
5+
6+
require "async/http/protocol/http2"
7+
require "async/http/a_protocol"
8+
9+
describe Async::HTTP::Protocol::HTTP11 do
10+
include Sus::Fixtures::Async::HTTP::ServerContext
11+
12+
let(:protocol) {subject}
13+
14+
with "invalid trailers" do
15+
let(:app) do
16+
Protocol::HTTP::Middleware.for do |request|
17+
Protocol::HTTP::Response[200, [], request.body]
18+
end
19+
end
20+
21+
it "rejects host header as trailer" do
22+
headers = ::Protocol::HTTP::Headers.new([["host", "example.com"]], 0)
23+
24+
body = Async::HTTP::Body::Writable.new
25+
26+
response = client.post("/", headers, body)
27+
28+
body.write("Hello world!")
29+
body.close_write
30+
31+
expect do
32+
response.read
33+
end.to raise_exception(EOFError)
34+
end
35+
end
36+
end
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# frozen_string_literal: true
2+
3+
# Released under the MIT License.
4+
# Copyright, 2026, by Samuel Williams.
5+
6+
require "async/http/protocol/http2"
7+
require "async/http/a_protocol"
8+
9+
describe Async::HTTP::Protocol::HTTP2 do
10+
include Sus::Fixtures::Async::HTTP::ServerContext
11+
12+
let(:protocol) {subject}
13+
14+
with "invalid trailers" do
15+
let(:app) do
16+
Protocol::HTTP::Middleware.for do |request|
17+
Protocol::HTTP::Response[200, [], request.body]
18+
end
19+
end
20+
21+
it "rejects host header as trailer" do
22+
headers = ::Protocol::HTTP::Headers.new([["host", "example.com"]], 0)
23+
24+
body = Async::HTTP::Body::Writable.new
25+
26+
response = client.post("/", headers, body)
27+
28+
body.write("Hello world!")
29+
body.close_write
30+
31+
expect do
32+
response.read
33+
end.to raise_exception(Protocol::HTTP2::StreamError)
34+
end
35+
end
36+
end

0 commit comments

Comments
 (0)