From bbf0200c0ae1d019439da7c2915c5f883ede4d61 Mon Sep 17 00:00:00 2001 From: gaowenju Date: Thu, 30 Nov 2023 17:51:37 +0800 Subject: [PATCH] optimize: stop parse the header if encounter a invalid char --- go.mod | 1 + go.sum | 2 ++ pkg/protocol/http1/req/header.go | 20 +++++++++++++++++++- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 3619b833d..509c88136 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,7 @@ require ( github.com/cloudwego/netpoll v0.5.0 github.com/fsnotify/fsnotify v1.5.4 github.com/tidwall/gjson v1.14.4 + golang.org/x/net v0.0.0-20190311183353-d8887717615a golang.org/x/sync v0.0.0-20210220032951-036812b2e83c golang.org/x/sys v0.0.0-20220412211240-33da011f77ad google.golang.org/protobuf v1.27.1 diff --git a/go.sum b/go.sum index 3cf3c2f96..26da89b19 100644 --- a/go.sum +++ b/go.sum @@ -64,6 +64,7 @@ golang.org/x/arch v0.0.0-20201008161808-52c3e6f60cff/go.mod h1:flIaEI6LNU6xOCD5P golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -71,6 +72,7 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20220110181412-a018aaa089fe/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= diff --git a/pkg/protocol/http1/req/header.go b/pkg/protocol/http1/req/header.go index 4d571a304..c1250eb8a 100644 --- a/pkg/protocol/http1/req/header.go +++ b/pkg/protocol/http1/req/header.go @@ -47,6 +47,7 @@ import ( "fmt" "io" + "github.com/cloudwego/hertz/internal/bytesconv" "github.com/cloudwego/hertz/internal/bytestr" errs "github.com/cloudwego/hertz/pkg/common/errors" "github.com/cloudwego/hertz/pkg/common/utils" @@ -165,6 +166,17 @@ func parseFirstLine(h *protocol.RequestHeader, buf []byte) (int, error) { return len(buf) - len(bNext), nil } +// validHeaderFieldValue is equal to httpguts.ValidHeaderFieldValue(shares the same context) +func validHeaderFieldValue(val []byte) bool { + for _, v := range val { + if bytesconv.ValidHeaderFieldValueTable[v] == 0 { + return false + } + continue + } + return true +} + func parseHeaders(h *protocol.RequestHeader, buf []byte) (int, error) { h.InitContentLengthWithValue(-2) @@ -178,7 +190,13 @@ func parseHeaders(h *protocol.RequestHeader, buf []byte) (int, error) { // See RFC 7230, Section 3.2.4. if bytes.IndexByte(s.Key, ' ') != -1 || bytes.IndexByte(s.Key, '\t') != -1 { err = fmt.Errorf("invalid header key %q", s.Key) - continue + return 0, err + } + + // Check the invalid chars in header value + if !validHeaderFieldValue(s.Value) { + err = fmt.Errorf("invalid header value %q", s.Value) + return 0, err } switch s.Key[0] | 0x20 {