github.com/alejandroEsc/spdy@v0.0.0-20200317064415-01a02f0eb389/spdy3/frames/data.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 "errors" 10 "fmt" 11 "io" 12 13 "github.com/SlyMarbo/spdy/common" 14 ) 15 16 type DATA struct { 17 StreamID common.StreamID 18 Flags common.Flags 19 Data []byte 20 } 21 22 func (frame *DATA) Compress(comp common.Compressor) error { 23 return nil 24 } 25 26 func (frame *DATA) Decompress(decomp common.Decompressor) error { 27 return nil 28 } 29 30 func (frame *DATA) Name() string { 31 return "DATA" 32 } 33 34 func (frame *DATA) ReadFrom(reader io.Reader) (int64, error) { 35 c := common.ReadCounter{R: reader} 36 data, err := common.ReadExactly(&c, 8) 37 if err != nil { 38 return c.N, err 39 } 40 41 // Check it's a data frame. 42 if data[0]&0x80 == 1 { 43 return c.N, common.IncorrectFrame(_CONTROL_FRAME, _DATA_FRAME, 3) 44 } 45 46 // Check flags. 47 if data[4] & ^byte(common.FLAG_FIN) != 0 { 48 return c.N, common.InvalidField("flags", int(data[4]), common.FLAG_FIN) 49 } 50 51 // Get and check length. 52 length := int(common.BytesToUint24(data[5:8])) 53 if length == 0 && data[4] == 0 { 54 return c.N, common.IncorrectDataLength(length, 1) 55 } else if length > common.MAX_FRAME_SIZE-8 { 56 return c.N, common.FrameTooLarge 57 } 58 59 // Read in data. 60 if length != 0 { 61 frame.Data, err = common.ReadExactly(&c, length) 62 if err != nil { 63 return c.N, err 64 } 65 } 66 67 frame.StreamID = common.StreamID(common.BytesToUint32(data[0:4])) 68 frame.Flags = common.Flags(data[4]) 69 if frame.Data == nil { 70 frame.Data = []byte{} 71 } 72 73 return c.N, nil 74 } 75 76 func (frame *DATA) String() string { 77 buf := new(bytes.Buffer) 78 79 flags := "" 80 if frame.Flags.FIN() { 81 flags += " common.FLAG_FIN" 82 } 83 if flags == "" { 84 flags = "[NONE]" 85 } else { 86 flags = flags[1:] 87 } 88 89 buf.WriteString("DATA {\n\t") 90 buf.WriteString(fmt.Sprintf("Stream ID: %d\n\t", frame.StreamID)) 91 buf.WriteString(fmt.Sprintf("Flags: %s\n\t", flags)) 92 buf.WriteString(fmt.Sprintf("Length: %d\n\t", len(frame.Data))) 93 if common.VerboseLogging || len(frame.Data) <= 21 { 94 buf.WriteString(fmt.Sprintf("Data: [% x]\n}\n", frame.Data)) 95 } else { 96 buf.WriteString(fmt.Sprintf("Data: [% x ... % x]\n}\n", frame.Data[:9], 97 frame.Data[len(frame.Data)-9:])) 98 } 99 100 return buf.String() 101 } 102 103 func (frame *DATA) WriteTo(writer io.Writer) (int64, error) { 104 c := common.WriteCounter{W: writer} 105 length := len(frame.Data) 106 if length > common.MAX_DATA_SIZE { 107 return c.N, errors.New("Error: Data size too large.") 108 } 109 if length == 0 && !frame.Flags.FIN() { 110 return c.N, errors.New("Error: Data is empty.") 111 } 112 113 out := make([]byte, 8) 114 115 out[0] = frame.StreamID.B1() // Control bit and Stream ID 116 out[1] = frame.StreamID.B2() // Stream ID 117 out[2] = frame.StreamID.B3() // Stream ID 118 out[3] = frame.StreamID.B4() // Stream ID 119 out[4] = byte(frame.Flags) // Flags 120 out[5] = byte(length >> 16) // Length 121 out[6] = byte(length >> 8) // Length 122 out[7] = byte(length) // Length 123 124 if err := common.WriteExactly(&c, out); err != nil { 125 return c.N, err 126 } 127 128 if err := common.WriteExactly(&c, frame.Data); err != nil { 129 return c.N, err 130 } 131 132 return c.N, nil 133 }