@@ -119,10 +119,10 @@ func TestHTTP2Parsing(t *testing.T) {
119
119
120
120
if ff , ok := f .(* http2.HeadersFrame ); ok {
121
121
connInfo := BPFConnInfo {}
122
- method , path , contentType , _ := readMetaFrame (& connInfo , framer , ff )
123
- assert .Equal (t , method , tt . method )
124
- assert .Equal (t , path , tt . path )
125
- assert .Equal (t , contentType , tt . contentType )
122
+ method , path , contentType , _ := readMetaFrame (& connInfo , false , framer , ff )
123
+ assert .Equal (t , tt . method , method )
124
+ assert .Equal (t , tt . path , path )
125
+ assert .Equal (t , tt . contentType , contentType )
126
126
}
127
127
}
128
128
})
@@ -169,6 +169,74 @@ func TestHTTP2EventsParsing(t *testing.T) {
169
169
}
170
170
}
171
171
172
+ func TestDynamicTableUpdates (t * testing.T ) {
173
+ rinput := []byte {0 , 0 , 138 , 1 , 36 , 0 , 0 , 0 , 11 , 0 , 0 , 0 , 0 , 15 , 0 , 0 , 0 , 0 , 45 , 0 , 0 , 0 , 0 , 0 , 11 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
174
+
175
+ tests := []struct {
176
+ name string
177
+ input []byte
178
+ inputLen int
179
+ }{
180
+ {
181
+ name : "Full path, lots of headers" ,
182
+ input : []byte {0 , 0 , 222 , 1 , 4 , 0 , 0 , 0 , 1 , 64 , 5 , 58 , 112 , 97 , 116 , 104 , 33 , 47 , 114 , 111 , 117 , 116 , 101 , 103 , 117 , 105 , 100 , 101 , 46 , 82 , 111 , 117 , 116 , 101 , 71 , 117 , 105 , 100 , 101 , 47 , 71 , 101 , 116 , 70 , 101 , 97 , 116 , 117 , 114 , 101 , 64 , 10 , 58 , 97 , 117 , 116 , 104 , 111 , 114 , 105 , 116 , 121 , 15 , 108 , 111 , 99 , 97 , 108 , 104 , 111 , 115 , 116 , 58 , 53 , 48 , 48 , 53 , 49 , 131 , 134 , 64 , 12 , 99 , 111 , 110 , 116 , 101 , 110 , 116 , 45 , 116 , 121 , 112 , 101 , 16 , 97 , 112 , 112 , 108 , 105 , 99 , 97 , 116 , 105 , 111 , 110 , 47 , 103 , 114 , 112 , 99 , 64 , 2 , 116 , 101 , 8 , 116 , 114 , 97 , 105 , 108 , 101 , 114 , 115 , 64 , 20 , 103 , 114 , 112 , 99 , 45 , 97 , 99 , 99 , 101 , 112 , 116 , 45 , 101 , 110 , 99 , 111 , 100 , 105 , 110 , 103 , 23 , 105 , 100 , 101 , 110 , 116 , 105 , 116 , 121 , 44 , 32 , 100 , 101 , 102 , 108 , 97 , 116 , 101 , 44 , 32 , 103 , 122 , 105 , 112 , 64 , 10 , 117 , 115 , 101 , 114 , 45 , 97 , 103 , 101 , 110 , 116 , 48 , 103 , 114 , 112 , 99 , 45 , 112 , 121 , 116 , 104 , 111 , 110 , 47 , 49 , 46 , 54 , 57 , 46 , 48 , 32 , 103 , 114 , 112 , 99 , 45 , 99 , 47 , 52 , 52 , 46 , 50 , 46 , 48 , 32 , 40 , 108 , 105 , 110 , 117 , 120 , 59 , 32 , 99 , 104 , 116 , 116 , 112 , 50 , 41 , 0 , 0 , 4 , 8 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 5 , 0 , 0 , 22 , 0 , 1 , 0 , 0 , 0 , 1 , 0 , 0 , 0 },
183
+ inputLen : 1024 ,
184
+ },
185
+ {
186
+ name : "Full path only" ,
187
+ input : []byte {0 , 0 , 222 , 1 , 4 , 0 , 0 , 0 , 1 , 64 , 5 , 58 , 112 , 97 , 116 , 104 , 33 , 47 , 114 , 111 , 117 , 116 , 101 , 103 , 117 , 105 , 100 , 101 , 46 , 82 , 111 , 117 , 116 , 101 , 71 , 117 , 105 , 100 , 101 , 47 , 71 , 101 , 116 , 70 , 101 , 97 , 116 , 117 , 114 , 101 , 131 },
188
+ inputLen : 1024 ,
189
+ },
190
+ {
191
+ name : "Index encoded" ,
192
+ input : []byte {0 , 0 , 8 , 1 , 4 , 0 , 0 , 0 , 3 , 195 , 194 , 131 , 134 , 193 , 192 , 191 , 190 , 0 , 0 , 4 , 8 , 0 , 0 , 0 , 0 , 3 , 0 , 0 , 0 , 5 , 0 , 0 , 5 , 0 , 1 , 0 , 0 , 0 , 3 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 4 , 8 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 84 },
193
+ inputLen : 1024 ,
194
+ },
195
+ }
196
+
197
+ for _ , tt := range tests {
198
+ t .Run (tt .name , func (t * testing.T ) {
199
+ info := makeBPFHTTP2InfoNewRequest (tt .input , rinput , tt .inputLen )
200
+ s , ignore , _ := http2FromBuffers (& info )
201
+ assert .False (t , ignore )
202
+ assert .Equal (t , "POST" , s .Method )
203
+ assert .Equal (t , "/routeguide.RouteGuide/GetFeature" , s .Path )
204
+ })
205
+ }
206
+
207
+ // Now let's break the decoder with pushing unknown indices
208
+ unknownIndexInput := []byte {0 , 0 , 8 , 1 , 4 , 0 , 0 , 0 , 3 , 199 , 200 , 131 , 134 , 201 , 202 , 203 , 204 , 0 , 0 , 4 , 8 , 0 , 0 , 0 , 0 , 3 , 0 , 0 , 0 , 5 , 0 , 0 , 5 , 0 , 1 , 0 , 0 , 0 , 3 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 4 , 8 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 84 }
209
+
210
+ info := makeBPFHTTP2InfoNewRequest (unknownIndexInput , rinput , 1024 )
211
+ s , ignore , _ := http2FromBuffers (& info )
212
+ assert .False (t , ignore )
213
+ assert .Equal (t , "POST" , s .Method )
214
+ assert .Equal (t , "*" , s .Path )
215
+
216
+ nextIndex := 8 + 61 // 61 is the static table index size, 7 is how many entries we store in the dynamic table with that first request
217
+
218
+ // Now let's send new path
219
+ newPathInput := []byte {0 , 0 , 222 , 1 , 4 , 0 , 0 , 0 , 1 , 64 , 5 , 58 , 112 , 97 , 116 , 104 , 33 , 47 , 112 , 111 , 117 , 116 , 101 , 103 , 117 , 105 , 100 , 101 , 46 , 82 , 111 , 117 , 116 , 101 , 71 , 117 , 105 , 100 , 101 , 47 , 71 , 101 , 116 , 70 , 101 , 97 , 116 , 117 , 114 , 101 , 64 , 10 , 58 , 97 , 117 , 116 , 104 , 111 , 114 , 105 , 116 , 121 , 15 , 108 , 111 , 99 , 97 , 108 , 104 , 111 , 115 , 116 , 58 , 53 , 48 , 48 , 53 , 49 , 131 , 134 , 64 , 12 , 99 , 111 , 110 , 116 , 101 , 110 , 116 , 45 , 116 , 121 , 112 , 101 , 16 , 97 , 112 , 112 , 108 , 105 , 99 , 97 , 116 , 105 , 111 , 110 , 47 , 103 , 114 , 112 , 99 , 64 , 2 , 116 , 101 , 8 , 116 , 114 , 97 , 105 , 108 , 101 , 114 , 115 , 64 , 20 , 103 , 114 , 112 , 99 , 45 , 97 , 99 , 99 , 101 , 112 , 116 , 45 , 101 , 110 , 99 , 111 , 100 , 105 , 110 , 103 , 23 , 105 , 100 , 101 , 110 , 116 , 105 , 116 , 121 , 44 , 32 , 100 , 101 , 102 , 108 , 97 , 116 , 101 , 44 , 32 , 103 , 122 , 105 , 112 , 64 , 10 , 117 , 115 , 101 , 114 , 45 , 97 , 103 , 101 , 110 , 116 , 48 , 103 , 114 , 112 , 99 , 45 , 112 , 121 , 116 , 104 , 111 , 110 , 47 , 49 , 46 , 54 , 57 , 46 , 48 , 32 , 103 , 114 , 112 , 99 , 45 , 99 , 47 , 52 , 52 , 46 , 50 , 46 , 48 , 32 , 40 , 108 , 105 , 110 , 117 , 120 , 59 , 32 , 99 , 104 , 116 , 116 , 112 , 50 , 41 , 0 , 0 , 4 , 8 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 5 , 0 , 0 , 22 , 0 , 1 , 0 , 0 , 0 , 1 , 0 , 0 , 0 }
220
+
221
+ // We'll be able to decode this correctly, even with broken decoder, beause the values are sent as text
222
+ info = makeBPFHTTP2InfoNewRequest (newPathInput , rinput , 1024 )
223
+ s , ignore , _ = http2FromBuffers (& info )
224
+ assert .False (t , ignore )
225
+ assert .Equal (t , "POST" , s .Method )
226
+ assert .Equal (t , "/pouteguide.RouteGuide/GetFeature" , s .Path ) // this value is the same I just changed the first character from r to p
227
+
228
+ // indexed version of newPathInput
229
+ // if we cached a new pair nextIndex + 128 is the high bit encoded next index which should be in the dynamic table
230
+ // however we mark the decoder as invalid and it shouldn't resolve to anything for :path
231
+ indexedNewPath := []byte {0 , 0 , 8 , 1 , 4 , 0 , 0 , 0 , 3 , 195 , 194 , 131 , 134 , 193 , 192 , 191 , byte (nextIndex + 128 ), 0 , 0 , 4 , 8 , 0 , 0 , 0 , 0 , 3 , 0 , 0 , 0 , 5 , 0 , 0 , 5 , 0 , 1 , 0 , 0 , 0 , 3 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 4 , 8 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 84 }
232
+
233
+ info = makeBPFHTTP2InfoNewRequest (indexedNewPath , rinput , 1024 )
234
+ s , ignore , _ = http2FromBuffers (& info )
235
+ assert .False (t , ignore )
236
+ assert .Equal (t , "POST" , s .Method )
237
+ assert .Equal (t , "*" , s .Path ) // this value is the same I just changed the first character from r to p
238
+ }
239
+
172
240
func makeBPFHTTP2Info (buf , rbuf []byte , len int ) BPFHTTP2Info {
173
241
var info BPFHTTP2Info
174
242
copy (info .Data [:], buf )
@@ -177,3 +245,12 @@ func makeBPFHTTP2Info(buf, rbuf []byte, len int) BPFHTTP2Info {
177
245
178
246
return info
179
247
}
248
+
249
+ func makeBPFHTTP2InfoNewRequest (buf , rbuf []byte , len int ) BPFHTTP2Info {
250
+ info := makeBPFHTTP2Info (buf , rbuf , len )
251
+ info .ConnInfo .D_port = 1
252
+ info .ConnInfo .S_port = 1
253
+ info .NewConn = 1
254
+
255
+ return info
256
+ }
0 commit comments