github.com/alejandroesc/spdy@v0.0.0-20200317064415-01a02f0eb389/spdy2/frames/goaway.go (about) 1 // Copyright 2014 Jamie Hall. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package frames 6 7 import ( 8 "bytes" 9 "fmt" 10 "io" 11 12 "github.com/SlyMarbo/spdy/common" 13 ) 14 15 type GOAWAY struct { 16 LastGoodStreamID common.StreamID 17 } 18 19 func (frame *GOAWAY) Compress(comp common.Compressor) error { 20 return nil 21 } 22 23 func (frame *GOAWAY) Decompress(decomp common.Decompressor) error { 24 return nil 25 } 26 27 func (frame *GOAWAY) Name() string { 28 return "GOAWAY" 29 } 30 31 func (frame *GOAWAY) ReadFrom(reader io.Reader) (int64, error) { 32 c := common.ReadCounter{R: reader} 33 data, err := common.ReadExactly(&c, 12) 34 if err != nil { 35 return c.N, err 36 } 37 38 err = controlFrameCommonProcessing(data[:5], _GOAWAY, 0) 39 if err != nil { 40 return c.N, err 41 } 42 43 // Get and check length. 44 length := int(common.BytesToUint24(data[5:8])) 45 if length != 4 { 46 return c.N, common.IncorrectDataLength(length, 4) 47 } 48 49 frame.LastGoodStreamID = common.StreamID(common.BytesToUint32(data[8:12])) 50 51 if !frame.LastGoodStreamID.Valid() { 52 return c.N, common.StreamIdTooLarge 53 } 54 55 return c.N, nil 56 } 57 58 func (frame *GOAWAY) String() string { 59 buf := new(bytes.Buffer) 60 61 buf.WriteString("GOAWAY {\n\t") 62 buf.WriteString(fmt.Sprintf("Version: 2\n\t")) 63 buf.WriteString(fmt.Sprintf("Last good stream ID: %d\n}\n", frame.LastGoodStreamID)) 64 65 return buf.String() 66 } 67 68 func (frame *GOAWAY) WriteTo(writer io.Writer) (int64, error) { 69 c := common.WriteCounter{W: writer} 70 if !frame.LastGoodStreamID.Valid() { 71 return c.N, common.StreamIdTooLarge 72 } 73 74 out := make([]byte, 12) 75 76 out[0] = 128 // Control bit and Version 77 out[1] = 2 // Version 78 out[2] = 0 // Type 79 out[3] = 7 // Type 80 out[4] = 0 // Flags 81 out[5] = 0 // Length 82 out[6] = 0 // Length 83 out[7] = 4 // Length 84 out[8] = frame.LastGoodStreamID.B1() // Last Good Stream ID 85 out[9] = frame.LastGoodStreamID.B2() // Last Good Stream ID 86 out[10] = frame.LastGoodStreamID.B3() // Last Good Stream ID 87 out[11] = frame.LastGoodStreamID.B4() // Last Good Stream ID 88 89 err := common.WriteExactly(&c, out) 90 if err != nil { 91 return c.N, err 92 } 93 94 return c.N, nil 95 }