http3: add client-side HTTP Trailer support (#4581)

* http3: add HTTP Trailer support for clients

This change only adds support to read HTTP trailers sent to clients.

* chore: add protection against some out-of-spec behavior + tests

* chore: re-add test accidentally overwtitten

* chore: empty commit to re-trigger ci

* fix: address some review notes (wip)

* fix: simplify code in stream.Read by using a callback from requestStream.ReadResponse

* restructure where trailers are read and parsed

* WIP simplify trailer parsing design

* chore: refactor to use simpler trailer parsing strategy

* make gofumpt happy

* Update http3/headers.go

Co-authored-by: Marten Seemann <martenseemann@gmail.com>

* remove stray TODO

---------

Co-authored-by: Marten Seemann <martenseemann@gmail.com>
This commit is contained in:
Kevin McDonald
2024-08-23 07:25:58 +02:00
committed by GitHub
parent d067fe4156
commit 17fb3b96ba
8 changed files with 221 additions and 51 deletions

View File

@@ -309,7 +309,8 @@ var _ = Describe("Response", func() {
{Name: ":status", Value: "200"},
{Name: "content-length", Value: "42"},
}
rsp, err := responseFromHeaders(headers)
rsp := &http.Response{}
err := updateResponseFromHeaders(rsp, headers)
Expect(err).NotTo(HaveOccurred())
Expect(rsp.Proto).To(Equal("HTTP/3.0"))
Expect(rsp.ProtoMajor).To(Equal(3))
@@ -327,7 +328,7 @@ var _ = Describe("Response", func() {
{Name: "content-length", Value: "42"},
{Name: ":status", Value: "200"},
}
_, err := responseFromHeaders(headers)
err := updateResponseFromHeaders(&http.Response{}, headers)
Expect(err).To(MatchError("received pseudo header :status after a regular header field"))
})
@@ -335,7 +336,7 @@ var _ = Describe("Response", func() {
headers := []qpack.HeaderField{
{Name: "content-length", Value: "42"},
}
_, err := responseFromHeaders(headers)
err := updateResponseFromHeaders(&http.Response{}, headers)
Expect(err).To(MatchError("missing status field"))
})
@@ -344,7 +345,7 @@ var _ = Describe("Response", func() {
{Name: ":status", Value: "foobar"},
{Name: "content-length", Value: "42"},
}
_, err := responseFromHeaders(headers)
err := updateResponseFromHeaders(&http.Response{}, headers)
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("invalid status code"))
})
@@ -354,7 +355,7 @@ var _ = Describe("Response", func() {
{Name: ":status", Value: "404"},
{Name: ":method", Value: "GET"},
}
_, err := responseFromHeaders(headers)
err := updateResponseFromHeaders(&http.Response{}, headers)
Expect(err).To(MatchError("invalid response pseudo header: :method"))
})
})