|
@@ -236,7 +236,7 @@ type encAndWant struct {
|
|
|
// C.3 Request Examples without Huffman Coding
|
|
// C.3 Request Examples without Huffman Coding
|
|
|
// http://http2.github.io/http2-spec/compression.html#rfc.section.C.3
|
|
// http://http2.github.io/http2-spec/compression.html#rfc.section.C.3
|
|
|
func TestDecodeC3_NoHuffman(t *testing.T) {
|
|
func TestDecodeC3_NoHuffman(t *testing.T) {
|
|
|
- testDecodeSeries(t, []encAndWant{
|
|
|
|
|
|
|
+ testDecodeSeries(t, 4096, []encAndWant{
|
|
|
{dehex("8286 8441 0f77 7777 2e65 7861 6d70 6c65 2e63 6f6d"),
|
|
{dehex("8286 8441 0f77 7777 2e65 7861 6d70 6c65 2e63 6f6d"),
|
|
|
[]HeaderField{
|
|
[]HeaderField{
|
|
|
pair(":method", "GET"),
|
|
pair(":method", "GET"),
|
|
@@ -284,7 +284,7 @@ func TestDecodeC3_NoHuffman(t *testing.T) {
|
|
|
// C.4 Request Examples with Huffman Coding
|
|
// C.4 Request Examples with Huffman Coding
|
|
|
// http://http2.github.io/http2-spec/compression.html#rfc.section.C.4
|
|
// http://http2.github.io/http2-spec/compression.html#rfc.section.C.4
|
|
|
func TestDecodeC4_Huffman(t *testing.T) {
|
|
func TestDecodeC4_Huffman(t *testing.T) {
|
|
|
- testDecodeSeries(t, []encAndWant{
|
|
|
|
|
|
|
+ testDecodeSeries(t, 4096, []encAndWant{
|
|
|
{dehex("8286 8441 8cf1 e3c2 e5f2 3a6b a0ab 90f4 ff"),
|
|
{dehex("8286 8441 8cf1 e3c2 e5f2 3a6b a0ab 90f4 ff"),
|
|
|
[]HeaderField{
|
|
[]HeaderField{
|
|
|
pair(":method", "GET"),
|
|
pair(":method", "GET"),
|
|
@@ -329,8 +329,147 @@ func TestDecodeC4_Huffman(t *testing.T) {
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-func testDecodeSeries(t *testing.T, steps []encAndWant) {
|
|
|
|
|
- d := NewDecoder(4096, nil)
|
|
|
|
|
|
|
+// http://http2.github.io/http2-spec/compression.html#rfc.section.C.5
|
|
|
|
|
+// "This section shows several consecutive header lists, corresponding
|
|
|
|
|
+// to HTTP responses, on the same connection. The HTTP/2 setting
|
|
|
|
|
+// parameter SETTINGS_HEADER_TABLE_SIZE is set to the value of 256
|
|
|
|
|
+// octets, causing some evictions to occur."
|
|
|
|
|
+func TestDecodeC5_ResponsesNoHuff(t *testing.T) {
|
|
|
|
|
+ testDecodeSeries(t, 256, []encAndWant{
|
|
|
|
|
+ {dehex(`
|
|
|
|
|
+4803 3330 3258 0770 7269 7661 7465 611d
|
|
|
|
|
+4d6f 6e2c 2032 3120 4f63 7420 3230 3133
|
|
|
|
|
+2032 303a 3133 3a32 3120 474d 546e 1768
|
|
|
|
|
+7474 7073 3a2f 2f77 7777 2e65 7861 6d70
|
|
|
|
|
+6c65 2e63 6f6d
|
|
|
|
|
+`),
|
|
|
|
|
+ []HeaderField{
|
|
|
|
|
+ pair(":status", "302"),
|
|
|
|
|
+ pair("cache-control", "private"),
|
|
|
|
|
+ pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"),
|
|
|
|
|
+ pair("location", "https://www.example.com"),
|
|
|
|
|
+ },
|
|
|
|
|
+ []HeaderField{
|
|
|
|
|
+ pair("location", "https://www.example.com"),
|
|
|
|
|
+ pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"),
|
|
|
|
|
+ pair("cache-control", "private"),
|
|
|
|
|
+ pair(":status", "302"),
|
|
|
|
|
+ },
|
|
|
|
|
+ 222,
|
|
|
|
|
+ },
|
|
|
|
|
+ {dehex("4803 3330 37c1 c0bf"),
|
|
|
|
|
+ []HeaderField{
|
|
|
|
|
+ pair(":status", "307"),
|
|
|
|
|
+ pair("cache-control", "private"),
|
|
|
|
|
+ pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"),
|
|
|
|
|
+ pair("location", "https://www.example.com"),
|
|
|
|
|
+ },
|
|
|
|
|
+ []HeaderField{
|
|
|
|
|
+ pair(":status", "307"),
|
|
|
|
|
+ pair("location", "https://www.example.com"),
|
|
|
|
|
+ pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"),
|
|
|
|
|
+ pair("cache-control", "private"),
|
|
|
|
|
+ },
|
|
|
|
|
+ 222,
|
|
|
|
|
+ },
|
|
|
|
|
+ {dehex(`
|
|
|
|
|
+88c1 611d 4d6f 6e2c 2032 3120 4f63 7420
|
|
|
|
|
+3230 3133 2032 303a 3133 3a32 3220 474d
|
|
|
|
|
+54c0 5a04 677a 6970 7738 666f 6f3d 4153
|
|
|
|
|
+444a 4b48 514b 425a 584f 5157 454f 5049
|
|
|
|
|
+5541 5851 5745 4f49 553b 206d 6178 2d61
|
|
|
|
|
+6765 3d33 3630 303b 2076 6572 7369 6f6e
|
|
|
|
|
+3d31
|
|
|
|
|
+`),
|
|
|
|
|
+ []HeaderField{
|
|
|
|
|
+ pair(":status", "200"),
|
|
|
|
|
+ pair("cache-control", "private"),
|
|
|
|
|
+ pair("date", "Mon, 21 Oct 2013 20:13:22 GMT"),
|
|
|
|
|
+ pair("location", "https://www.example.com"),
|
|
|
|
|
+ pair("content-encoding", "gzip"),
|
|
|
|
|
+ pair("set-cookie", "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1"),
|
|
|
|
|
+ },
|
|
|
|
|
+ []HeaderField{
|
|
|
|
|
+ pair("set-cookie", "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1"),
|
|
|
|
|
+ pair("content-encoding", "gzip"),
|
|
|
|
|
+ pair("date", "Mon, 21 Oct 2013 20:13:22 GMT"),
|
|
|
|
|
+ },
|
|
|
|
|
+ 215,
|
|
|
|
|
+ },
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// http://http2.github.io/http2-spec/compression.html#rfc.section.C.6
|
|
|
|
|
+// "This section shows the same examples as the previous section, but
|
|
|
|
|
+// using Huffman encoding for the literal values. The HTTP/2 setting
|
|
|
|
|
+// parameter SETTINGS_HEADER_TABLE_SIZE is set to the value of 256
|
|
|
|
|
+// octets, causing some evictions to occur. The eviction mechanism
|
|
|
|
|
+// uses the length of the decoded literal values, so the same
|
|
|
|
|
+// evictions occurs as in the previous section."
|
|
|
|
|
+func TestDecodeC6_ResponsesHuffman(t *testing.T) {
|
|
|
|
|
+ testDecodeSeries(t, 256, []encAndWant{
|
|
|
|
|
+ {dehex(`
|
|
|
|
|
+4882 6402 5885 aec3 771a 4b61 96d0 7abe
|
|
|
|
|
+9410 54d4 44a8 2005 9504 0b81 66e0 82a6
|
|
|
|
|
+2d1b ff6e 919d 29ad 1718 63c7 8f0b 97c8
|
|
|
|
|
+e9ae 82ae 43d3
|
|
|
|
|
+`),
|
|
|
|
|
+ []HeaderField{
|
|
|
|
|
+ pair(":status", "302"),
|
|
|
|
|
+ pair("cache-control", "private"),
|
|
|
|
|
+ pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"),
|
|
|
|
|
+ pair("location", "https://www.example.com"),
|
|
|
|
|
+ },
|
|
|
|
|
+ []HeaderField{
|
|
|
|
|
+ pair("location", "https://www.example.com"),
|
|
|
|
|
+ pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"),
|
|
|
|
|
+ pair("cache-control", "private"),
|
|
|
|
|
+ pair(":status", "302"),
|
|
|
|
|
+ },
|
|
|
|
|
+ 222,
|
|
|
|
|
+ },
|
|
|
|
|
+ {dehex("4883 640e ffc1 c0bf"),
|
|
|
|
|
+ []HeaderField{
|
|
|
|
|
+ pair(":status", "307"),
|
|
|
|
|
+ pair("cache-control", "private"),
|
|
|
|
|
+ pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"),
|
|
|
|
|
+ pair("location", "https://www.example.com"),
|
|
|
|
|
+ },
|
|
|
|
|
+ []HeaderField{
|
|
|
|
|
+ pair(":status", "307"),
|
|
|
|
|
+ pair("location", "https://www.example.com"),
|
|
|
|
|
+ pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"),
|
|
|
|
|
+ pair("cache-control", "private"),
|
|
|
|
|
+ },
|
|
|
|
|
+ 222,
|
|
|
|
|
+ },
|
|
|
|
|
+ {dehex(`
|
|
|
|
|
+88c1 6196 d07a be94 1054 d444 a820 0595
|
|
|
|
|
+040b 8166 e084 a62d 1bff c05a 839b d9ab
|
|
|
|
|
+77ad 94e7 821d d7f2 e6c7 b335 dfdf cd5b
|
|
|
|
|
+3960 d5af 2708 7f36 72c1 ab27 0fb5 291f
|
|
|
|
|
+9587 3160 65c0 03ed 4ee5 b106 3d50 07
|
|
|
|
|
+`),
|
|
|
|
|
+ []HeaderField{
|
|
|
|
|
+ pair(":status", "200"),
|
|
|
|
|
+ pair("cache-control", "private"),
|
|
|
|
|
+ pair("date", "Mon, 21 Oct 2013 20:13:22 GMT"),
|
|
|
|
|
+ pair("location", "https://www.example.com"),
|
|
|
|
|
+ pair("content-encoding", "gzip"),
|
|
|
|
|
+ pair("set-cookie", "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1"),
|
|
|
|
|
+ },
|
|
|
|
|
+ []HeaderField{
|
|
|
|
|
+ pair("set-cookie", "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1"),
|
|
|
|
|
+ pair("content-encoding", "gzip"),
|
|
|
|
|
+ pair("date", "Mon, 21 Oct 2013 20:13:22 GMT"),
|
|
|
|
|
+ },
|
|
|
|
|
+ 215,
|
|
|
|
|
+ },
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func testDecodeSeries(t *testing.T, size uint32, steps []encAndWant) {
|
|
|
|
|
+ d := NewDecoder(size, nil)
|
|
|
for i, step := range steps {
|
|
for i, step := range steps {
|
|
|
hf, err := d.DecodeFull(step.enc)
|
|
hf, err := d.DecodeFull(step.enc)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
@@ -439,6 +578,7 @@ func TestReadVarInt(t *testing.T) {
|
|
|
|
|
|
|
|
func dehex(s string) []byte {
|
|
func dehex(s string) []byte {
|
|
|
s = strings.Replace(s, " ", "", -1)
|
|
s = strings.Replace(s, " ", "", -1)
|
|
|
|
|
+ s = strings.Replace(s, "\n", "", -1)
|
|
|
b, err := hex.DecodeString(s)
|
|
b, err := hex.DecodeString(s)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
panic(err)
|
|
panic(err)
|