mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-03 04:07:35 +03:00
http3: enforce ordering requirement between pseudo and regular headers (#3968)
* http3: enforce ordering requirement between pseudo and regular headers * simplify logic
This commit is contained in:
parent
4378283f95
commit
514df55288
2 changed files with 24 additions and 3 deletions
|
@ -17,6 +17,7 @@ func requestFromHeaders(headers []qpack.HeaderField) (*http.Request, error) {
|
|||
var path, authority, method, protocol, scheme, contentLengthStr string
|
||||
|
||||
httpHeaders := http.Header{}
|
||||
var readFirstRegularHeader bool
|
||||
for _, h := range headers {
|
||||
// field names need to be lowercase, see section 4.2 of RFC 9114
|
||||
if strings.ToLower(h.Name) != h.Name {
|
||||
|
@ -25,6 +26,18 @@ func requestFromHeaders(headers []qpack.HeaderField) (*http.Request, error) {
|
|||
if !httpguts.ValidHeaderFieldValue(h.Value) {
|
||||
return nil, fmt.Errorf("invalid header field value for %s: %q", h.Name, h.Value)
|
||||
}
|
||||
if h.IsPseudo() {
|
||||
if readFirstRegularHeader {
|
||||
// all pseudo headers must appear before regular header fields, see section 4.3 of RFC 9114
|
||||
return nil, fmt.Errorf("received pseudo header %s after a regular header field", h.Name)
|
||||
}
|
||||
} else {
|
||||
if !httpguts.ValidHeaderFieldName(h.Name) {
|
||||
return nil, fmt.Errorf("invalid header field name: %q", h.Name)
|
||||
}
|
||||
readFirstRegularHeader = true
|
||||
}
|
||||
|
||||
switch h.Name {
|
||||
case ":path":
|
||||
path = h.Value
|
||||
|
@ -40,9 +53,6 @@ func requestFromHeaders(headers []qpack.HeaderField) (*http.Request, error) {
|
|||
contentLengthStr = h.Value
|
||||
default:
|
||||
if !h.IsPseudo() {
|
||||
if !httpguts.ValidHeaderFieldName(h.Name) {
|
||||
return nil, fmt.Errorf("invalid header field name: %q", h.Name)
|
||||
}
|
||||
httpHeaders.Add(h.Name, h.Value)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,6 +66,17 @@ var _ = Describe("Request", func() {
|
|||
Expect(err).To(MatchError(`invalid header field value for content: "\n"`))
|
||||
})
|
||||
|
||||
It("rejects pseudo header fields after regular header fields", func() {
|
||||
headers := []qpack.HeaderField{
|
||||
{Name: ":path", Value: "/foo"},
|
||||
{Name: "content-length", Value: "42"},
|
||||
{Name: ":authority", Value: "quic.clemente.io"},
|
||||
{Name: ":method", Value: "GET"},
|
||||
}
|
||||
_, err := requestFromHeaders(headers)
|
||||
Expect(err).To(MatchError("received pseudo header :authority after a regular header field"))
|
||||
})
|
||||
|
||||
It("rejects negative Content-Length values", func() {
|
||||
headers := []qpack.HeaderField{
|
||||
{Name: ":path", Value: "/foo"},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue