mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-07 19:23:40 +00:00
Remove the dead golang.org/x/net/spdy/
This commit is contained in:
parent
bc07f63190
commit
a8b4e42483
5
Godeps/Godeps.json
generated
5
Godeps/Godeps.json
generated
@ -552,11 +552,6 @@
|
|||||||
"ImportPath": "golang.org/x/net/html",
|
"ImportPath": "golang.org/x/net/html",
|
||||||
"Rev": "cbcac7bb8415db9b6cb4d1ebab1dc9afbd688b97"
|
"Rev": "cbcac7bb8415db9b6cb4d1ebab1dc9afbd688b97"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/net/spdy",
|
|
||||||
"Comment": "deleted-upstream",
|
|
||||||
"Rev": "d175081df37eff8cda13f478bc11a0a65b39958b"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"ImportPath": "golang.org/x/net/websocket",
|
"ImportPath": "golang.org/x/net/websocket",
|
||||||
"Rev": "cbcac7bb8415db9b6cb4d1ebab1dc9afbd688b97"
|
"Rev": "cbcac7bb8415db9b6cb4d1ebab1dc9afbd688b97"
|
||||||
|
187
Godeps/_workspace/src/golang.org/x/net/spdy/dictionary.go
generated
vendored
187
Godeps/_workspace/src/golang.org/x/net/spdy/dictionary.go
generated
vendored
@ -1,187 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package spdy
|
|
||||||
|
|
||||||
// headerDictionary is the dictionary sent to the zlib compressor/decompressor.
|
|
||||||
var headerDictionary = []byte{
|
|
||||||
0x00, 0x00, 0x00, 0x07, 0x6f, 0x70, 0x74, 0x69,
|
|
||||||
0x6f, 0x6e, 0x73, 0x00, 0x00, 0x00, 0x04, 0x68,
|
|
||||||
0x65, 0x61, 0x64, 0x00, 0x00, 0x00, 0x04, 0x70,
|
|
||||||
0x6f, 0x73, 0x74, 0x00, 0x00, 0x00, 0x03, 0x70,
|
|
||||||
0x75, 0x74, 0x00, 0x00, 0x00, 0x06, 0x64, 0x65,
|
|
||||||
0x6c, 0x65, 0x74, 0x65, 0x00, 0x00, 0x00, 0x05,
|
|
||||||
0x74, 0x72, 0x61, 0x63, 0x65, 0x00, 0x00, 0x00,
|
|
||||||
0x06, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x00,
|
|
||||||
0x00, 0x00, 0x0e, 0x61, 0x63, 0x63, 0x65, 0x70,
|
|
||||||
0x74, 0x2d, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65,
|
|
||||||
0x74, 0x00, 0x00, 0x00, 0x0f, 0x61, 0x63, 0x63,
|
|
||||||
0x65, 0x70, 0x74, 0x2d, 0x65, 0x6e, 0x63, 0x6f,
|
|
||||||
0x64, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x0f,
|
|
||||||
0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x6c,
|
|
||||||
0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x00,
|
|
||||||
0x00, 0x00, 0x0d, 0x61, 0x63, 0x63, 0x65, 0x70,
|
|
||||||
0x74, 0x2d, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73,
|
|
||||||
0x00, 0x00, 0x00, 0x03, 0x61, 0x67, 0x65, 0x00,
|
|
||||||
0x00, 0x00, 0x05, 0x61, 0x6c, 0x6c, 0x6f, 0x77,
|
|
||||||
0x00, 0x00, 0x00, 0x0d, 0x61, 0x75, 0x74, 0x68,
|
|
||||||
0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f,
|
|
||||||
0x6e, 0x00, 0x00, 0x00, 0x0d, 0x63, 0x61, 0x63,
|
|
||||||
0x68, 0x65, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72,
|
|
||||||
0x6f, 0x6c, 0x00, 0x00, 0x00, 0x0a, 0x63, 0x6f,
|
|
||||||
0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e,
|
|
||||||
0x00, 0x00, 0x00, 0x0c, 0x63, 0x6f, 0x6e, 0x74,
|
|
||||||
0x65, 0x6e, 0x74, 0x2d, 0x62, 0x61, 0x73, 0x65,
|
|
||||||
0x00, 0x00, 0x00, 0x10, 0x63, 0x6f, 0x6e, 0x74,
|
|
||||||
0x65, 0x6e, 0x74, 0x2d, 0x65, 0x6e, 0x63, 0x6f,
|
|
||||||
0x64, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x10,
|
|
||||||
0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d,
|
|
||||||
0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65,
|
|
||||||
0x00, 0x00, 0x00, 0x0e, 0x63, 0x6f, 0x6e, 0x74,
|
|
||||||
0x65, 0x6e, 0x74, 0x2d, 0x6c, 0x65, 0x6e, 0x67,
|
|
||||||
0x74, 0x68, 0x00, 0x00, 0x00, 0x10, 0x63, 0x6f,
|
|
||||||
0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x6c, 0x6f,
|
|
||||||
0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00,
|
|
||||||
0x00, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e,
|
|
||||||
0x74, 0x2d, 0x6d, 0x64, 0x35, 0x00, 0x00, 0x00,
|
|
||||||
0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
|
|
||||||
0x2d, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00,
|
|
||||||
0x00, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e,
|
|
||||||
0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x00, 0x00,
|
|
||||||
0x00, 0x04, 0x64, 0x61, 0x74, 0x65, 0x00, 0x00,
|
|
||||||
0x00, 0x04, 0x65, 0x74, 0x61, 0x67, 0x00, 0x00,
|
|
||||||
0x00, 0x06, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74,
|
|
||||||
0x00, 0x00, 0x00, 0x07, 0x65, 0x78, 0x70, 0x69,
|
|
||||||
0x72, 0x65, 0x73, 0x00, 0x00, 0x00, 0x04, 0x66,
|
|
||||||
0x72, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x04, 0x68,
|
|
||||||
0x6f, 0x73, 0x74, 0x00, 0x00, 0x00, 0x08, 0x69,
|
|
||||||
0x66, 0x2d, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x00,
|
|
||||||
0x00, 0x00, 0x11, 0x69, 0x66, 0x2d, 0x6d, 0x6f,
|
|
||||||
0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x2d, 0x73,
|
|
||||||
0x69, 0x6e, 0x63, 0x65, 0x00, 0x00, 0x00, 0x0d,
|
|
||||||
0x69, 0x66, 0x2d, 0x6e, 0x6f, 0x6e, 0x65, 0x2d,
|
|
||||||
0x6d, 0x61, 0x74, 0x63, 0x68, 0x00, 0x00, 0x00,
|
|
||||||
0x08, 0x69, 0x66, 0x2d, 0x72, 0x61, 0x6e, 0x67,
|
|
||||||
0x65, 0x00, 0x00, 0x00, 0x13, 0x69, 0x66, 0x2d,
|
|
||||||
0x75, 0x6e, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69,
|
|
||||||
0x65, 0x64, 0x2d, 0x73, 0x69, 0x6e, 0x63, 0x65,
|
|
||||||
0x00, 0x00, 0x00, 0x0d, 0x6c, 0x61, 0x73, 0x74,
|
|
||||||
0x2d, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65,
|
|
||||||
0x64, 0x00, 0x00, 0x00, 0x08, 0x6c, 0x6f, 0x63,
|
|
||||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00,
|
|
||||||
0x0c, 0x6d, 0x61, 0x78, 0x2d, 0x66, 0x6f, 0x72,
|
|
||||||
0x77, 0x61, 0x72, 0x64, 0x73, 0x00, 0x00, 0x00,
|
|
||||||
0x06, 0x70, 0x72, 0x61, 0x67, 0x6d, 0x61, 0x00,
|
|
||||||
0x00, 0x00, 0x12, 0x70, 0x72, 0x6f, 0x78, 0x79,
|
|
||||||
0x2d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74,
|
|
||||||
0x69, 0x63, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00,
|
|
||||||
0x13, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2d, 0x61,
|
|
||||||
0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61,
|
|
||||||
0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x05,
|
|
||||||
0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, 0x00,
|
|
||||||
0x07, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x72,
|
|
||||||
0x00, 0x00, 0x00, 0x0b, 0x72, 0x65, 0x74, 0x72,
|
|
||||||
0x79, 0x2d, 0x61, 0x66, 0x74, 0x65, 0x72, 0x00,
|
|
||||||
0x00, 0x00, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65,
|
|
||||||
0x72, 0x00, 0x00, 0x00, 0x02, 0x74, 0x65, 0x00,
|
|
||||||
0x00, 0x00, 0x07, 0x74, 0x72, 0x61, 0x69, 0x6c,
|
|
||||||
0x65, 0x72, 0x00, 0x00, 0x00, 0x11, 0x74, 0x72,
|
|
||||||
0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2d, 0x65,
|
|
||||||
0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x00,
|
|
||||||
0x00, 0x00, 0x07, 0x75, 0x70, 0x67, 0x72, 0x61,
|
|
||||||
0x64, 0x65, 0x00, 0x00, 0x00, 0x0a, 0x75, 0x73,
|
|
||||||
0x65, 0x72, 0x2d, 0x61, 0x67, 0x65, 0x6e, 0x74,
|
|
||||||
0x00, 0x00, 0x00, 0x04, 0x76, 0x61, 0x72, 0x79,
|
|
||||||
0x00, 0x00, 0x00, 0x03, 0x76, 0x69, 0x61, 0x00,
|
|
||||||
0x00, 0x00, 0x07, 0x77, 0x61, 0x72, 0x6e, 0x69,
|
|
||||||
0x6e, 0x67, 0x00, 0x00, 0x00, 0x10, 0x77, 0x77,
|
|
||||||
0x77, 0x2d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e,
|
|
||||||
0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x00, 0x00,
|
|
||||||
0x00, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64,
|
|
||||||
0x00, 0x00, 0x00, 0x03, 0x67, 0x65, 0x74, 0x00,
|
|
||||||
0x00, 0x00, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75,
|
|
||||||
0x73, 0x00, 0x00, 0x00, 0x06, 0x32, 0x30, 0x30,
|
|
||||||
0x20, 0x4f, 0x4b, 0x00, 0x00, 0x00, 0x07, 0x76,
|
|
||||||
0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x00, 0x00,
|
|
||||||
0x00, 0x08, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31,
|
|
||||||
0x2e, 0x31, 0x00, 0x00, 0x00, 0x03, 0x75, 0x72,
|
|
||||||
0x6c, 0x00, 0x00, 0x00, 0x06, 0x70, 0x75, 0x62,
|
|
||||||
0x6c, 0x69, 0x63, 0x00, 0x00, 0x00, 0x0a, 0x73,
|
|
||||||
0x65, 0x74, 0x2d, 0x63, 0x6f, 0x6f, 0x6b, 0x69,
|
|
||||||
0x65, 0x00, 0x00, 0x00, 0x0a, 0x6b, 0x65, 0x65,
|
|
||||||
0x70, 0x2d, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x00,
|
|
||||||
0x00, 0x00, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69,
|
|
||||||
0x6e, 0x31, 0x30, 0x30, 0x31, 0x30, 0x31, 0x32,
|
|
||||||
0x30, 0x31, 0x32, 0x30, 0x32, 0x32, 0x30, 0x35,
|
|
||||||
0x32, 0x30, 0x36, 0x33, 0x30, 0x30, 0x33, 0x30,
|
|
||||||
0x32, 0x33, 0x30, 0x33, 0x33, 0x30, 0x34, 0x33,
|
|
||||||
0x30, 0x35, 0x33, 0x30, 0x36, 0x33, 0x30, 0x37,
|
|
||||||
0x34, 0x30, 0x32, 0x34, 0x30, 0x35, 0x34, 0x30,
|
|
||||||
0x36, 0x34, 0x30, 0x37, 0x34, 0x30, 0x38, 0x34,
|
|
||||||
0x30, 0x39, 0x34, 0x31, 0x30, 0x34, 0x31, 0x31,
|
|
||||||
0x34, 0x31, 0x32, 0x34, 0x31, 0x33, 0x34, 0x31,
|
|
||||||
0x34, 0x34, 0x31, 0x35, 0x34, 0x31, 0x36, 0x34,
|
|
||||||
0x31, 0x37, 0x35, 0x30, 0x32, 0x35, 0x30, 0x34,
|
|
||||||
0x35, 0x30, 0x35, 0x32, 0x30, 0x33, 0x20, 0x4e,
|
|
||||||
0x6f, 0x6e, 0x2d, 0x41, 0x75, 0x74, 0x68, 0x6f,
|
|
||||||
0x72, 0x69, 0x74, 0x61, 0x74, 0x69, 0x76, 0x65,
|
|
||||||
0x20, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61,
|
|
||||||
0x74, 0x69, 0x6f, 0x6e, 0x32, 0x30, 0x34, 0x20,
|
|
||||||
0x4e, 0x6f, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x65,
|
|
||||||
0x6e, 0x74, 0x33, 0x30, 0x31, 0x20, 0x4d, 0x6f,
|
|
||||||
0x76, 0x65, 0x64, 0x20, 0x50, 0x65, 0x72, 0x6d,
|
|
||||||
0x61, 0x6e, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x34,
|
|
||||||
0x30, 0x30, 0x20, 0x42, 0x61, 0x64, 0x20, 0x52,
|
|
||||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x34, 0x30,
|
|
||||||
0x31, 0x20, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68,
|
|
||||||
0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x34, 0x30,
|
|
||||||
0x33, 0x20, 0x46, 0x6f, 0x72, 0x62, 0x69, 0x64,
|
|
||||||
0x64, 0x65, 0x6e, 0x34, 0x30, 0x34, 0x20, 0x4e,
|
|
||||||
0x6f, 0x74, 0x20, 0x46, 0x6f, 0x75, 0x6e, 0x64,
|
|
||||||
0x35, 0x30, 0x30, 0x20, 0x49, 0x6e, 0x74, 0x65,
|
|
||||||
0x72, 0x6e, 0x61, 0x6c, 0x20, 0x53, 0x65, 0x72,
|
|
||||||
0x76, 0x65, 0x72, 0x20, 0x45, 0x72, 0x72, 0x6f,
|
|
||||||
0x72, 0x35, 0x30, 0x31, 0x20, 0x4e, 0x6f, 0x74,
|
|
||||||
0x20, 0x49, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65,
|
|
||||||
0x6e, 0x74, 0x65, 0x64, 0x35, 0x30, 0x33, 0x20,
|
|
||||||
0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x20,
|
|
||||||
0x55, 0x6e, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61,
|
|
||||||
0x62, 0x6c, 0x65, 0x4a, 0x61, 0x6e, 0x20, 0x46,
|
|
||||||
0x65, 0x62, 0x20, 0x4d, 0x61, 0x72, 0x20, 0x41,
|
|
||||||
0x70, 0x72, 0x20, 0x4d, 0x61, 0x79, 0x20, 0x4a,
|
|
||||||
0x75, 0x6e, 0x20, 0x4a, 0x75, 0x6c, 0x20, 0x41,
|
|
||||||
0x75, 0x67, 0x20, 0x53, 0x65, 0x70, 0x74, 0x20,
|
|
||||||
0x4f, 0x63, 0x74, 0x20, 0x4e, 0x6f, 0x76, 0x20,
|
|
||||||
0x44, 0x65, 0x63, 0x20, 0x30, 0x30, 0x3a, 0x30,
|
|
||||||
0x30, 0x3a, 0x30, 0x30, 0x20, 0x4d, 0x6f, 0x6e,
|
|
||||||
0x2c, 0x20, 0x54, 0x75, 0x65, 0x2c, 0x20, 0x57,
|
|
||||||
0x65, 0x64, 0x2c, 0x20, 0x54, 0x68, 0x75, 0x2c,
|
|
||||||
0x20, 0x46, 0x72, 0x69, 0x2c, 0x20, 0x53, 0x61,
|
|
||||||
0x74, 0x2c, 0x20, 0x53, 0x75, 0x6e, 0x2c, 0x20,
|
|
||||||
0x47, 0x4d, 0x54, 0x63, 0x68, 0x75, 0x6e, 0x6b,
|
|
||||||
0x65, 0x64, 0x2c, 0x74, 0x65, 0x78, 0x74, 0x2f,
|
|
||||||
0x68, 0x74, 0x6d, 0x6c, 0x2c, 0x69, 0x6d, 0x61,
|
|
||||||
0x67, 0x65, 0x2f, 0x70, 0x6e, 0x67, 0x2c, 0x69,
|
|
||||||
0x6d, 0x61, 0x67, 0x65, 0x2f, 0x6a, 0x70, 0x67,
|
|
||||||
0x2c, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67,
|
|
||||||
0x69, 0x66, 0x2c, 0x61, 0x70, 0x70, 0x6c, 0x69,
|
|
||||||
0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78,
|
|
||||||
0x6d, 0x6c, 0x2c, 0x61, 0x70, 0x70, 0x6c, 0x69,
|
|
||||||
0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78,
|
|
||||||
0x68, 0x74, 0x6d, 0x6c, 0x2b, 0x78, 0x6d, 0x6c,
|
|
||||||
0x2c, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c,
|
|
||||||
0x61, 0x69, 0x6e, 0x2c, 0x74, 0x65, 0x78, 0x74,
|
|
||||||
0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72,
|
|
||||||
0x69, 0x70, 0x74, 0x2c, 0x70, 0x75, 0x62, 0x6c,
|
|
||||||
0x69, 0x63, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74,
|
|
||||||
0x65, 0x6d, 0x61, 0x78, 0x2d, 0x61, 0x67, 0x65,
|
|
||||||
0x3d, 0x67, 0x7a, 0x69, 0x70, 0x2c, 0x64, 0x65,
|
|
||||||
0x66, 0x6c, 0x61, 0x74, 0x65, 0x2c, 0x73, 0x64,
|
|
||||||
0x63, 0x68, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65,
|
|
||||||
0x74, 0x3d, 0x75, 0x74, 0x66, 0x2d, 0x38, 0x63,
|
|
||||||
0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, 0x69,
|
|
||||||
0x73, 0x6f, 0x2d, 0x38, 0x38, 0x35, 0x39, 0x2d,
|
|
||||||
0x31, 0x2c, 0x75, 0x74, 0x66, 0x2d, 0x2c, 0x2a,
|
|
||||||
0x2c, 0x65, 0x6e, 0x71, 0x3d, 0x30, 0x2e,
|
|
||||||
}
|
|
348
Godeps/_workspace/src/golang.org/x/net/spdy/read.go
generated
vendored
348
Godeps/_workspace/src/golang.org/x/net/spdy/read.go
generated
vendored
@ -1,348 +0,0 @@
|
|||||||
// Copyright 2011 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package spdy
|
|
||||||
|
|
||||||
import (
|
|
||||||
"compress/zlib"
|
|
||||||
"encoding/binary"
|
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (frame *SynStreamFrame) read(h ControlFrameHeader, f *Framer) error {
|
|
||||||
return f.readSynStreamFrame(h, frame)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (frame *SynReplyFrame) read(h ControlFrameHeader, f *Framer) error {
|
|
||||||
return f.readSynReplyFrame(h, frame)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (frame *RstStreamFrame) read(h ControlFrameHeader, f *Framer) error {
|
|
||||||
frame.CFHeader = h
|
|
||||||
if err := binary.Read(f.r, binary.BigEndian, &frame.StreamId); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := binary.Read(f.r, binary.BigEndian, &frame.Status); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if frame.Status == 0 {
|
|
||||||
return &Error{InvalidControlFrame, frame.StreamId}
|
|
||||||
}
|
|
||||||
if frame.StreamId == 0 {
|
|
||||||
return &Error{ZeroStreamId, 0}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (frame *SettingsFrame) read(h ControlFrameHeader, f *Framer) error {
|
|
||||||
frame.CFHeader = h
|
|
||||||
var numSettings uint32
|
|
||||||
if err := binary.Read(f.r, binary.BigEndian, &numSettings); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
frame.FlagIdValues = make([]SettingsFlagIdValue, numSettings)
|
|
||||||
for i := uint32(0); i < numSettings; i++ {
|
|
||||||
if err := binary.Read(f.r, binary.BigEndian, &frame.FlagIdValues[i].Id); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
frame.FlagIdValues[i].Flag = SettingsFlag((frame.FlagIdValues[i].Id & 0xff000000) >> 24)
|
|
||||||
frame.FlagIdValues[i].Id &= 0xffffff
|
|
||||||
if err := binary.Read(f.r, binary.BigEndian, &frame.FlagIdValues[i].Value); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (frame *PingFrame) read(h ControlFrameHeader, f *Framer) error {
|
|
||||||
frame.CFHeader = h
|
|
||||||
if err := binary.Read(f.r, binary.BigEndian, &frame.Id); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if frame.Id == 0 {
|
|
||||||
return &Error{ZeroStreamId, 0}
|
|
||||||
}
|
|
||||||
if frame.CFHeader.Flags != 0 {
|
|
||||||
return &Error{InvalidControlFrame, StreamId(frame.Id)}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (frame *GoAwayFrame) read(h ControlFrameHeader, f *Framer) error {
|
|
||||||
frame.CFHeader = h
|
|
||||||
if err := binary.Read(f.r, binary.BigEndian, &frame.LastGoodStreamId); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if frame.CFHeader.Flags != 0 {
|
|
||||||
return &Error{InvalidControlFrame, frame.LastGoodStreamId}
|
|
||||||
}
|
|
||||||
if frame.CFHeader.length != 8 {
|
|
||||||
return &Error{InvalidControlFrame, frame.LastGoodStreamId}
|
|
||||||
}
|
|
||||||
if err := binary.Read(f.r, binary.BigEndian, &frame.Status); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (frame *HeadersFrame) read(h ControlFrameHeader, f *Framer) error {
|
|
||||||
return f.readHeadersFrame(h, frame)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (frame *WindowUpdateFrame) read(h ControlFrameHeader, f *Framer) error {
|
|
||||||
frame.CFHeader = h
|
|
||||||
if err := binary.Read(f.r, binary.BigEndian, &frame.StreamId); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if frame.CFHeader.Flags != 0 {
|
|
||||||
return &Error{InvalidControlFrame, frame.StreamId}
|
|
||||||
}
|
|
||||||
if frame.CFHeader.length != 8 {
|
|
||||||
return &Error{InvalidControlFrame, frame.StreamId}
|
|
||||||
}
|
|
||||||
if err := binary.Read(f.r, binary.BigEndian, &frame.DeltaWindowSize); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func newControlFrame(frameType ControlFrameType) (controlFrame, error) {
|
|
||||||
ctor, ok := cframeCtor[frameType]
|
|
||||||
if !ok {
|
|
||||||
return nil, &Error{Err: InvalidControlFrame}
|
|
||||||
}
|
|
||||||
return ctor(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var cframeCtor = map[ControlFrameType]func() controlFrame{
|
|
||||||
TypeSynStream: func() controlFrame { return new(SynStreamFrame) },
|
|
||||||
TypeSynReply: func() controlFrame { return new(SynReplyFrame) },
|
|
||||||
TypeRstStream: func() controlFrame { return new(RstStreamFrame) },
|
|
||||||
TypeSettings: func() controlFrame { return new(SettingsFrame) },
|
|
||||||
TypePing: func() controlFrame { return new(PingFrame) },
|
|
||||||
TypeGoAway: func() controlFrame { return new(GoAwayFrame) },
|
|
||||||
TypeHeaders: func() controlFrame { return new(HeadersFrame) },
|
|
||||||
TypeWindowUpdate: func() controlFrame { return new(WindowUpdateFrame) },
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *Framer) uncorkHeaderDecompressor(payloadSize int64) error {
|
|
||||||
if f.headerDecompressor != nil {
|
|
||||||
f.headerReader.N = payloadSize
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
f.headerReader = io.LimitedReader{R: f.r, N: payloadSize}
|
|
||||||
decompressor, err := zlib.NewReaderDict(&f.headerReader, []byte(headerDictionary))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
f.headerDecompressor = decompressor
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadFrame reads SPDY encoded data and returns a decompressed Frame.
|
|
||||||
func (f *Framer) ReadFrame() (Frame, error) {
|
|
||||||
var firstWord uint32
|
|
||||||
if err := binary.Read(f.r, binary.BigEndian, &firstWord); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if firstWord&0x80000000 != 0 {
|
|
||||||
frameType := ControlFrameType(firstWord & 0xffff)
|
|
||||||
version := uint16(firstWord >> 16 & 0x7fff)
|
|
||||||
return f.parseControlFrame(version, frameType)
|
|
||||||
}
|
|
||||||
return f.parseDataFrame(StreamId(firstWord & 0x7fffffff))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *Framer) parseControlFrame(version uint16, frameType ControlFrameType) (Frame, error) {
|
|
||||||
var length uint32
|
|
||||||
if err := binary.Read(f.r, binary.BigEndian, &length); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
flags := ControlFlags((length & 0xff000000) >> 24)
|
|
||||||
length &= 0xffffff
|
|
||||||
header := ControlFrameHeader{version, frameType, flags, length}
|
|
||||||
cframe, err := newControlFrame(frameType)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if err = cframe.read(header, f); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return cframe, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseHeaderValueBlock(r io.Reader, streamId StreamId) (http.Header, error) {
|
|
||||||
var numHeaders uint32
|
|
||||||
if err := binary.Read(r, binary.BigEndian, &numHeaders); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
var e error
|
|
||||||
h := make(http.Header, int(numHeaders))
|
|
||||||
for i := 0; i < int(numHeaders); i++ {
|
|
||||||
var length uint32
|
|
||||||
if err := binary.Read(r, binary.BigEndian, &length); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
nameBytes := make([]byte, length)
|
|
||||||
if _, err := io.ReadFull(r, nameBytes); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
name := string(nameBytes)
|
|
||||||
if name != strings.ToLower(name) {
|
|
||||||
e = &Error{UnlowercasedHeaderName, streamId}
|
|
||||||
name = strings.ToLower(name)
|
|
||||||
}
|
|
||||||
if h[name] != nil {
|
|
||||||
e = &Error{DuplicateHeaders, streamId}
|
|
||||||
}
|
|
||||||
if err := binary.Read(r, binary.BigEndian, &length); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
value := make([]byte, length)
|
|
||||||
if _, err := io.ReadFull(r, value); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
valueList := strings.Split(string(value), headerValueSeparator)
|
|
||||||
for _, v := range valueList {
|
|
||||||
h.Add(name, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if e != nil {
|
|
||||||
return h, e
|
|
||||||
}
|
|
||||||
return h, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *Framer) readSynStreamFrame(h ControlFrameHeader, frame *SynStreamFrame) error {
|
|
||||||
frame.CFHeader = h
|
|
||||||
var err error
|
|
||||||
if err = binary.Read(f.r, binary.BigEndian, &frame.StreamId); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err = binary.Read(f.r, binary.BigEndian, &frame.AssociatedToStreamId); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err = binary.Read(f.r, binary.BigEndian, &frame.Priority); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
frame.Priority >>= 5
|
|
||||||
if err = binary.Read(f.r, binary.BigEndian, &frame.Slot); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
reader := f.r
|
|
||||||
if !f.headerCompressionDisabled {
|
|
||||||
err := f.uncorkHeaderDecompressor(int64(h.length - 10))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
reader = f.headerDecompressor
|
|
||||||
}
|
|
||||||
frame.Headers, err = parseHeaderValueBlock(reader, frame.StreamId)
|
|
||||||
if !f.headerCompressionDisabled && (err == io.EOF && f.headerReader.N == 0 || f.headerReader.N != 0) {
|
|
||||||
err = &Error{WrongCompressedPayloadSize, 0}
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for h := range frame.Headers {
|
|
||||||
if invalidReqHeaders[h] {
|
|
||||||
return &Error{InvalidHeaderPresent, frame.StreamId}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if frame.StreamId == 0 {
|
|
||||||
return &Error{ZeroStreamId, 0}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *Framer) readSynReplyFrame(h ControlFrameHeader, frame *SynReplyFrame) error {
|
|
||||||
frame.CFHeader = h
|
|
||||||
var err error
|
|
||||||
if err = binary.Read(f.r, binary.BigEndian, &frame.StreamId); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
reader := f.r
|
|
||||||
if !f.headerCompressionDisabled {
|
|
||||||
err := f.uncorkHeaderDecompressor(int64(h.length - 4))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
reader = f.headerDecompressor
|
|
||||||
}
|
|
||||||
frame.Headers, err = parseHeaderValueBlock(reader, frame.StreamId)
|
|
||||||
if !f.headerCompressionDisabled && (err == io.EOF && f.headerReader.N == 0 || f.headerReader.N != 0) {
|
|
||||||
err = &Error{WrongCompressedPayloadSize, 0}
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for h := range frame.Headers {
|
|
||||||
if invalidRespHeaders[h] {
|
|
||||||
return &Error{InvalidHeaderPresent, frame.StreamId}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if frame.StreamId == 0 {
|
|
||||||
return &Error{ZeroStreamId, 0}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *Framer) readHeadersFrame(h ControlFrameHeader, frame *HeadersFrame) error {
|
|
||||||
frame.CFHeader = h
|
|
||||||
var err error
|
|
||||||
if err = binary.Read(f.r, binary.BigEndian, &frame.StreamId); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
reader := f.r
|
|
||||||
if !f.headerCompressionDisabled {
|
|
||||||
err := f.uncorkHeaderDecompressor(int64(h.length - 4))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
reader = f.headerDecompressor
|
|
||||||
}
|
|
||||||
frame.Headers, err = parseHeaderValueBlock(reader, frame.StreamId)
|
|
||||||
if !f.headerCompressionDisabled && (err == io.EOF && f.headerReader.N == 0 || f.headerReader.N != 0) {
|
|
||||||
err = &Error{WrongCompressedPayloadSize, 0}
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
var invalidHeaders map[string]bool
|
|
||||||
if frame.StreamId%2 == 0 {
|
|
||||||
invalidHeaders = invalidReqHeaders
|
|
||||||
} else {
|
|
||||||
invalidHeaders = invalidRespHeaders
|
|
||||||
}
|
|
||||||
for h := range frame.Headers {
|
|
||||||
if invalidHeaders[h] {
|
|
||||||
return &Error{InvalidHeaderPresent, frame.StreamId}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if frame.StreamId == 0 {
|
|
||||||
return &Error{ZeroStreamId, 0}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *Framer) parseDataFrame(streamId StreamId) (*DataFrame, error) {
|
|
||||||
var length uint32
|
|
||||||
if err := binary.Read(f.r, binary.BigEndian, &length); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
var frame DataFrame
|
|
||||||
frame.StreamId = streamId
|
|
||||||
frame.Flags = DataFlags(length >> 24)
|
|
||||||
length &= 0xffffff
|
|
||||||
frame.Data = make([]byte, length)
|
|
||||||
if _, err := io.ReadFull(f.r, frame.Data); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if frame.StreamId == 0 {
|
|
||||||
return nil, &Error{ZeroStreamId, 0}
|
|
||||||
}
|
|
||||||
return &frame, nil
|
|
||||||
}
|
|
644
Godeps/_workspace/src/golang.org/x/net/spdy/spdy_test.go
generated
vendored
644
Godeps/_workspace/src/golang.org/x/net/spdy/spdy_test.go
generated
vendored
@ -1,644 +0,0 @@
|
|||||||
// Copyright 2011 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package spdy
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"compress/zlib"
|
|
||||||
"encoding/base64"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
var HeadersFixture = http.Header{
|
|
||||||
"Url": []string{"http://www.google.com/"},
|
|
||||||
"Method": []string{"get"},
|
|
||||||
"Version": []string{"http/1.1"},
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHeaderParsing(t *testing.T) {
|
|
||||||
var headerValueBlockBuf bytes.Buffer
|
|
||||||
writeHeaderValueBlock(&headerValueBlockBuf, HeadersFixture)
|
|
||||||
const bogusStreamId = 1
|
|
||||||
newHeaders, err := parseHeaderValueBlock(&headerValueBlockBuf, bogusStreamId)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("parseHeaderValueBlock:", err)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(HeadersFixture, newHeaders) {
|
|
||||||
t.Fatal("got: ", newHeaders, "\nwant: ", HeadersFixture)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCreateParseSynStreamFrameCompressionDisable(t *testing.T) {
|
|
||||||
buffer := new(bytes.Buffer)
|
|
||||||
// Fixture framer for no compression test.
|
|
||||||
framer := &Framer{
|
|
||||||
headerCompressionDisabled: true,
|
|
||||||
w: buffer,
|
|
||||||
headerBuf: new(bytes.Buffer),
|
|
||||||
r: buffer,
|
|
||||||
}
|
|
||||||
synStreamFrame := SynStreamFrame{
|
|
||||||
CFHeader: ControlFrameHeader{
|
|
||||||
version: Version,
|
|
||||||
frameType: TypeSynStream,
|
|
||||||
},
|
|
||||||
StreamId: 2,
|
|
||||||
Headers: HeadersFixture,
|
|
||||||
}
|
|
||||||
if err := framer.WriteFrame(&synStreamFrame); err != nil {
|
|
||||||
t.Fatal("WriteFrame without compression:", err)
|
|
||||||
}
|
|
||||||
frame, err := framer.ReadFrame()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("ReadFrame without compression:", err)
|
|
||||||
}
|
|
||||||
parsedSynStreamFrame, ok := frame.(*SynStreamFrame)
|
|
||||||
if !ok {
|
|
||||||
t.Fatal("Parsed incorrect frame type:", frame)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(synStreamFrame, *parsedSynStreamFrame) {
|
|
||||||
t.Fatal("got: ", *parsedSynStreamFrame, "\nwant: ", synStreamFrame)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCreateParseSynStreamFrameCompressionEnable(t *testing.T) {
|
|
||||||
buffer := new(bytes.Buffer)
|
|
||||||
framer, err := NewFramer(buffer, buffer)
|
|
||||||
synStreamFrame := SynStreamFrame{
|
|
||||||
CFHeader: ControlFrameHeader{
|
|
||||||
version: Version,
|
|
||||||
frameType: TypeSynStream,
|
|
||||||
},
|
|
||||||
StreamId: 2,
|
|
||||||
Headers: HeadersFixture,
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("Failed to create new framer:", err)
|
|
||||||
}
|
|
||||||
if err := framer.WriteFrame(&synStreamFrame); err != nil {
|
|
||||||
t.Fatal("WriteFrame with compression:", err)
|
|
||||||
}
|
|
||||||
frame, err := framer.ReadFrame()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("ReadFrame with compression:", err)
|
|
||||||
}
|
|
||||||
parsedSynStreamFrame, ok := frame.(*SynStreamFrame)
|
|
||||||
if !ok {
|
|
||||||
t.Fatal("Parsed incorrect frame type:", frame)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(synStreamFrame, *parsedSynStreamFrame) {
|
|
||||||
t.Fatal("got: ", *parsedSynStreamFrame, "\nwant: ", synStreamFrame)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCreateParseSynReplyFrameCompressionDisable(t *testing.T) {
|
|
||||||
buffer := new(bytes.Buffer)
|
|
||||||
framer := &Framer{
|
|
||||||
headerCompressionDisabled: true,
|
|
||||||
w: buffer,
|
|
||||||
headerBuf: new(bytes.Buffer),
|
|
||||||
r: buffer,
|
|
||||||
}
|
|
||||||
synReplyFrame := SynReplyFrame{
|
|
||||||
CFHeader: ControlFrameHeader{
|
|
||||||
version: Version,
|
|
||||||
frameType: TypeSynReply,
|
|
||||||
},
|
|
||||||
StreamId: 2,
|
|
||||||
Headers: HeadersFixture,
|
|
||||||
}
|
|
||||||
if err := framer.WriteFrame(&synReplyFrame); err != nil {
|
|
||||||
t.Fatal("WriteFrame without compression:", err)
|
|
||||||
}
|
|
||||||
frame, err := framer.ReadFrame()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("ReadFrame without compression:", err)
|
|
||||||
}
|
|
||||||
parsedSynReplyFrame, ok := frame.(*SynReplyFrame)
|
|
||||||
if !ok {
|
|
||||||
t.Fatal("Parsed incorrect frame type:", frame)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(synReplyFrame, *parsedSynReplyFrame) {
|
|
||||||
t.Fatal("got: ", *parsedSynReplyFrame, "\nwant: ", synReplyFrame)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCreateParseSynReplyFrameCompressionEnable(t *testing.T) {
|
|
||||||
buffer := new(bytes.Buffer)
|
|
||||||
framer, err := NewFramer(buffer, buffer)
|
|
||||||
synReplyFrame := SynReplyFrame{
|
|
||||||
CFHeader: ControlFrameHeader{
|
|
||||||
version: Version,
|
|
||||||
frameType: TypeSynReply,
|
|
||||||
},
|
|
||||||
StreamId: 2,
|
|
||||||
Headers: HeadersFixture,
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("Failed to create new framer:", err)
|
|
||||||
}
|
|
||||||
if err := framer.WriteFrame(&synReplyFrame); err != nil {
|
|
||||||
t.Fatal("WriteFrame with compression:", err)
|
|
||||||
}
|
|
||||||
frame, err := framer.ReadFrame()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("ReadFrame with compression:", err)
|
|
||||||
}
|
|
||||||
parsedSynReplyFrame, ok := frame.(*SynReplyFrame)
|
|
||||||
if !ok {
|
|
||||||
t.Fatal("Parsed incorrect frame type:", frame)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(synReplyFrame, *parsedSynReplyFrame) {
|
|
||||||
t.Fatal("got: ", *parsedSynReplyFrame, "\nwant: ", synReplyFrame)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCreateParseRstStream(t *testing.T) {
|
|
||||||
buffer := new(bytes.Buffer)
|
|
||||||
framer, err := NewFramer(buffer, buffer)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("Failed to create new framer:", err)
|
|
||||||
}
|
|
||||||
rstStreamFrame := RstStreamFrame{
|
|
||||||
CFHeader: ControlFrameHeader{
|
|
||||||
version: Version,
|
|
||||||
frameType: TypeRstStream,
|
|
||||||
},
|
|
||||||
StreamId: 1,
|
|
||||||
Status: InvalidStream,
|
|
||||||
}
|
|
||||||
if err := framer.WriteFrame(&rstStreamFrame); err != nil {
|
|
||||||
t.Fatal("WriteFrame:", err)
|
|
||||||
}
|
|
||||||
frame, err := framer.ReadFrame()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("ReadFrame:", err)
|
|
||||||
}
|
|
||||||
parsedRstStreamFrame, ok := frame.(*RstStreamFrame)
|
|
||||||
if !ok {
|
|
||||||
t.Fatal("Parsed incorrect frame type:", frame)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(rstStreamFrame, *parsedRstStreamFrame) {
|
|
||||||
t.Fatal("got: ", *parsedRstStreamFrame, "\nwant: ", rstStreamFrame)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCreateParseSettings(t *testing.T) {
|
|
||||||
buffer := new(bytes.Buffer)
|
|
||||||
framer, err := NewFramer(buffer, buffer)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("Failed to create new framer:", err)
|
|
||||||
}
|
|
||||||
settingsFrame := SettingsFrame{
|
|
||||||
CFHeader: ControlFrameHeader{
|
|
||||||
version: Version,
|
|
||||||
frameType: TypeSettings,
|
|
||||||
},
|
|
||||||
FlagIdValues: []SettingsFlagIdValue{
|
|
||||||
{FlagSettingsPersistValue, SettingsCurrentCwnd, 10},
|
|
||||||
{FlagSettingsPersisted, SettingsUploadBandwidth, 1},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
if err := framer.WriteFrame(&settingsFrame); err != nil {
|
|
||||||
t.Fatal("WriteFrame:", err)
|
|
||||||
}
|
|
||||||
frame, err := framer.ReadFrame()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("ReadFrame:", err)
|
|
||||||
}
|
|
||||||
parsedSettingsFrame, ok := frame.(*SettingsFrame)
|
|
||||||
if !ok {
|
|
||||||
t.Fatal("Parsed incorrect frame type:", frame)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(settingsFrame, *parsedSettingsFrame) {
|
|
||||||
t.Fatal("got: ", *parsedSettingsFrame, "\nwant: ", settingsFrame)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCreateParsePing(t *testing.T) {
|
|
||||||
buffer := new(bytes.Buffer)
|
|
||||||
framer, err := NewFramer(buffer, buffer)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("Failed to create new framer:", err)
|
|
||||||
}
|
|
||||||
pingFrame := PingFrame{
|
|
||||||
CFHeader: ControlFrameHeader{
|
|
||||||
version: Version,
|
|
||||||
frameType: TypePing,
|
|
||||||
},
|
|
||||||
Id: 31337,
|
|
||||||
}
|
|
||||||
if err := framer.WriteFrame(&pingFrame); err != nil {
|
|
||||||
t.Fatal("WriteFrame:", err)
|
|
||||||
}
|
|
||||||
if pingFrame.CFHeader.Flags != 0 {
|
|
||||||
t.Fatal("Incorrect frame type:", pingFrame)
|
|
||||||
}
|
|
||||||
frame, err := framer.ReadFrame()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("ReadFrame:", err)
|
|
||||||
}
|
|
||||||
parsedPingFrame, ok := frame.(*PingFrame)
|
|
||||||
if !ok {
|
|
||||||
t.Fatal("Parsed incorrect frame type:", frame)
|
|
||||||
}
|
|
||||||
if parsedPingFrame.CFHeader.Flags != 0 {
|
|
||||||
t.Fatal("Parsed incorrect frame type:", parsedPingFrame)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(pingFrame, *parsedPingFrame) {
|
|
||||||
t.Fatal("got: ", *parsedPingFrame, "\nwant: ", pingFrame)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCreateParseGoAway(t *testing.T) {
|
|
||||||
buffer := new(bytes.Buffer)
|
|
||||||
framer, err := NewFramer(buffer, buffer)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("Failed to create new framer:", err)
|
|
||||||
}
|
|
||||||
goAwayFrame := GoAwayFrame{
|
|
||||||
CFHeader: ControlFrameHeader{
|
|
||||||
version: Version,
|
|
||||||
frameType: TypeGoAway,
|
|
||||||
},
|
|
||||||
LastGoodStreamId: 31337,
|
|
||||||
Status: 1,
|
|
||||||
}
|
|
||||||
if err := framer.WriteFrame(&goAwayFrame); err != nil {
|
|
||||||
t.Fatal("WriteFrame:", err)
|
|
||||||
}
|
|
||||||
if goAwayFrame.CFHeader.Flags != 0 {
|
|
||||||
t.Fatal("Incorrect frame type:", goAwayFrame)
|
|
||||||
}
|
|
||||||
if goAwayFrame.CFHeader.length != 8 {
|
|
||||||
t.Fatal("Incorrect frame type:", goAwayFrame)
|
|
||||||
}
|
|
||||||
frame, err := framer.ReadFrame()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("ReadFrame:", err)
|
|
||||||
}
|
|
||||||
parsedGoAwayFrame, ok := frame.(*GoAwayFrame)
|
|
||||||
if !ok {
|
|
||||||
t.Fatal("Parsed incorrect frame type:", frame)
|
|
||||||
}
|
|
||||||
if parsedGoAwayFrame.CFHeader.Flags != 0 {
|
|
||||||
t.Fatal("Incorrect frame type:", parsedGoAwayFrame)
|
|
||||||
}
|
|
||||||
if parsedGoAwayFrame.CFHeader.length != 8 {
|
|
||||||
t.Fatal("Incorrect frame type:", parsedGoAwayFrame)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(goAwayFrame, *parsedGoAwayFrame) {
|
|
||||||
t.Fatal("got: ", *parsedGoAwayFrame, "\nwant: ", goAwayFrame)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCreateParseHeadersFrame(t *testing.T) {
|
|
||||||
buffer := new(bytes.Buffer)
|
|
||||||
framer := &Framer{
|
|
||||||
headerCompressionDisabled: true,
|
|
||||||
w: buffer,
|
|
||||||
headerBuf: new(bytes.Buffer),
|
|
||||||
r: buffer,
|
|
||||||
}
|
|
||||||
headersFrame := HeadersFrame{
|
|
||||||
CFHeader: ControlFrameHeader{
|
|
||||||
version: Version,
|
|
||||||
frameType: TypeHeaders,
|
|
||||||
},
|
|
||||||
StreamId: 2,
|
|
||||||
}
|
|
||||||
headersFrame.Headers = HeadersFixture
|
|
||||||
if err := framer.WriteFrame(&headersFrame); err != nil {
|
|
||||||
t.Fatal("WriteFrame without compression:", err)
|
|
||||||
}
|
|
||||||
frame, err := framer.ReadFrame()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("ReadFrame without compression:", err)
|
|
||||||
}
|
|
||||||
parsedHeadersFrame, ok := frame.(*HeadersFrame)
|
|
||||||
if !ok {
|
|
||||||
t.Fatal("Parsed incorrect frame type:", frame)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(headersFrame, *parsedHeadersFrame) {
|
|
||||||
t.Fatal("got: ", *parsedHeadersFrame, "\nwant: ", headersFrame)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCreateParseHeadersFrameCompressionEnable(t *testing.T) {
|
|
||||||
buffer := new(bytes.Buffer)
|
|
||||||
headersFrame := HeadersFrame{
|
|
||||||
CFHeader: ControlFrameHeader{
|
|
||||||
version: Version,
|
|
||||||
frameType: TypeHeaders,
|
|
||||||
},
|
|
||||||
StreamId: 2,
|
|
||||||
}
|
|
||||||
headersFrame.Headers = HeadersFixture
|
|
||||||
|
|
||||||
framer, err := NewFramer(buffer, buffer)
|
|
||||||
if err := framer.WriteFrame(&headersFrame); err != nil {
|
|
||||||
t.Fatal("WriteFrame with compression:", err)
|
|
||||||
}
|
|
||||||
frame, err := framer.ReadFrame()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("ReadFrame with compression:", err)
|
|
||||||
}
|
|
||||||
parsedHeadersFrame, ok := frame.(*HeadersFrame)
|
|
||||||
if !ok {
|
|
||||||
t.Fatal("Parsed incorrect frame type:", frame)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(headersFrame, *parsedHeadersFrame) {
|
|
||||||
t.Fatal("got: ", *parsedHeadersFrame, "\nwant: ", headersFrame)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCreateParseWindowUpdateFrame(t *testing.T) {
|
|
||||||
buffer := new(bytes.Buffer)
|
|
||||||
framer, err := NewFramer(buffer, buffer)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("Failed to create new framer:", err)
|
|
||||||
}
|
|
||||||
windowUpdateFrame := WindowUpdateFrame{
|
|
||||||
CFHeader: ControlFrameHeader{
|
|
||||||
version: Version,
|
|
||||||
frameType: TypeWindowUpdate,
|
|
||||||
},
|
|
||||||
StreamId: 31337,
|
|
||||||
DeltaWindowSize: 1,
|
|
||||||
}
|
|
||||||
if err := framer.WriteFrame(&windowUpdateFrame); err != nil {
|
|
||||||
t.Fatal("WriteFrame:", err)
|
|
||||||
}
|
|
||||||
if windowUpdateFrame.CFHeader.Flags != 0 {
|
|
||||||
t.Fatal("Incorrect frame type:", windowUpdateFrame)
|
|
||||||
}
|
|
||||||
if windowUpdateFrame.CFHeader.length != 8 {
|
|
||||||
t.Fatal("Incorrect frame type:", windowUpdateFrame)
|
|
||||||
}
|
|
||||||
frame, err := framer.ReadFrame()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("ReadFrame:", err)
|
|
||||||
}
|
|
||||||
parsedWindowUpdateFrame, ok := frame.(*WindowUpdateFrame)
|
|
||||||
if !ok {
|
|
||||||
t.Fatal("Parsed incorrect frame type:", frame)
|
|
||||||
}
|
|
||||||
if parsedWindowUpdateFrame.CFHeader.Flags != 0 {
|
|
||||||
t.Fatal("Incorrect frame type:", parsedWindowUpdateFrame)
|
|
||||||
}
|
|
||||||
if parsedWindowUpdateFrame.CFHeader.length != 8 {
|
|
||||||
t.Fatal("Incorrect frame type:", parsedWindowUpdateFrame)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(windowUpdateFrame, *parsedWindowUpdateFrame) {
|
|
||||||
t.Fatal("got: ", *parsedWindowUpdateFrame, "\nwant: ", windowUpdateFrame)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCreateParseDataFrame(t *testing.T) {
|
|
||||||
buffer := new(bytes.Buffer)
|
|
||||||
framer, err := NewFramer(buffer, buffer)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("Failed to create new framer:", err)
|
|
||||||
}
|
|
||||||
dataFrame := DataFrame{
|
|
||||||
StreamId: 1,
|
|
||||||
Data: []byte{'h', 'e', 'l', 'l', 'o'},
|
|
||||||
}
|
|
||||||
if err := framer.WriteFrame(&dataFrame); err != nil {
|
|
||||||
t.Fatal("WriteFrame:", err)
|
|
||||||
}
|
|
||||||
frame, err := framer.ReadFrame()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("ReadFrame:", err)
|
|
||||||
}
|
|
||||||
parsedDataFrame, ok := frame.(*DataFrame)
|
|
||||||
if !ok {
|
|
||||||
t.Fatal("Parsed incorrect frame type:", frame)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(dataFrame, *parsedDataFrame) {
|
|
||||||
t.Fatal("got: ", *parsedDataFrame, "\nwant: ", dataFrame)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCompressionContextAcrossFrames(t *testing.T) {
|
|
||||||
buffer := new(bytes.Buffer)
|
|
||||||
framer, err := NewFramer(buffer, buffer)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("Failed to create new framer:", err)
|
|
||||||
}
|
|
||||||
headersFrame := HeadersFrame{
|
|
||||||
CFHeader: ControlFrameHeader{
|
|
||||||
version: Version,
|
|
||||||
frameType: TypeHeaders,
|
|
||||||
},
|
|
||||||
StreamId: 2,
|
|
||||||
Headers: HeadersFixture,
|
|
||||||
}
|
|
||||||
if err := framer.WriteFrame(&headersFrame); err != nil {
|
|
||||||
t.Fatal("WriteFrame (HEADERS):", err)
|
|
||||||
}
|
|
||||||
synStreamFrame := SynStreamFrame{
|
|
||||||
ControlFrameHeader{
|
|
||||||
Version,
|
|
||||||
TypeSynStream,
|
|
||||||
0, // Flags
|
|
||||||
0, // length
|
|
||||||
},
|
|
||||||
2, // StreamId
|
|
||||||
0, // AssociatedTOStreamID
|
|
||||||
0, // Priority
|
|
||||||
1, // Slot
|
|
||||||
nil, // Headers
|
|
||||||
}
|
|
||||||
synStreamFrame.Headers = HeadersFixture
|
|
||||||
|
|
||||||
if err := framer.WriteFrame(&synStreamFrame); err != nil {
|
|
||||||
t.Fatal("WriteFrame (SYN_STREAM):", err)
|
|
||||||
}
|
|
||||||
frame, err := framer.ReadFrame()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("ReadFrame (HEADERS):", err, buffer.Bytes())
|
|
||||||
}
|
|
||||||
parsedHeadersFrame, ok := frame.(*HeadersFrame)
|
|
||||||
if !ok {
|
|
||||||
t.Fatalf("expected HeadersFrame; got %T %v", frame, frame)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(headersFrame, *parsedHeadersFrame) {
|
|
||||||
t.Fatal("got: ", *parsedHeadersFrame, "\nwant: ", headersFrame)
|
|
||||||
}
|
|
||||||
frame, err = framer.ReadFrame()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("ReadFrame (SYN_STREAM):", err, buffer.Bytes())
|
|
||||||
}
|
|
||||||
parsedSynStreamFrame, ok := frame.(*SynStreamFrame)
|
|
||||||
if !ok {
|
|
||||||
t.Fatalf("expected SynStreamFrame; got %T %v", frame, frame)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(synStreamFrame, *parsedSynStreamFrame) {
|
|
||||||
t.Fatal("got: ", *parsedSynStreamFrame, "\nwant: ", synStreamFrame)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMultipleSPDYFrames(t *testing.T) {
|
|
||||||
// Initialize the framers.
|
|
||||||
pr1, pw1 := io.Pipe()
|
|
||||||
pr2, pw2 := io.Pipe()
|
|
||||||
writer, err := NewFramer(pw1, pr2)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("Failed to create writer:", err)
|
|
||||||
}
|
|
||||||
reader, err := NewFramer(pw2, pr1)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("Failed to create reader:", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up the frames we're actually transferring.
|
|
||||||
headersFrame := HeadersFrame{
|
|
||||||
CFHeader: ControlFrameHeader{
|
|
||||||
version: Version,
|
|
||||||
frameType: TypeHeaders,
|
|
||||||
},
|
|
||||||
StreamId: 2,
|
|
||||||
Headers: HeadersFixture,
|
|
||||||
}
|
|
||||||
synStreamFrame := SynStreamFrame{
|
|
||||||
CFHeader: ControlFrameHeader{
|
|
||||||
version: Version,
|
|
||||||
frameType: TypeSynStream,
|
|
||||||
},
|
|
||||||
StreamId: 2,
|
|
||||||
Headers: HeadersFixture,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start the goroutines to write the frames.
|
|
||||||
go func() {
|
|
||||||
if err := writer.WriteFrame(&headersFrame); err != nil {
|
|
||||||
t.Fatal("WriteFrame (HEADERS): ", err)
|
|
||||||
}
|
|
||||||
if err := writer.WriteFrame(&synStreamFrame); err != nil {
|
|
||||||
t.Fatal("WriteFrame (SYN_STREAM): ", err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
// Read the frames and verify they look as expected.
|
|
||||||
frame, err := reader.ReadFrame()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("ReadFrame (HEADERS): ", err)
|
|
||||||
}
|
|
||||||
parsedHeadersFrame, ok := frame.(*HeadersFrame)
|
|
||||||
if !ok {
|
|
||||||
t.Fatal("Parsed incorrect frame type:", frame)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(headersFrame, *parsedHeadersFrame) {
|
|
||||||
t.Fatal("got: ", *parsedHeadersFrame, "\nwant: ", headersFrame)
|
|
||||||
}
|
|
||||||
frame, err = reader.ReadFrame()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("ReadFrame (SYN_STREAM):", err)
|
|
||||||
}
|
|
||||||
parsedSynStreamFrame, ok := frame.(*SynStreamFrame)
|
|
||||||
if !ok {
|
|
||||||
t.Fatal("Parsed incorrect frame type.")
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(synStreamFrame, *parsedSynStreamFrame) {
|
|
||||||
t.Fatal("got: ", *parsedSynStreamFrame, "\nwant: ", synStreamFrame)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestReadMalformedZlibHeader(t *testing.T) {
|
|
||||||
// These were constructed by corrupting the first byte of the zlib
|
|
||||||
// header after writing.
|
|
||||||
malformedStructs := map[string]string{
|
|
||||||
"SynStreamFrame": "gAIAAQAAABgAAAACAAAAAAAAF/nfolGyYmAAAAAA//8=",
|
|
||||||
"SynReplyFrame": "gAIAAgAAABQAAAACAAAX+d+iUbJiYAAAAAD//w==",
|
|
||||||
"HeadersFrame": "gAIACAAAABQAAAACAAAX+d+iUbJiYAAAAAD//w==",
|
|
||||||
}
|
|
||||||
for name, bad := range malformedStructs {
|
|
||||||
b, err := base64.StdEncoding.DecodeString(bad)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("Unable to decode base64 encoded frame %s: %v", name, err)
|
|
||||||
}
|
|
||||||
buf := bytes.NewBuffer(b)
|
|
||||||
reader, err := NewFramer(buf, buf)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("NewFramer: %v", err)
|
|
||||||
}
|
|
||||||
_, err = reader.ReadFrame()
|
|
||||||
if err != zlib.ErrHeader {
|
|
||||||
t.Errorf("Frame %s, expected: %#v, actual: %#v", name, zlib.ErrHeader, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: these tests are too weak for updating SPDY spec. Fix me.
|
|
||||||
|
|
||||||
type zeroStream struct {
|
|
||||||
frame Frame
|
|
||||||
encoded string
|
|
||||||
}
|
|
||||||
|
|
||||||
var streamIdZeroFrames = map[string]zeroStream{
|
|
||||||
"SynStreamFrame": {
|
|
||||||
&SynStreamFrame{StreamId: 0},
|
|
||||||
"gAIAAQAAABgAAAAAAAAAAAAAePnfolGyYmAAAAAA//8=",
|
|
||||||
},
|
|
||||||
"SynReplyFrame": {
|
|
||||||
&SynReplyFrame{StreamId: 0},
|
|
||||||
"gAIAAgAAABQAAAAAAAB4+d+iUbJiYAAAAAD//w==",
|
|
||||||
},
|
|
||||||
"RstStreamFrame": {
|
|
||||||
&RstStreamFrame{StreamId: 0},
|
|
||||||
"gAIAAwAAAAgAAAAAAAAAAA==",
|
|
||||||
},
|
|
||||||
"HeadersFrame": {
|
|
||||||
&HeadersFrame{StreamId: 0},
|
|
||||||
"gAIACAAAABQAAAAAAAB4+d+iUbJiYAAAAAD//w==",
|
|
||||||
},
|
|
||||||
"DataFrame": {
|
|
||||||
&DataFrame{StreamId: 0},
|
|
||||||
"AAAAAAAAAAA=",
|
|
||||||
},
|
|
||||||
"PingFrame": {
|
|
||||||
&PingFrame{Id: 0},
|
|
||||||
"gAIABgAAAAQAAAAA",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNoZeroStreamId(t *testing.T) {
|
|
||||||
t.Log("skipping") // TODO: update to work with SPDY3
|
|
||||||
return
|
|
||||||
|
|
||||||
for name, f := range streamIdZeroFrames {
|
|
||||||
b, err := base64.StdEncoding.DecodeString(f.encoded)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("Unable to decode base64 encoded frame %s: %v", f, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
framer, err := NewFramer(ioutil.Discard, bytes.NewReader(b))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("NewFramer: %v", err)
|
|
||||||
}
|
|
||||||
err = framer.WriteFrame(f.frame)
|
|
||||||
checkZeroStreamId(t, name, "WriteFrame", err)
|
|
||||||
|
|
||||||
_, err = framer.ReadFrame()
|
|
||||||
checkZeroStreamId(t, name, "ReadFrame", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkZeroStreamId(t *testing.T, frame string, method string, err error) {
|
|
||||||
if err == nil {
|
|
||||||
t.Errorf("%s ZeroStreamId, no error on %s", method, frame)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
eerr, ok := err.(*Error)
|
|
||||||
if !ok || eerr.Err != ZeroStreamId {
|
|
||||||
t.Errorf("%s ZeroStreamId, incorrect error %#v, frame %s", method, eerr, frame)
|
|
||||||
}
|
|
||||||
}
|
|
275
Godeps/_workspace/src/golang.org/x/net/spdy/types.go
generated
vendored
275
Godeps/_workspace/src/golang.org/x/net/spdy/types.go
generated
vendored
@ -1,275 +0,0 @@
|
|||||||
// Copyright 2011 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// Package spdy implements the SPDY protocol (currently SPDY/3), described in
|
|
||||||
// http://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3.
|
|
||||||
package spdy // import "golang.org/x/net/spdy"
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"compress/zlib"
|
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Version is the protocol version number that this package implements.
|
|
||||||
const Version = 3
|
|
||||||
|
|
||||||
// ControlFrameType stores the type field in a control frame header.
|
|
||||||
type ControlFrameType uint16
|
|
||||||
|
|
||||||
const (
|
|
||||||
TypeSynStream ControlFrameType = 0x0001
|
|
||||||
TypeSynReply = 0x0002
|
|
||||||
TypeRstStream = 0x0003
|
|
||||||
TypeSettings = 0x0004
|
|
||||||
TypePing = 0x0006
|
|
||||||
TypeGoAway = 0x0007
|
|
||||||
TypeHeaders = 0x0008
|
|
||||||
TypeWindowUpdate = 0x0009
|
|
||||||
)
|
|
||||||
|
|
||||||
// ControlFlags are the flags that can be set on a control frame.
|
|
||||||
type ControlFlags uint8
|
|
||||||
|
|
||||||
const (
|
|
||||||
ControlFlagFin ControlFlags = 0x01
|
|
||||||
ControlFlagUnidirectional = 0x02
|
|
||||||
ControlFlagSettingsClearSettings = 0x01
|
|
||||||
)
|
|
||||||
|
|
||||||
// DataFlags are the flags that can be set on a data frame.
|
|
||||||
type DataFlags uint8
|
|
||||||
|
|
||||||
const (
|
|
||||||
DataFlagFin DataFlags = 0x01
|
|
||||||
)
|
|
||||||
|
|
||||||
// MaxDataLength is the maximum number of bytes that can be stored in one frame.
|
|
||||||
const MaxDataLength = 1<<24 - 1
|
|
||||||
|
|
||||||
// headerValueSepator separates multiple header values.
|
|
||||||
const headerValueSeparator = "\x00"
|
|
||||||
|
|
||||||
// Frame is a single SPDY frame in its unpacked in-memory representation. Use
|
|
||||||
// Framer to read and write it.
|
|
||||||
type Frame interface {
|
|
||||||
write(f *Framer) error
|
|
||||||
}
|
|
||||||
|
|
||||||
// ControlFrameHeader contains all the fields in a control frame header,
|
|
||||||
// in its unpacked in-memory representation.
|
|
||||||
type ControlFrameHeader struct {
|
|
||||||
// Note, high bit is the "Control" bit.
|
|
||||||
version uint16 // spdy version number
|
|
||||||
frameType ControlFrameType
|
|
||||||
Flags ControlFlags
|
|
||||||
length uint32 // length of data field
|
|
||||||
}
|
|
||||||
|
|
||||||
type controlFrame interface {
|
|
||||||
Frame
|
|
||||||
read(h ControlFrameHeader, f *Framer) error
|
|
||||||
}
|
|
||||||
|
|
||||||
// StreamId represents a 31-bit value identifying the stream.
|
|
||||||
type StreamId uint32
|
|
||||||
|
|
||||||
// SynStreamFrame is the unpacked, in-memory representation of a SYN_STREAM
|
|
||||||
// frame.
|
|
||||||
type SynStreamFrame struct {
|
|
||||||
CFHeader ControlFrameHeader
|
|
||||||
StreamId StreamId
|
|
||||||
AssociatedToStreamId StreamId // stream id for a stream which this stream is associated to
|
|
||||||
Priority uint8 // priority of this frame (3-bit)
|
|
||||||
Slot uint8 // index in the server's credential vector of the client certificate
|
|
||||||
Headers http.Header
|
|
||||||
}
|
|
||||||
|
|
||||||
// SynReplyFrame is the unpacked, in-memory representation of a SYN_REPLY frame.
|
|
||||||
type SynReplyFrame struct {
|
|
||||||
CFHeader ControlFrameHeader
|
|
||||||
StreamId StreamId
|
|
||||||
Headers http.Header
|
|
||||||
}
|
|
||||||
|
|
||||||
// RstStreamStatus represents the status that led to a RST_STREAM.
|
|
||||||
type RstStreamStatus uint32
|
|
||||||
|
|
||||||
const (
|
|
||||||
ProtocolError RstStreamStatus = iota + 1
|
|
||||||
InvalidStream
|
|
||||||
RefusedStream
|
|
||||||
UnsupportedVersion
|
|
||||||
Cancel
|
|
||||||
InternalError
|
|
||||||
FlowControlError
|
|
||||||
StreamInUse
|
|
||||||
StreamAlreadyClosed
|
|
||||||
InvalidCredentials
|
|
||||||
FrameTooLarge
|
|
||||||
)
|
|
||||||
|
|
||||||
// RstStreamFrame is the unpacked, in-memory representation of a RST_STREAM
|
|
||||||
// frame.
|
|
||||||
type RstStreamFrame struct {
|
|
||||||
CFHeader ControlFrameHeader
|
|
||||||
StreamId StreamId
|
|
||||||
Status RstStreamStatus
|
|
||||||
}
|
|
||||||
|
|
||||||
// SettingsFlag represents a flag in a SETTINGS frame.
|
|
||||||
type SettingsFlag uint8
|
|
||||||
|
|
||||||
const (
|
|
||||||
FlagSettingsPersistValue SettingsFlag = 0x1
|
|
||||||
FlagSettingsPersisted = 0x2
|
|
||||||
)
|
|
||||||
|
|
||||||
// SettingsFlag represents the id of an id/value pair in a SETTINGS frame.
|
|
||||||
type SettingsId uint32
|
|
||||||
|
|
||||||
const (
|
|
||||||
SettingsUploadBandwidth SettingsId = iota + 1
|
|
||||||
SettingsDownloadBandwidth
|
|
||||||
SettingsRoundTripTime
|
|
||||||
SettingsMaxConcurrentStreams
|
|
||||||
SettingsCurrentCwnd
|
|
||||||
SettingsDownloadRetransRate
|
|
||||||
SettingsInitialWindowSize
|
|
||||||
SettingsClientCretificateVectorSize
|
|
||||||
)
|
|
||||||
|
|
||||||
// SettingsFlagIdValue is the unpacked, in-memory representation of the
|
|
||||||
// combined flag/id/value for a setting in a SETTINGS frame.
|
|
||||||
type SettingsFlagIdValue struct {
|
|
||||||
Flag SettingsFlag
|
|
||||||
Id SettingsId
|
|
||||||
Value uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
// SettingsFrame is the unpacked, in-memory representation of a SPDY
|
|
||||||
// SETTINGS frame.
|
|
||||||
type SettingsFrame struct {
|
|
||||||
CFHeader ControlFrameHeader
|
|
||||||
FlagIdValues []SettingsFlagIdValue
|
|
||||||
}
|
|
||||||
|
|
||||||
// PingFrame is the unpacked, in-memory representation of a PING frame.
|
|
||||||
type PingFrame struct {
|
|
||||||
CFHeader ControlFrameHeader
|
|
||||||
Id uint32 // unique id for this ping, from server is even, from client is odd.
|
|
||||||
}
|
|
||||||
|
|
||||||
// GoAwayStatus represents the status in a GoAwayFrame.
|
|
||||||
type GoAwayStatus uint32
|
|
||||||
|
|
||||||
const (
|
|
||||||
GoAwayOK GoAwayStatus = iota
|
|
||||||
GoAwayProtocolError
|
|
||||||
GoAwayInternalError
|
|
||||||
)
|
|
||||||
|
|
||||||
// GoAwayFrame is the unpacked, in-memory representation of a GOAWAY frame.
|
|
||||||
type GoAwayFrame struct {
|
|
||||||
CFHeader ControlFrameHeader
|
|
||||||
LastGoodStreamId StreamId // last stream id which was accepted by sender
|
|
||||||
Status GoAwayStatus
|
|
||||||
}
|
|
||||||
|
|
||||||
// HeadersFrame is the unpacked, in-memory representation of a HEADERS frame.
|
|
||||||
type HeadersFrame struct {
|
|
||||||
CFHeader ControlFrameHeader
|
|
||||||
StreamId StreamId
|
|
||||||
Headers http.Header
|
|
||||||
}
|
|
||||||
|
|
||||||
// WindowUpdateFrame is the unpacked, in-memory representation of a
|
|
||||||
// WINDOW_UPDATE frame.
|
|
||||||
type WindowUpdateFrame struct {
|
|
||||||
CFHeader ControlFrameHeader
|
|
||||||
StreamId StreamId
|
|
||||||
DeltaWindowSize uint32 // additional number of bytes to existing window size
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Implement credential frame and related methods.
|
|
||||||
|
|
||||||
// DataFrame is the unpacked, in-memory representation of a DATA frame.
|
|
||||||
type DataFrame struct {
|
|
||||||
// Note, high bit is the "Control" bit. Should be 0 for data frames.
|
|
||||||
StreamId StreamId
|
|
||||||
Flags DataFlags
|
|
||||||
Data []byte // payload data of this frame
|
|
||||||
}
|
|
||||||
|
|
||||||
// A SPDY specific error.
|
|
||||||
type ErrorCode string
|
|
||||||
|
|
||||||
const (
|
|
||||||
UnlowercasedHeaderName ErrorCode = "header was not lowercased"
|
|
||||||
DuplicateHeaders = "multiple headers with same name"
|
|
||||||
WrongCompressedPayloadSize = "compressed payload size was incorrect"
|
|
||||||
UnknownFrameType = "unknown frame type"
|
|
||||||
InvalidControlFrame = "invalid control frame"
|
|
||||||
InvalidDataFrame = "invalid data frame"
|
|
||||||
InvalidHeaderPresent = "frame contained invalid header"
|
|
||||||
ZeroStreamId = "stream id zero is disallowed"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Error contains both the type of error and additional values. StreamId is 0
|
|
||||||
// if Error is not associated with a stream.
|
|
||||||
type Error struct {
|
|
||||||
Err ErrorCode
|
|
||||||
StreamId StreamId
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Error) Error() string {
|
|
||||||
return string(e.Err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var invalidReqHeaders = map[string]bool{
|
|
||||||
"Connection": true,
|
|
||||||
"Host": true,
|
|
||||||
"Keep-Alive": true,
|
|
||||||
"Proxy-Connection": true,
|
|
||||||
"Transfer-Encoding": true,
|
|
||||||
}
|
|
||||||
|
|
||||||
var invalidRespHeaders = map[string]bool{
|
|
||||||
"Connection": true,
|
|
||||||
"Keep-Alive": true,
|
|
||||||
"Proxy-Connection": true,
|
|
||||||
"Transfer-Encoding": true,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Framer handles serializing/deserializing SPDY frames, including compressing/
|
|
||||||
// decompressing payloads.
|
|
||||||
type Framer struct {
|
|
||||||
headerCompressionDisabled bool
|
|
||||||
w io.Writer
|
|
||||||
headerBuf *bytes.Buffer
|
|
||||||
headerCompressor *zlib.Writer
|
|
||||||
r io.Reader
|
|
||||||
headerReader io.LimitedReader
|
|
||||||
headerDecompressor io.ReadCloser
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewFramer allocates a new Framer for a given SPDY connection, represented by
|
|
||||||
// a io.Writer and io.Reader. Note that Framer will read and write individual fields
|
|
||||||
// from/to the Reader and Writer, so the caller should pass in an appropriately
|
|
||||||
// buffered implementation to optimize performance.
|
|
||||||
func NewFramer(w io.Writer, r io.Reader) (*Framer, error) {
|
|
||||||
compressBuf := new(bytes.Buffer)
|
|
||||||
compressor, err := zlib.NewWriterLevelDict(compressBuf, zlib.BestCompression, []byte(headerDictionary))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
framer := &Framer{
|
|
||||||
w: w,
|
|
||||||
headerBuf: compressBuf,
|
|
||||||
headerCompressor: compressor,
|
|
||||||
r: r,
|
|
||||||
}
|
|
||||||
return framer, nil
|
|
||||||
}
|
|
318
Godeps/_workspace/src/golang.org/x/net/spdy/write.go
generated
vendored
318
Godeps/_workspace/src/golang.org/x/net/spdy/write.go
generated
vendored
@ -1,318 +0,0 @@
|
|||||||
// Copyright 2011 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package spdy
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/binary"
|
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (frame *SynStreamFrame) write(f *Framer) error {
|
|
||||||
return f.writeSynStreamFrame(frame)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (frame *SynReplyFrame) write(f *Framer) error {
|
|
||||||
return f.writeSynReplyFrame(frame)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (frame *RstStreamFrame) write(f *Framer) (err error) {
|
|
||||||
if frame.StreamId == 0 {
|
|
||||||
return &Error{ZeroStreamId, 0}
|
|
||||||
}
|
|
||||||
frame.CFHeader.version = Version
|
|
||||||
frame.CFHeader.frameType = TypeRstStream
|
|
||||||
frame.CFHeader.Flags = 0
|
|
||||||
frame.CFHeader.length = 8
|
|
||||||
|
|
||||||
// Serialize frame to Writer.
|
|
||||||
if err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err = binary.Write(f.w, binary.BigEndian, frame.StreamId); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if frame.Status == 0 {
|
|
||||||
return &Error{InvalidControlFrame, frame.StreamId}
|
|
||||||
}
|
|
||||||
if err = binary.Write(f.w, binary.BigEndian, frame.Status); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (frame *SettingsFrame) write(f *Framer) (err error) {
|
|
||||||
frame.CFHeader.version = Version
|
|
||||||
frame.CFHeader.frameType = TypeSettings
|
|
||||||
frame.CFHeader.length = uint32(len(frame.FlagIdValues)*8 + 4)
|
|
||||||
|
|
||||||
// Serialize frame to Writer.
|
|
||||||
if err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err = binary.Write(f.w, binary.BigEndian, uint32(len(frame.FlagIdValues))); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for _, flagIdValue := range frame.FlagIdValues {
|
|
||||||
flagId := uint32(flagIdValue.Flag)<<24 | uint32(flagIdValue.Id)
|
|
||||||
if err = binary.Write(f.w, binary.BigEndian, flagId); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err = binary.Write(f.w, binary.BigEndian, flagIdValue.Value); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (frame *PingFrame) write(f *Framer) (err error) {
|
|
||||||
if frame.Id == 0 {
|
|
||||||
return &Error{ZeroStreamId, 0}
|
|
||||||
}
|
|
||||||
frame.CFHeader.version = Version
|
|
||||||
frame.CFHeader.frameType = TypePing
|
|
||||||
frame.CFHeader.Flags = 0
|
|
||||||
frame.CFHeader.length = 4
|
|
||||||
|
|
||||||
// Serialize frame to Writer.
|
|
||||||
if err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err = binary.Write(f.w, binary.BigEndian, frame.Id); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (frame *GoAwayFrame) write(f *Framer) (err error) {
|
|
||||||
frame.CFHeader.version = Version
|
|
||||||
frame.CFHeader.frameType = TypeGoAway
|
|
||||||
frame.CFHeader.Flags = 0
|
|
||||||
frame.CFHeader.length = 8
|
|
||||||
|
|
||||||
// Serialize frame to Writer.
|
|
||||||
if err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err = binary.Write(f.w, binary.BigEndian, frame.LastGoodStreamId); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err = binary.Write(f.w, binary.BigEndian, frame.Status); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (frame *HeadersFrame) write(f *Framer) error {
|
|
||||||
return f.writeHeadersFrame(frame)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (frame *WindowUpdateFrame) write(f *Framer) (err error) {
|
|
||||||
frame.CFHeader.version = Version
|
|
||||||
frame.CFHeader.frameType = TypeWindowUpdate
|
|
||||||
frame.CFHeader.Flags = 0
|
|
||||||
frame.CFHeader.length = 8
|
|
||||||
|
|
||||||
// Serialize frame to Writer.
|
|
||||||
if err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err = binary.Write(f.w, binary.BigEndian, frame.StreamId); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err = binary.Write(f.w, binary.BigEndian, frame.DeltaWindowSize); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (frame *DataFrame) write(f *Framer) error {
|
|
||||||
return f.writeDataFrame(frame)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteFrame writes a frame.
|
|
||||||
func (f *Framer) WriteFrame(frame Frame) error {
|
|
||||||
return frame.write(f)
|
|
||||||
}
|
|
||||||
|
|
||||||
func writeControlFrameHeader(w io.Writer, h ControlFrameHeader) error {
|
|
||||||
if err := binary.Write(w, binary.BigEndian, 0x8000|h.version); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := binary.Write(w, binary.BigEndian, h.frameType); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
flagsAndLength := uint32(h.Flags)<<24 | h.length
|
|
||||||
if err := binary.Write(w, binary.BigEndian, flagsAndLength); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func writeHeaderValueBlock(w io.Writer, h http.Header) (n int, err error) {
|
|
||||||
n = 0
|
|
||||||
if err = binary.Write(w, binary.BigEndian, uint32(len(h))); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
n += 2
|
|
||||||
for name, values := range h {
|
|
||||||
if err = binary.Write(w, binary.BigEndian, uint32(len(name))); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
n += 2
|
|
||||||
name = strings.ToLower(name)
|
|
||||||
if _, err = io.WriteString(w, name); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
n += len(name)
|
|
||||||
v := strings.Join(values, headerValueSeparator)
|
|
||||||
if err = binary.Write(w, binary.BigEndian, uint32(len(v))); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
n += 2
|
|
||||||
if _, err = io.WriteString(w, v); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
n += len(v)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *Framer) writeSynStreamFrame(frame *SynStreamFrame) (err error) {
|
|
||||||
if frame.StreamId == 0 {
|
|
||||||
return &Error{ZeroStreamId, 0}
|
|
||||||
}
|
|
||||||
// Marshal the headers.
|
|
||||||
var writer io.Writer = f.headerBuf
|
|
||||||
if !f.headerCompressionDisabled {
|
|
||||||
writer = f.headerCompressor
|
|
||||||
}
|
|
||||||
if _, err = writeHeaderValueBlock(writer, frame.Headers); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !f.headerCompressionDisabled {
|
|
||||||
f.headerCompressor.Flush()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set ControlFrameHeader.
|
|
||||||
frame.CFHeader.version = Version
|
|
||||||
frame.CFHeader.frameType = TypeSynStream
|
|
||||||
frame.CFHeader.length = uint32(len(f.headerBuf.Bytes()) + 10)
|
|
||||||
|
|
||||||
// Serialize frame to Writer.
|
|
||||||
if err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err = binary.Write(f.w, binary.BigEndian, frame.StreamId); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err = binary.Write(f.w, binary.BigEndian, frame.AssociatedToStreamId); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err = binary.Write(f.w, binary.BigEndian, frame.Priority<<5); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err = binary.Write(f.w, binary.BigEndian, frame.Slot); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if _, err = f.w.Write(f.headerBuf.Bytes()); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
f.headerBuf.Reset()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *Framer) writeSynReplyFrame(frame *SynReplyFrame) (err error) {
|
|
||||||
if frame.StreamId == 0 {
|
|
||||||
return &Error{ZeroStreamId, 0}
|
|
||||||
}
|
|
||||||
// Marshal the headers.
|
|
||||||
var writer io.Writer = f.headerBuf
|
|
||||||
if !f.headerCompressionDisabled {
|
|
||||||
writer = f.headerCompressor
|
|
||||||
}
|
|
||||||
if _, err = writeHeaderValueBlock(writer, frame.Headers); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !f.headerCompressionDisabled {
|
|
||||||
f.headerCompressor.Flush()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set ControlFrameHeader.
|
|
||||||
frame.CFHeader.version = Version
|
|
||||||
frame.CFHeader.frameType = TypeSynReply
|
|
||||||
frame.CFHeader.length = uint32(len(f.headerBuf.Bytes()) + 4)
|
|
||||||
|
|
||||||
// Serialize frame to Writer.
|
|
||||||
if err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err = binary.Write(f.w, binary.BigEndian, frame.StreamId); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if _, err = f.w.Write(f.headerBuf.Bytes()); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
f.headerBuf.Reset()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *Framer) writeHeadersFrame(frame *HeadersFrame) (err error) {
|
|
||||||
if frame.StreamId == 0 {
|
|
||||||
return &Error{ZeroStreamId, 0}
|
|
||||||
}
|
|
||||||
// Marshal the headers.
|
|
||||||
var writer io.Writer = f.headerBuf
|
|
||||||
if !f.headerCompressionDisabled {
|
|
||||||
writer = f.headerCompressor
|
|
||||||
}
|
|
||||||
if _, err = writeHeaderValueBlock(writer, frame.Headers); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !f.headerCompressionDisabled {
|
|
||||||
f.headerCompressor.Flush()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set ControlFrameHeader.
|
|
||||||
frame.CFHeader.version = Version
|
|
||||||
frame.CFHeader.frameType = TypeHeaders
|
|
||||||
frame.CFHeader.length = uint32(len(f.headerBuf.Bytes()) + 4)
|
|
||||||
|
|
||||||
// Serialize frame to Writer.
|
|
||||||
if err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err = binary.Write(f.w, binary.BigEndian, frame.StreamId); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if _, err = f.w.Write(f.headerBuf.Bytes()); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
f.headerBuf.Reset()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *Framer) writeDataFrame(frame *DataFrame) (err error) {
|
|
||||||
if frame.StreamId == 0 {
|
|
||||||
return &Error{ZeroStreamId, 0}
|
|
||||||
}
|
|
||||||
if frame.StreamId&0x80000000 != 0 || len(frame.Data) > MaxDataLength {
|
|
||||||
return &Error{InvalidDataFrame, frame.StreamId}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Serialize frame to Writer.
|
|
||||||
if err = binary.Write(f.w, binary.BigEndian, frame.StreamId); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
flagsAndLength := uint32(frame.Flags)<<24 | uint32(len(frame.Data))
|
|
||||||
if err = binary.Write(f.w, binary.BigEndian, flagsAndLength); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if _, err = f.w.Write(frame.Data); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user