77 "bytes"
88 "encoding/binary"
99 "errors"
10+ "regexp"
1011 "strconv"
1112 "strings"
1213 "unsafe"
@@ -34,6 +35,11 @@ const (
3435
3536const initialHeaderTableSize = 4096
3637
38+ var (
39+ validPath = regexp .MustCompile (`^[A-Za-z0-9\-/._~]+$` )
40+ validContentType = regexp .MustCompile (`^[A-Za-z\-/\+]+$` )
41+ )
42+
3743type h2Connection struct {
3844 hdec * bhpack.Decoder
3945 hdecRet * bhpack.Decoder
@@ -84,13 +90,50 @@ func protocolIsGRPC(activeGRPCConnections *lru.Cache[uint64, h2Connection], conn
8490
8591var commonHDec = bhpack .NewDecoder (0 , nil )
8692
93+ func isHTTPOp (op string ) bool {
94+ return op == "GET" || op == "POST" || op == "PATCH" || op == "DELETE" || op == "OPTIONS" || op == "HEAD"
95+ }
96+
97+ func handleHeaderField (hf * bhpack.HeaderField ) bool {
98+ hfKey := strings .ToLower (hf .Name )
99+ switch hfKey {
100+ case ":method" :
101+ val := strings .ToUpper (hf .Value )
102+ if isHTTPOp (val ) {
103+ return true
104+ }
105+ case ":scheme" :
106+ val := strings .ToUpper (hf .Value )
107+ if val == "HTTP" {
108+ return true
109+ }
110+ case "traceparent" :
111+ return true
112+ case ":path" :
113+ val := hf .Value
114+ if pos := strings .Index (val , "?" ); pos >= 0 {
115+ val = val [:pos ]
116+ }
117+ if validPath .MatchString (val ) {
118+ return true
119+ }
120+ case "content-type" :
121+ val := hf .Value
122+ if validContentType .MatchString (val ) {
123+ return true
124+ }
125+ case "grpc-status" :
126+ return true
127+ }
128+
129+ return false
130+ }
131+
87132func knownFrameKeys (fr * http2.Framer , hf * http2.HeadersFrame ) bool {
88- known := false
133+ knownCount := 0
89134 commonHDec .SetEmitFunc (func (hf bhpack.HeaderField ) {
90- hfKey := strings .ToLower (hf .Name )
91- switch hfKey {
92- case ":method" , ":path" , "content-type" , ":status" , "grpc-status" :
93- known = true
135+ if handleHeaderField (& hf ) {
136+ knownCount ++
94137 }
95138 })
96139 // Lose reference to MetaHeadersFrame:
@@ -116,7 +159,7 @@ func knownFrameKeys(fr *http2.Framer, hf *http2.HeadersFrame) bool {
116159 frag = cf .HeaderBlockFragment ()
117160 }
118161
119- return known
162+ return knownCount > 1
120163}
121164
122165func readMetaFrame (parseContext * EBPFParseContext , connID uint64 , fr * http2.Framer , hf * http2.HeadersFrame ) (string , string , string , bool ) {
@@ -358,8 +401,10 @@ func http2FromBuffers(parseContext *EBPFParseContext, event *BPFHTTP2Info) (requ
358401 if ff , ok := f .(* http2.HeadersFrame ); ok {
359402 rok := false
360403 method , path , contentType , ok := readMetaFrame (parseContext , connID , framer , ff )
361-
362- if path == "" {
404+ if pos := strings .Index (path , "?" ); pos >= 0 {
405+ path = path [:pos ]
406+ }
407+ if path == "" || ! validPath .MatchString (path ) {
363408 path = "*"
364409 }
365410
0 commit comments