1
2
3
4
5 package hpack
6
7 import (
8 "bytes"
9 "encoding/hex"
10 "fmt"
11 "math/rand"
12 "reflect"
13 "strings"
14 "testing"
15 "time"
16 )
17
18 func (d *Decoder) mustAt(idx int) HeaderField {
19 if hf, ok := d.at(uint64(idx)); !ok {
20 panic(fmt.Sprintf("bogus index %d", idx))
21 } else {
22 return hf
23 }
24 }
25
26 func TestDynamicTableAt(t *testing.T) {
27 d := NewDecoder(4096, nil)
28 at := d.mustAt
29 if got, want := at(2), (pair(":method", "GET")); got != want {
30 t.Errorf("at(2) = %v; want %v", got, want)
31 }
32 d.dynTab.add(pair("foo", "bar"))
33 d.dynTab.add(pair("blake", "miz"))
34 if got, want := at(staticTable.len()+1), (pair("blake", "miz")); got != want {
35 t.Errorf("at(dyn 1) = %v; want %v", got, want)
36 }
37 if got, want := at(staticTable.len()+2), (pair("foo", "bar")); got != want {
38 t.Errorf("at(dyn 2) = %v; want %v", got, want)
39 }
40 if got, want := at(3), (pair(":method", "POST")); got != want {
41 t.Errorf("at(3) = %v; want %v", got, want)
42 }
43 }
44
45 func TestDynamicTableSizeEvict(t *testing.T) {
46 d := NewDecoder(4096, nil)
47 if want := uint32(0); d.dynTab.size != want {
48 t.Fatalf("size = %d; want %d", d.dynTab.size, want)
49 }
50 add := d.dynTab.add
51 add(pair("blake", "eats pizza"))
52 if want := uint32(15 + 32); d.dynTab.size != want {
53 t.Fatalf("after pizza, size = %d; want %d", d.dynTab.size, want)
54 }
55 add(pair("foo", "bar"))
56 if want := uint32(15 + 32 + 6 + 32); d.dynTab.size != want {
57 t.Fatalf("after foo bar, size = %d; want %d", d.dynTab.size, want)
58 }
59 d.dynTab.setMaxSize(15 + 32 + 1 )
60 if want := uint32(6 + 32); d.dynTab.size != want {
61 t.Fatalf("after setMaxSize, size = %d; want %d", d.dynTab.size, want)
62 }
63 if got, want := d.mustAt(staticTable.len()+1), (pair("foo", "bar")); got != want {
64 t.Errorf("at(dyn 1) = %v; want %v", got, want)
65 }
66 add(pair("long", strings.Repeat("x", 500)))
67 if want := uint32(0); d.dynTab.size != want {
68 t.Fatalf("after big one, size = %d; want %d", d.dynTab.size, want)
69 }
70 }
71
72 func TestDecoderDecode(t *testing.T) {
73 tests := []struct {
74 name string
75 in []byte
76 want []HeaderField
77 wantDynTab []HeaderField
78 }{
79
80
81 {"C.2.1", dehex("400a 6375 7374 6f6d 2d6b 6579 0d63 7573 746f 6d2d 6865 6164 6572"),
82 []HeaderField{pair("custom-key", "custom-header")},
83 []HeaderField{pair("custom-key", "custom-header")},
84 },
85
86
87
88 {"C.2.2", dehex("040c 2f73 616d 706c 652f 7061 7468"),
89 []HeaderField{pair(":path", "/sample/path")},
90 []HeaderField{}},
91
92
93
94 {"C.2.3", dehex("1008 7061 7373 776f 7264 0673 6563 7265 74"),
95 []HeaderField{{"password", "secret", true}},
96 []HeaderField{}},
97
98
99
100 {"C.2.4", []byte("\x82"),
101 []HeaderField{pair(":method", "GET")},
102 []HeaderField{}},
103 }
104 for _, tt := range tests {
105 d := NewDecoder(4096, nil)
106 hf, err := d.DecodeFull(tt.in)
107 if err != nil {
108 t.Errorf("%s: %v", tt.name, err)
109 continue
110 }
111 if !reflect.DeepEqual(hf, tt.want) {
112 t.Errorf("%s: Got %v; want %v", tt.name, hf, tt.want)
113 }
114 gotDynTab := d.dynTab.reverseCopy()
115 if !reflect.DeepEqual(gotDynTab, tt.wantDynTab) {
116 t.Errorf("%s: dynamic table after = %v; want %v", tt.name, gotDynTab, tt.wantDynTab)
117 }
118 }
119 }
120
121 func (dt *dynamicTable) reverseCopy() (hf []HeaderField) {
122 hf = make([]HeaderField, len(dt.table.ents))
123 for i := range hf {
124 hf[i] = dt.table.ents[len(dt.table.ents)-1-i]
125 }
126 return
127 }
128
129 type encAndWant struct {
130 enc []byte
131 want []HeaderField
132 wantDynTab []HeaderField
133 wantDynSize uint32
134 }
135
136
137
138 func TestDecodeC3_NoHuffman(t *testing.T) {
139 testDecodeSeries(t, 4096, []encAndWant{
140 {dehex("8286 8441 0f77 7777 2e65 7861 6d70 6c65 2e63 6f6d"),
141 []HeaderField{
142 pair(":method", "GET"),
143 pair(":scheme", "http"),
144 pair(":path", "/"),
145 pair(":authority", "www.example.com"),
146 },
147 []HeaderField{
148 pair(":authority", "www.example.com"),
149 },
150 57,
151 },
152 {dehex("8286 84be 5808 6e6f 2d63 6163 6865"),
153 []HeaderField{
154 pair(":method", "GET"),
155 pair(":scheme", "http"),
156 pair(":path", "/"),
157 pair(":authority", "www.example.com"),
158 pair("cache-control", "no-cache"),
159 },
160 []HeaderField{
161 pair("cache-control", "no-cache"),
162 pair(":authority", "www.example.com"),
163 },
164 110,
165 },
166 {dehex("8287 85bf 400a 6375 7374 6f6d 2d6b 6579 0c63 7573 746f 6d2d 7661 6c75 65"),
167 []HeaderField{
168 pair(":method", "GET"),
169 pair(":scheme", "https"),
170 pair(":path", "/index.html"),
171 pair(":authority", "www.example.com"),
172 pair("custom-key", "custom-value"),
173 },
174 []HeaderField{
175 pair("custom-key", "custom-value"),
176 pair("cache-control", "no-cache"),
177 pair(":authority", "www.example.com"),
178 },
179 164,
180 },
181 })
182 }
183
184
185
186 func TestDecodeC4_Huffman(t *testing.T) {
187 testDecodeSeries(t, 4096, []encAndWant{
188 {dehex("8286 8441 8cf1 e3c2 e5f2 3a6b a0ab 90f4 ff"),
189 []HeaderField{
190 pair(":method", "GET"),
191 pair(":scheme", "http"),
192 pair(":path", "/"),
193 pair(":authority", "www.example.com"),
194 },
195 []HeaderField{
196 pair(":authority", "www.example.com"),
197 },
198 57,
199 },
200 {dehex("8286 84be 5886 a8eb 1064 9cbf"),
201 []HeaderField{
202 pair(":method", "GET"),
203 pair(":scheme", "http"),
204 pair(":path", "/"),
205 pair(":authority", "www.example.com"),
206 pair("cache-control", "no-cache"),
207 },
208 []HeaderField{
209 pair("cache-control", "no-cache"),
210 pair(":authority", "www.example.com"),
211 },
212 110,
213 },
214 {dehex("8287 85bf 4088 25a8 49e9 5ba9 7d7f 8925 a849 e95b b8e8 b4bf"),
215 []HeaderField{
216 pair(":method", "GET"),
217 pair(":scheme", "https"),
218 pair(":path", "/index.html"),
219 pair(":authority", "www.example.com"),
220 pair("custom-key", "custom-value"),
221 },
222 []HeaderField{
223 pair("custom-key", "custom-value"),
224 pair("cache-control", "no-cache"),
225 pair(":authority", "www.example.com"),
226 },
227 164,
228 },
229 })
230 }
231
232
233
234
235
236
237 func TestDecodeC5_ResponsesNoHuff(t *testing.T) {
238 testDecodeSeries(t, 256, []encAndWant{
239 {dehex(`
240 4803 3330 3258 0770 7269 7661 7465 611d
241 4d6f 6e2c 2032 3120 4f63 7420 3230 3133
242 2032 303a 3133 3a32 3120 474d 546e 1768
243 7474 7073 3a2f 2f77 7777 2e65 7861 6d70
244 6c65 2e63 6f6d
245 `),
246 []HeaderField{
247 pair(":status", "302"),
248 pair("cache-control", "private"),
249 pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"),
250 pair("location", "https://www.example.com"),
251 },
252 []HeaderField{
253 pair("location", "https://www.example.com"),
254 pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"),
255 pair("cache-control", "private"),
256 pair(":status", "302"),
257 },
258 222,
259 },
260 {dehex("4803 3330 37c1 c0bf"),
261 []HeaderField{
262 pair(":status", "307"),
263 pair("cache-control", "private"),
264 pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"),
265 pair("location", "https://www.example.com"),
266 },
267 []HeaderField{
268 pair(":status", "307"),
269 pair("location", "https://www.example.com"),
270 pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"),
271 pair("cache-control", "private"),
272 },
273 222,
274 },
275 {dehex(`
276 88c1 611d 4d6f 6e2c 2032 3120 4f63 7420
277 3230 3133 2032 303a 3133 3a32 3220 474d
278 54c0 5a04 677a 6970 7738 666f 6f3d 4153
279 444a 4b48 514b 425a 584f 5157 454f 5049
280 5541 5851 5745 4f49 553b 206d 6178 2d61
281 6765 3d33 3630 303b 2076 6572 7369 6f6e
282 3d31
283 `),
284 []HeaderField{
285 pair(":status", "200"),
286 pair("cache-control", "private"),
287 pair("date", "Mon, 21 Oct 2013 20:13:22 GMT"),
288 pair("location", "https://www.example.com"),
289 pair("content-encoding", "gzip"),
290 pair("set-cookie", "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1"),
291 },
292 []HeaderField{
293 pair("set-cookie", "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1"),
294 pair("content-encoding", "gzip"),
295 pair("date", "Mon, 21 Oct 2013 20:13:22 GMT"),
296 },
297 215,
298 },
299 })
300 }
301
302
303
304
305
306
307
308
309 func TestDecodeC6_ResponsesHuffman(t *testing.T) {
310 testDecodeSeries(t, 256, []encAndWant{
311 {dehex(`
312 4882 6402 5885 aec3 771a 4b61 96d0 7abe
313 9410 54d4 44a8 2005 9504 0b81 66e0 82a6
314 2d1b ff6e 919d 29ad 1718 63c7 8f0b 97c8
315 e9ae 82ae 43d3
316 `),
317 []HeaderField{
318 pair(":status", "302"),
319 pair("cache-control", "private"),
320 pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"),
321 pair("location", "https://www.example.com"),
322 },
323 []HeaderField{
324 pair("location", "https://www.example.com"),
325 pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"),
326 pair("cache-control", "private"),
327 pair(":status", "302"),
328 },
329 222,
330 },
331 {dehex("4883 640e ffc1 c0bf"),
332 []HeaderField{
333 pair(":status", "307"),
334 pair("cache-control", "private"),
335 pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"),
336 pair("location", "https://www.example.com"),
337 },
338 []HeaderField{
339 pair(":status", "307"),
340 pair("location", "https://www.example.com"),
341 pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"),
342 pair("cache-control", "private"),
343 },
344 222,
345 },
346 {dehex(`
347 88c1 6196 d07a be94 1054 d444 a820 0595
348 040b 8166 e084 a62d 1bff c05a 839b d9ab
349 77ad 94e7 821d d7f2 e6c7 b335 dfdf cd5b
350 3960 d5af 2708 7f36 72c1 ab27 0fb5 291f
351 9587 3160 65c0 03ed 4ee5 b106 3d50 07
352 `),
353 []HeaderField{
354 pair(":status", "200"),
355 pair("cache-control", "private"),
356 pair("date", "Mon, 21 Oct 2013 20:13:22 GMT"),
357 pair("location", "https://www.example.com"),
358 pair("content-encoding", "gzip"),
359 pair("set-cookie", "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1"),
360 },
361 []HeaderField{
362 pair("set-cookie", "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1"),
363 pair("content-encoding", "gzip"),
364 pair("date", "Mon, 21 Oct 2013 20:13:22 GMT"),
365 },
366 215,
367 },
368 })
369 }
370
371 func testDecodeSeries(t *testing.T, size uint32, steps []encAndWant) {
372 d := NewDecoder(size, nil)
373 for i, step := range steps {
374 hf, err := d.DecodeFull(step.enc)
375 if err != nil {
376 t.Fatalf("Error at step index %d: %v", i, err)
377 }
378 if !reflect.DeepEqual(hf, step.want) {
379 t.Fatalf("At step index %d: Got headers %v; want %v", i, hf, step.want)
380 }
381 gotDynTab := d.dynTab.reverseCopy()
382 if !reflect.DeepEqual(gotDynTab, step.wantDynTab) {
383 t.Errorf("After step index %d, dynamic table = %v; want %v", i, gotDynTab, step.wantDynTab)
384 }
385 if d.dynTab.size != step.wantDynSize {
386 t.Errorf("After step index %d, dynamic table size = %v; want %v", i, d.dynTab.size, step.wantDynSize)
387 }
388 }
389 }
390
391 func TestHuffmanDecodeExcessPadding(t *testing.T) {
392 tests := [][]byte{
393 {0xff},
394 {0x1f, 0xff},
395 {0x1f, 0xff, 0xff},
396 {0x1f, 0xff, 0xff, 0xff},
397 {0xff, 0x9f, 0xff, 0xff, 0xff},
398 {'R', 0xbc, '0', 0xff, 0xff, 0xff, 0xff},
399 }
400 for i, in := range tests {
401 var buf bytes.Buffer
402 if _, err := HuffmanDecode(&buf, in); err != ErrInvalidHuffman {
403 t.Errorf("test-%d: decode(%q) = %v; want ErrInvalidHuffman", i, in, err)
404 }
405 }
406 }
407
408 func TestHuffmanDecodeEOS(t *testing.T) {
409 in := []byte{0xff, 0xff, 0xff, 0xff, 0xfc}
410 var buf bytes.Buffer
411 if _, err := HuffmanDecode(&buf, in); err != ErrInvalidHuffman {
412 t.Errorf("error = %v; want ErrInvalidHuffman", err)
413 }
414 }
415
416 func TestHuffmanDecodeMaxLengthOnTrailingByte(t *testing.T) {
417 in := []byte{0x00, 0x01}
418 var buf bytes.Buffer
419 if err := huffmanDecode(&buf, 2, in); err != ErrStringLength {
420 t.Errorf("error = %v; want ErrStringLength", err)
421 }
422 }
423
424 func TestHuffmanDecodeCorruptPadding(t *testing.T) {
425 in := []byte{0x00}
426 var buf bytes.Buffer
427 if _, err := HuffmanDecode(&buf, in); err != ErrInvalidHuffman {
428 t.Errorf("error = %v; want ErrInvalidHuffman", err)
429 }
430 }
431
432 func TestHuffmanDecode(t *testing.T) {
433 tests := []struct {
434 inHex, want string
435 }{
436 {"f1e3 c2e5 f23a 6ba0 ab90 f4ff", "www.example.com"},
437 {"a8eb 1064 9cbf", "no-cache"},
438 {"25a8 49e9 5ba9 7d7f", "custom-key"},
439 {"25a8 49e9 5bb8 e8b4 bf", "custom-value"},
440 {"6402", "302"},
441 {"aec3 771a 4b", "private"},
442 {"d07a be94 1054 d444 a820 0595 040b 8166 e082 a62d 1bff", "Mon, 21 Oct 2013 20:13:21 GMT"},
443 {"9d29 ad17 1863 c78f 0b97 c8e9 ae82 ae43 d3", "https://www.example.com"},
444 {"9bd9 ab", "gzip"},
445 {"94e7 821d d7f2 e6c7 b335 dfdf cd5b 3960 d5af 2708 7f36 72c1 ab27 0fb5 291f 9587 3160 65c0 03ed 4ee5 b106 3d50 07",
446 "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1"},
447 }
448 for i, tt := range tests {
449 var buf bytes.Buffer
450 in, err := hex.DecodeString(strings.Replace(tt.inHex, " ", "", -1))
451 if err != nil {
452 t.Errorf("%d. hex input error: %v", i, err)
453 continue
454 }
455 if _, err := HuffmanDecode(&buf, in); err != nil {
456 t.Errorf("%d. decode error: %v", i, err)
457 continue
458 }
459 if got := buf.String(); tt.want != got {
460 t.Errorf("%d. decode = %q; want %q", i, got, tt.want)
461 }
462 }
463 }
464
465 func BenchmarkHuffmanDecode(b *testing.B) {
466 b.StopTimer()
467 enc, err := hex.DecodeString(strings.Replace("94e7 821d d7f2 e6c7 b335 dfdf cd5b 3960 d5af 2708 7f36 72c1 ab27 0fb5 291f 9587 3160 65c0 03ed 4ee5 b106 3d50 07",
468 " ", "", -1))
469 if err != nil {
470 b.Fatal(err)
471 }
472 b.ReportAllocs()
473 b.StartTimer()
474 var buf bytes.Buffer
475 for i := 0; i < b.N; i++ {
476 buf.Reset()
477 if _, err := HuffmanDecode(&buf, enc); err != nil {
478 b.Fatalf("decode error: %v", err)
479 }
480 if string(buf.Bytes()) != "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1" {
481 b.Fatalf("bogus output %q", buf.Bytes())
482 }
483 }
484 }
485
486 func TestAppendHuffmanString(t *testing.T) {
487 tests := []struct {
488 in, want string
489 }{
490 {"www.example.com", "f1e3 c2e5 f23a 6ba0 ab90 f4ff"},
491 {"no-cache", "a8eb 1064 9cbf"},
492 {"custom-key", "25a8 49e9 5ba9 7d7f"},
493 {"custom-value", "25a8 49e9 5bb8 e8b4 bf"},
494 {"302", "6402"},
495 {"private", "aec3 771a 4b"},
496 {"Mon, 21 Oct 2013 20:13:21 GMT", "d07a be94 1054 d444 a820 0595 040b 8166 e082 a62d 1bff"},
497 {"https://www.example.com", "9d29 ad17 1863 c78f 0b97 c8e9 ae82 ae43 d3"},
498 {"gzip", "9bd9 ab"},
499 {"foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1",
500 "94e7 821d d7f2 e6c7 b335 dfdf cd5b 3960 d5af 2708 7f36 72c1 ab27 0fb5 291f 9587 3160 65c0 03ed 4ee5 b106 3d50 07"},
501 }
502 for i, tt := range tests {
503 buf := []byte{}
504 want := strings.Replace(tt.want, " ", "", -1)
505 buf = AppendHuffmanString(buf, tt.in)
506 if got := hex.EncodeToString(buf); want != got {
507 t.Errorf("%d. encode = %q; want %q", i, got, want)
508 }
509 }
510 }
511
512 func BenchmarkAppendHuffmanString(b *testing.B) {
513 b.StopTimer()
514 expected, err := hex.DecodeString(strings.Replace("94e7 821d d7f2 e6c7 b335 dfdf cd5b 3960 d5af 2708 7f36 72c1 ab27 0fb5 291f 9587 3160 65c0 03ed 4ee5 b106 3d50 07",
515 " ", "", -1))
516 if err != nil {
517 b.Fatal(err)
518 }
519 buf := make([]byte, 0, len(expected))
520 b.ReportAllocs()
521 b.StartTimer()
522
523 for i := 0; i < b.N; i++ {
524 enc := AppendHuffmanString(buf, "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1")
525 if string(enc) != string(expected) {
526 b.Fatalf("bogus output %q", enc)
527 }
528 }
529 }
530
531 func TestHuffmanMaxStrLen(t *testing.T) {
532 const msg = "Some string"
533 huff := AppendHuffmanString(nil, msg)
534
535 testGood := func(max int) {
536 var out bytes.Buffer
537 if err := huffmanDecode(&out, max, huff); err != nil {
538 t.Errorf("For maxLen=%d, unexpected error: %v", max, err)
539 }
540 if out.String() != msg {
541 t.Errorf("For maxLen=%d, out = %q; want %q", max, out.String(), msg)
542 }
543 }
544 testGood(0)
545 testGood(len(msg))
546 testGood(len(msg) + 1)
547
548 var out bytes.Buffer
549 if err := huffmanDecode(&out, len(msg)-1, huff); err != ErrStringLength {
550 t.Errorf("err = %v; want ErrStringLength", err)
551 }
552 }
553
554 func TestHuffmanRoundtripStress(t *testing.T) {
555 const Len = 50
556 input := make([]byte, Len)
557 var output bytes.Buffer
558 var huff []byte
559
560 n := 5000
561 if testing.Short() {
562 n = 100
563 }
564 seed := time.Now().UnixNano()
565 t.Logf("Seed = %v", seed)
566 src := rand.New(rand.NewSource(seed))
567 var encSize int64
568 for i := 0; i < n; i++ {
569 for l := range input {
570 input[l] = byte(src.Intn(256))
571 }
572 huff = AppendHuffmanString(huff[:0], string(input))
573 encSize += int64(len(huff))
574 output.Reset()
575 if err := huffmanDecode(&output, 0, huff); err != nil {
576 t.Errorf("Failed to decode %q -> %q -> error %v", input, huff, err)
577 continue
578 }
579 if !bytes.Equal(output.Bytes(), input) {
580 t.Errorf("Roundtrip failure on %q -> %q -> %q", input, huff, output.Bytes())
581 }
582 }
583 t.Logf("Compressed size of original: %0.02f%% (%v -> %v)", 100*(float64(encSize)/(Len*float64(n))), Len*n, encSize)
584 }
585
586 func TestHuffmanDecodeFuzz(t *testing.T) {
587 const Len = 50
588 var buf, zbuf bytes.Buffer
589
590 n := 5000
591 if testing.Short() {
592 n = 100
593 }
594 seed := time.Now().UnixNano()
595 t.Logf("Seed = %v", seed)
596 src := rand.New(rand.NewSource(seed))
597 numFail := 0
598 for i := 0; i < n; i++ {
599 zbuf.Reset()
600 if i == 0 {
601
602 zbuf.WriteString("00\x91\xff\xff\xff\xff\xc8")
603 } else {
604 for l := 0; l < Len; l++ {
605 zbuf.WriteByte(byte(src.Intn(256)))
606 }
607 }
608
609 buf.Reset()
610 if err := huffmanDecode(&buf, 0, zbuf.Bytes()); err != nil {
611 if err == ErrInvalidHuffman {
612 numFail++
613 continue
614 }
615 t.Errorf("Failed to decode %q: %v", zbuf.Bytes(), err)
616 continue
617 }
618 }
619 t.Logf("%0.02f%% are invalid (%d / %d)", 100*float64(numFail)/float64(n), numFail, n)
620 if numFail < 1 {
621 t.Error("expected at least one invalid huffman encoding (test starts with one)")
622 }
623 }
624
625 func TestReadVarInt(t *testing.T) {
626 type res struct {
627 i uint64
628 consumed int
629 err error
630 }
631 tests := []struct {
632 n byte
633 p []byte
634 want res
635 }{
636
637 {1, []byte{0}, res{0, 1, nil}},
638 {2, []byte{2}, res{2, 1, nil}},
639 {3, []byte{6}, res{6, 1, nil}},
640 {4, []byte{14}, res{14, 1, nil}},
641 {5, []byte{30}, res{30, 1, nil}},
642 {6, []byte{62}, res{62, 1, nil}},
643 {7, []byte{126}, res{126, 1, nil}},
644 {8, []byte{254}, res{254, 1, nil}},
645
646
647 {1, []byte{1}, res{0, 0, errNeedMore}},
648 {2, []byte{3}, res{0, 0, errNeedMore}},
649 {3, []byte{7}, res{0, 0, errNeedMore}},
650 {4, []byte{15}, res{0, 0, errNeedMore}},
651 {5, []byte{31}, res{0, 0, errNeedMore}},
652 {6, []byte{63}, res{0, 0, errNeedMore}},
653 {7, []byte{127}, res{0, 0, errNeedMore}},
654 {8, []byte{255}, res{0, 0, errNeedMore}},
655
656
657 {5, []byte{255, 154, 10}, res{1337, 3, nil}},
658 {5, []byte{159, 154, 10}, res{1337, 3, nil}},
659 {5, []byte{191, 154, 10}, res{1337, 3, nil}},
660
661
662 {5, []byte{191, 154, 10, 2}, res{1337, 3, nil}},
663
664
665 {5, []byte{191, 154}, res{0, 0, errNeedMore}},
666
667
668 {1, []byte{255, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128}, res{0, 0, errVarintOverflow}},
669 }
670 for _, tt := range tests {
671 i, remain, err := readVarInt(tt.n, tt.p)
672 consumed := len(tt.p) - len(remain)
673 got := res{i, consumed, err}
674 if got != tt.want {
675 t.Errorf("readVarInt(%d, %v ~ %x) = %+v; want %+v", tt.n, tt.p, tt.p, got, tt.want)
676 }
677 }
678 }
679
680
681 func TestHuffmanFuzzCrash(t *testing.T) {
682 got, err := HuffmanDecodeToString([]byte("00\x91\xff\xff\xff\xff\xc8"))
683 if got != "" {
684 t.Errorf("Got %q; want empty string", got)
685 }
686 if err != ErrInvalidHuffman {
687 t.Errorf("Err = %v; want ErrInvalidHuffman", err)
688 }
689 }
690
691 func pair(name, value string) HeaderField {
692 return HeaderField{Name: name, Value: value}
693 }
694
695 func dehex(s string) []byte {
696 s = strings.Replace(s, " ", "", -1)
697 s = strings.Replace(s, "\n", "", -1)
698 b, err := hex.DecodeString(s)
699 if err != nil {
700 panic(err)
701 }
702 return b
703 }
704
705 func TestEmitEnabled(t *testing.T) {
706 var buf bytes.Buffer
707 enc := NewEncoder(&buf)
708 enc.WriteField(HeaderField{Name: "foo", Value: "bar"})
709 enc.WriteField(HeaderField{Name: "foo", Value: "bar"})
710
711 numCallback := 0
712 var dec *Decoder
713 dec = NewDecoder(8<<20, func(HeaderField) {
714 numCallback++
715 dec.SetEmitEnabled(false)
716 })
717 if !dec.EmitEnabled() {
718 t.Errorf("initial emit enabled = false; want true")
719 }
720 if _, err := dec.Write(buf.Bytes()); err != nil {
721 t.Error(err)
722 }
723 if numCallback != 1 {
724 t.Errorf("num callbacks = %d; want 1", numCallback)
725 }
726 if dec.EmitEnabled() {
727 t.Errorf("emit enabled = true; want false")
728 }
729 }
730
731 func TestSlowIncrementalDecode(t *testing.T) {
732
733 t.Skip("too slow in -race mode")
734
735 var buf bytes.Buffer
736 enc := NewEncoder(&buf)
737 hf := HeaderField{
738 Name: strings.Repeat("k", 1<<20),
739 Value: strings.Repeat("v", 1<<20),
740 }
741 enc.WriteField(hf)
742 hbuf := buf.Bytes()
743 count := 0
744 dec := NewDecoder(initialHeaderTableSize, func(got HeaderField) {
745 count++
746 if count != 1 {
747 t.Errorf("decoded %v fields, want 1", count)
748 }
749 if got.Name != hf.Name {
750 t.Errorf("decoded Name does not match input")
751 }
752 if got.Value != hf.Value {
753 t.Errorf("decoded Value does not match input")
754 }
755 })
756 for i := 0; i < len(hbuf); i++ {
757 dec.Write(hbuf[i : i+1])
758 }
759 }
760
761 func TestSaveBufLimit(t *testing.T) {
762 const maxStr = 1 << 10
763 var got []HeaderField
764 dec := NewDecoder(initialHeaderTableSize, func(hf HeaderField) {
765 got = append(got, hf)
766 })
767 dec.SetMaxStringLength(maxStr)
768 var frag []byte
769 frag = append(frag[:0], encodeTypeByte(false, false))
770 frag = appendVarInt(frag, 7, 3)
771 frag = append(frag, "foo"...)
772 frag = appendVarInt(frag, 7, 3)
773 frag = append(frag, "bar"...)
774
775 if _, err := dec.Write(frag); err != nil {
776 t.Fatal(err)
777 }
778
779 want := []HeaderField{{Name: "foo", Value: "bar"}}
780 if !reflect.DeepEqual(got, want) {
781 t.Errorf("After small writes, got %v; want %v", got, want)
782 }
783
784 frag = append(frag[:0], encodeTypeByte(false, false))
785 frag = appendVarInt(frag, 7, maxStr*3)
786 frag = append(frag, make([]byte, maxStr*3)...)
787
788 _, err := dec.Write(frag)
789 if err != ErrStringLength {
790 t.Fatalf("Write error = %v; want ErrStringLength", err)
791 }
792 }
793
794 func TestDynamicSizeUpdate(t *testing.T) {
795 var buf bytes.Buffer
796 enc := NewEncoder(&buf)
797 enc.SetMaxDynamicTableSize(255)
798 enc.WriteField(HeaderField{Name: "foo", Value: "bar"})
799
800 d := NewDecoder(4096, func(_ HeaderField) {})
801 _, err := d.Write(buf.Bytes())
802 if err != nil {
803 t.Fatalf("unexpected error: got = %v", err)
804 }
805
806 d.Close()
807
808
809 _, err = d.Write(buf.Bytes())
810 if err != nil {
811 t.Fatalf("unexpected error: got = %v", err)
812 }
813
814
815 _, err = d.Write(buf.Bytes())
816 if err == nil {
817 t.Fatalf("dynamic table size update not at the beginning of a header block")
818 }
819 }
820
View as plain text