| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334 |
- // Copyright 2014 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 http2
- import (
- "bytes"
- "reflect"
- "testing"
- )
- func testFramer() (*Framer, *bytes.Buffer) {
- buf := new(bytes.Buffer)
- return NewFramer(buf, buf), buf
- }
- func TestWriteRST(t *testing.T) {
- fr, buf := testFramer()
- var streamID uint32 = 1<<24 + 2<<16 + 3<<8 + 4
- var errCode uint32 = 7<<24 + 6<<16 + 5<<8 + 4
- fr.WriteRSTStream(streamID, errCode)
- const wantEnc = "\x00\x00\x04\x03\x00\x01\x02\x03\x04\x07\x06\x05\x04"
- if buf.String() != wantEnc {
- t.Errorf("encoded as %q; want %q", buf.Bytes(), wantEnc)
- }
- f, err := fr.ReadFrame()
- if err != nil {
- t.Fatal(err)
- }
- want := &RSTStreamFrame{
- FrameHeader: FrameHeader{
- valid: true,
- Type: 0x3,
- Flags: 0x0,
- Length: 0x4,
- StreamID: 0x1020304,
- },
- ErrCode: 0x7060504,
- }
- if !reflect.DeepEqual(f, want) {
- t.Errorf("parsed back %#v; want %#v", f, want)
- }
- }
- func TestWriteData(t *testing.T) {
- fr, buf := testFramer()
- var streamID uint32 = 1<<24 + 2<<16 + 3<<8 + 4
- data := []byte("ABC")
- fr.WriteData(streamID, true, data)
- const wantEnc = "\x00\x00\x03\x00\x01\x01\x02\x03\x04ABC"
- if buf.String() != wantEnc {
- t.Errorf("encoded as %q; want %q", buf.Bytes(), wantEnc)
- }
- f, err := fr.ReadFrame()
- if err != nil {
- t.Fatal(err)
- }
- df, ok := f.(*DataFrame)
- if !ok {
- t.Fatalf("got %T; want *DataFrame", f)
- }
- if !bytes.Equal(df.Data(), data) {
- t.Errorf("got %q; want %q", df.Data, data)
- }
- if f.Header().Flags&1 == 0 {
- t.Errorf("didn't see END_STREAM flag")
- }
- }
- func TestWriteHeaders(t *testing.T) {
- tests := []struct {
- name string
- p HeadersFrameParam
- wantEnc string
- wantFrame *HeadersFrame
- }{
- {
- "basic",
- HeadersFrameParam{
- StreamID: 42,
- BlockFragment: []byte("abc"),
- Priority: PriorityParam{},
- },
- "\x00\x00\x03\x01\x00\x00\x00\x00*abc",
- &HeadersFrame{
- FrameHeader: FrameHeader{
- valid: true,
- StreamID: 42,
- Type: FrameHeaders,
- Length: uint32(len("abc")),
- },
- Priority: PriorityParam{},
- headerFragBuf: []byte("abc"),
- },
- },
- {
- "basic + end flags",
- HeadersFrameParam{
- StreamID: 42,
- BlockFragment: []byte("abc"),
- EndStream: true,
- EndHeaders: true,
- Priority: PriorityParam{},
- },
- "\x00\x00\x03\x01\x05\x00\x00\x00*abc",
- &HeadersFrame{
- FrameHeader: FrameHeader{
- valid: true,
- StreamID: 42,
- Type: FrameHeaders,
- Flags: FlagHeadersEndStream | FlagHeadersEndHeaders,
- Length: uint32(len("abc")),
- },
- Priority: PriorityParam{},
- headerFragBuf: []byte("abc"),
- },
- },
- {
- "with padding",
- HeadersFrameParam{
- StreamID: 42,
- BlockFragment: []byte("abc"),
- EndStream: true,
- EndHeaders: true,
- PadLength: 5,
- Priority: PriorityParam{},
- },
- "\x00\x00\t\x01\r\x00\x00\x00*\x05abc\x00\x00\x00\x00\x00",
- &HeadersFrame{
- FrameHeader: FrameHeader{
- valid: true,
- StreamID: 42,
- Type: FrameHeaders,
- Flags: FlagHeadersEndStream | FlagHeadersEndHeaders | FlagHeadersPadded,
- Length: uint32(1 + len("abc") + 5), // pad length + contents + padding
- },
- Priority: PriorityParam{},
- headerFragBuf: []byte("abc"),
- },
- },
- {
- "with priority",
- HeadersFrameParam{
- StreamID: 42,
- BlockFragment: []byte("abc"),
- EndStream: true,
- EndHeaders: true,
- PadLength: 2,
- Priority: PriorityParam{
- StreamDep: 15,
- Exclusive: true,
- Weight: 127,
- },
- },
- "\x00\x00\v\x01-\x00\x00\x00*\x02\x80\x00\x00\x0f\u007fabc\x00\x00",
- &HeadersFrame{
- FrameHeader: FrameHeader{
- valid: true,
- StreamID: 42,
- Type: FrameHeaders,
- Flags: FlagHeadersEndStream | FlagHeadersEndHeaders | FlagHeadersPadded | FlagHeadersPriority,
- Length: uint32(1 + 5 + len("abc") + 2), // pad length + priority + contents + padding
- },
- Priority: PriorityParam{
- StreamDep: 15,
- Exclusive: true,
- Weight: 127,
- },
- headerFragBuf: []byte("abc"),
- },
- },
- }
- for _, tt := range tests {
- fr, buf := testFramer()
- if err := fr.WriteHeaders(tt.p); err != nil {
- t.Errorf("test %q: %v", tt.name, err)
- continue
- }
- if buf.String() != tt.wantEnc {
- t.Errorf("test %q: encoded %q; want %q", tt.name, buf.Bytes(), tt.wantEnc)
- }
- f, err := fr.ReadFrame()
- if err != nil {
- t.Errorf("test %q: failed to read the frame back: %v", tt.name, err)
- continue
- }
- if !reflect.DeepEqual(f, tt.wantFrame) {
- t.Errorf("test %q: mismatch.\n got: %#v\nwant: %#v\n", tt.name, f, tt.wantFrame)
- }
- }
- }
- func TestWriteContinuation(t *testing.T) {
- const streamID = 42
- tests := []struct {
- name string
- end bool
- frag []byte
- wantFrame *ContinuationFrame
- }{
- {
- "not end",
- false,
- []byte("abc"),
- &ContinuationFrame{
- FrameHeader: FrameHeader{
- valid: true,
- StreamID: streamID,
- Type: FrameContinuation,
- Length: uint32(len("abc")),
- },
- headerFragBuf: []byte("abc"),
- },
- },
- {
- "end",
- true,
- []byte("def"),
- &ContinuationFrame{
- FrameHeader: FrameHeader{
- valid: true,
- StreamID: streamID,
- Type: FrameContinuation,
- Flags: FlagContinuationEndHeaders,
- Length: uint32(len("def")),
- },
- headerFragBuf: []byte("def"),
- },
- },
- }
- for _, tt := range tests {
- fr, _ := testFramer()
- if err := fr.WriteContinuation(streamID, tt.end, tt.frag); err != nil {
- t.Errorf("test %q: %v", tt.name, err)
- continue
- }
- f, err := fr.ReadFrame()
- if err != nil {
- t.Errorf("test %q: failed to read the frame back: %v", tt.name, err)
- continue
- }
- if !reflect.DeepEqual(f, tt.wantFrame) {
- t.Errorf("test %q: mismatch.\n got: %#v\nwant: %#v\n", tt.name, f, tt.wantFrame)
- }
- }
- }
- func TestWritePriority(t *testing.T) {
- const streamID = 42
- tests := []struct {
- name string
- priority PriorityParam
- wantFrame *PriorityFrame
- }{
- {
- "not exclusive",
- PriorityParam{
- StreamDep: 2,
- Exclusive: false,
- Weight: 127,
- },
- &PriorityFrame{
- FrameHeader{
- valid: true,
- StreamID: streamID,
- Type: FramePriority,
- Length: 5,
- },
- PriorityParam{
- StreamDep: 2,
- Exclusive: false,
- Weight: 127,
- },
- },
- },
- {
- "exclusive",
- PriorityParam{
- StreamDep: 3,
- Exclusive: true,
- Weight: 77,
- },
- &PriorityFrame{
- FrameHeader{
- valid: true,
- StreamID: streamID,
- Type: FramePriority,
- Length: 5,
- },
- PriorityParam{
- StreamDep: 3,
- Exclusive: true,
- Weight: 77,
- },
- },
- },
- }
- for _, tt := range tests {
- fr, _ := testFramer()
- if err := fr.WritePriority(streamID, tt.priority); err != nil {
- t.Errorf("test %q: %v", tt.name, err)
- continue
- }
- f, err := fr.ReadFrame()
- if err != nil {
- t.Errorf("test %q: failed to read the frame back: %v", tt.name, err)
- continue
- }
- if !reflect.DeepEqual(f, tt.wantFrame) {
- t.Errorf("test %q: mismatch.\n got: %#v\nwant: %#v\n", tt.name, f, tt.wantFrame)
- }
- }
- }
- func TestWriteSettings(t *testing.T) {
- fr, buf := testFramer()
- fr.WriteSettings(Setting{1, 2}, Setting{3, 4})
- const wantEnc = "\x00\x00\f\x04\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x03\x00\x00\x00\x04"
- if buf.String() != wantEnc {
- t.Errorf("encoded as %q; want %q", buf.Bytes(), wantEnc)
- }
- }
- func TestWriteSettingsAck(t *testing.T) {
- fr, buf := testFramer()
- fr.WriteSettingsAck()
- const wantEnc = "\x00\x00\x00\x04\x01\x00\x00\x00\x00"
- if buf.String() != wantEnc {
- t.Errorf("encoded as %q; want %q", buf.Bytes(), wantEnc)
- }
- }
|