github.com/alejandroEsc/spdy@v0.0.0-20200317064415-01a02f0eb389/spdy3/frames/rst_stream.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 RST_STREAM struct { 16 StreamID common.StreamID 17 Status common.StatusCode 18 } 19 20 func (frame *RST_STREAM) Compress(comp common.Compressor) error { 21 return nil 22 } 23 24 func (frame *RST_STREAM) Decompress(decomp common.Decompressor) error { 25 return nil 26 } 27 28 func (frame *RST_STREAM) Error() string { 29 if err := frame.Status.String(); err != "" { 30 return err 31 } 32 33 return fmt.Sprintf("[unknown status code %d]", frame.Status) 34 } 35 36 func (frame *RST_STREAM) Name() string { 37 return "RST_STREAM" 38 } 39 40 func (frame *RST_STREAM) ReadFrom(reader io.Reader) (int64, error) { 41 c := common.ReadCounter{R: reader} 42 data, err := common.ReadExactly(&c, 16) 43 if err != nil { 44 return c.N, err 45 } 46 47 err = controlFrameCommonProcessing(data[:5], _RST_STREAM, 0) 48 if err != nil { 49 return c.N, err 50 } 51 52 // Get and check length. 53 length := int(common.BytesToUint24(data[5:8])) 54 if length != 8 { 55 return c.N, common.IncorrectDataLength(length, 8) 56 } else if length > common.MAX_FRAME_SIZE-8 { 57 return c.N, common.FrameTooLarge 58 } 59 60 frame.StreamID = common.StreamID(common.BytesToUint32(data[8:12])) 61 frame.Status = common.StatusCode(common.BytesToUint32(data[12:16])) 62 63 if !frame.StreamID.Valid() { 64 return c.N, common.StreamIdTooLarge 65 } 66 67 return c.N, nil 68 } 69 70 func (frame *RST_STREAM) String() string { 71 buf := new(bytes.Buffer) 72 73 buf.WriteString("RST_STREAM {\n\t") 74 buf.WriteString(fmt.Sprintf("Version: 3\n\t")) 75 buf.WriteString(fmt.Sprintf("Stream ID: %d\n\t", frame.StreamID)) 76 buf.WriteString(fmt.Sprintf("Status code: %s\n}\n", frame.Status)) 77 78 return buf.String() 79 } 80 81 func (frame *RST_STREAM) WriteTo(writer io.Writer) (int64, error) { 82 c := common.WriteCounter{W: writer} 83 if !frame.StreamID.Valid() { 84 return c.N, common.StreamIdTooLarge 85 } 86 87 out := make([]byte, 16) 88 89 out[0] = 128 // Control bit and Version 90 out[1] = 3 // Version 91 out[2] = 0 // Type 92 out[3] = 3 // Type 93 out[4] = 0 // Flags 94 out[5] = 0 // Length 95 out[6] = 0 // Length 96 out[7] = 8 // Length 97 out[8] = frame.StreamID.B1() // Stream ID 98 out[9] = frame.StreamID.B2() // Stream ID 99 out[10] = frame.StreamID.B3() // Stream ID 100 out[11] = frame.StreamID.B4() // Stream ID 101 out[12] = frame.Status.B1() // Status 102 out[13] = frame.Status.B2() // Status 103 out[14] = frame.Status.B3() // Status 104 out[15] = frame.Status.B4() // Status 105 106 err := common.WriteExactly(&c, out) 107 if err != nil { 108 return c.N, err 109 } 110 111 return c.N, nil 112 }