Skip to content

Commit

Permalink
http3: only use :protocol pseudo-header for Extended CONNECT (#4261)
Browse files Browse the repository at this point in the history
* Fix protocol

The default value should be "HTTP/3.0".

* Reject normal request with :protocol header

The :protocol pseudo header is only defined for
Extended Connect requests (RFC 9220).

* save one branch check

* Fix review issue
  • Loading branch information
taoso committed Jan 26, 2024
1 parent d3974e1 commit 808f849
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 3 deletions.
10 changes: 7 additions & 3 deletions http3/headers.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,14 @@ func requestFromHeaders(headerFields []qpack.HeaderField) (*http.Request, error)
return nil, errors.New(":path, :authority and :method must not be empty")
}

if !isExtendedConnected && len(hdr.Protocol) > 0 {
return nil, errors.New(":protocol must be empty")
}

var u *url.URL
var requestURI string
var protocol string

protocol := "HTTP/3.0"

if isConnect {
u = &url.URL{}
Expand All @@ -137,15 +142,14 @@ func requestFromHeaders(headerFields []qpack.HeaderField) (*http.Request, error)
if err != nil {
return nil, err
}
protocol = hdr.Protocol
} else {
u.Path = hdr.Path
}
u.Scheme = hdr.Scheme
u.Host = hdr.Authority
requestURI = hdr.Authority
protocol = hdr.Protocol
} else {
protocol = "HTTP/3.0"
u, err = url.ParseRequestURI(hdr.Path)
if err != nil {
return nil, fmt.Errorf("invalid content length: %w", err)
Expand Down
12 changes: 12 additions & 0 deletions http3/headers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,17 @@ var _ = Describe("Request", func() {
Expect(err).To(MatchError(":path, :authority and :method must not be empty"))
})

It("errors with invalid protocol", func() {
headers := []qpack.HeaderField{
{Name: ":path", Value: "/foo"},
{Name: ":authority", Value: "quic.clemente.io"},
{Name: ":method", Value: "GET"},
{Name: ":protocol", Value: "connect-udp"},
}
_, err := requestFromHeaders(headers)
Expect(err).To(MatchError(":protocol must be empty"))
})

Context("regular HTTP CONNECT", func() {
It("handles CONNECT method", func() {
headers := []qpack.HeaderField{
Expand All @@ -221,6 +232,7 @@ var _ = Describe("Request", func() {
req, err := requestFromHeaders(headers)
Expect(err).NotTo(HaveOccurred())
Expect(req.Method).To(Equal(http.MethodConnect))
Expect(req.Proto).To(Equal("HTTP/3.0"))
Expect(req.RequestURI).To(Equal("quic.clemente.io"))
})

Expand Down

0 comments on commit 808f849

Please sign in to comment.