github.com/alejandroEsc/spdy@v0.0.0-20200317064415-01a02f0eb389/spdy3/frames/syn_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 "errors" 10 "fmt" 11 "io" 12 "net/http" 13 14 "github.com/SlyMarbo/spdy/common" 15 ) 16 17 type SYN_STREAM struct { 18 Flags common.Flags 19 StreamID common.StreamID 20 AssocStreamID common.StreamID 21 Priority common.Priority 22 Slot byte 23 Header http.Header 24 rawHeader []byte 25 } 26 27 func (frame *SYN_STREAM) Compress(com common.Compressor) error { 28 if frame.rawHeader != nil { 29 return nil 30 } 31 32 data, err := com.Compress(frame.Header) 33 if err != nil { 34 return err 35 } 36 37 frame.rawHeader = data 38 return nil 39 } 40 41 func (frame *SYN_STREAM) Decompress(decom common.Decompressor) error { 42 if frame.Header != nil { 43 return nil 44 } 45 46 header, err := decom.Decompress(frame.rawHeader) 47 if err != nil { 48 return err 49 } 50 51 frame.Header = header 52 frame.rawHeader = nil 53 return nil 54 } 55 56 func (frame *SYN_STREAM) Name() string { 57 return "SYN_STREAM" 58 } 59 60 func (frame *SYN_STREAM) ReadFrom(reader io.Reader) (int64, error) { 61 c := common.ReadCounter{R: reader} 62 data, err := common.ReadExactly(&c, 18) 63 if err != nil { 64 return c.N, err 65 } 66 67 err = controlFrameCommonProcessing(data[:5], _SYN_STREAM, common.FLAG_FIN|common.FLAG_UNIDIRECTIONAL) 68 if err != nil { 69 return c.N, err 70 } 71 72 // Get and check length. 73 length := int(common.BytesToUint24(data[5:8])) 74 if length < 10 { 75 return c.N, common.IncorrectDataLength(length, 10) 76 } else if length > common.MAX_FRAME_SIZE-18 { 77 return c.N, common.FrameTooLarge 78 } 79 80 // Read in data. 81 header, err := common.ReadExactly(&c, length-10) 82 if err != nil { 83 return c.N, err 84 } 85 86 frame.Flags = common.Flags(data[4]) 87 frame.StreamID = common.StreamID(common.BytesToUint32(data[8:12])) 88 frame.AssocStreamID = common.StreamID(common.BytesToUint32(data[12:16])) 89 frame.Priority = common.Priority(data[16] >> 5) 90 frame.Slot = data[17] 91 frame.rawHeader = header 92 93 if !frame.StreamID.Valid() { 94 return c.N, common.StreamIdTooLarge 95 } 96 if frame.StreamID.Zero() { 97 return c.N, common.StreamIdIsZero 98 } 99 if !frame.AssocStreamID.Valid() { 100 return c.N, common.StreamIdTooLarge 101 } 102 103 return c.N, nil 104 } 105 106 func (frame *SYN_STREAM) String() string { 107 buf := new(bytes.Buffer) 108 flags := "" 109 if frame.Flags.FIN() { 110 flags += " common.FLAG_FIN" 111 } 112 if frame.Flags.UNIDIRECTIONAL() { 113 flags += " FLAG_UNIDIRECTIONAL" 114 } 115 if flags == "" { 116 flags = "[NONE]" 117 } else { 118 flags = flags[1:] 119 } 120 121 buf.WriteString("SYN_STREAM {\n\t") 122 buf.WriteString(fmt.Sprintf("Version: 3\n\t")) 123 buf.WriteString(fmt.Sprintf("Flags: %s\n\t", flags)) 124 buf.WriteString(fmt.Sprintf("Stream ID: %d\n\t", frame.StreamID)) 125 buf.WriteString(fmt.Sprintf("Associated Stream ID: %d\n\t", frame.AssocStreamID)) 126 buf.WriteString(fmt.Sprintf("Priority: %d\n\t", frame.Priority)) 127 buf.WriteString(fmt.Sprintf("Slot: %d\n\t", frame.Slot)) 128 buf.WriteString(fmt.Sprintf("Header: %#v\n}\n", frame.Header)) 129 130 return buf.String() 131 } 132 133 func (frame *SYN_STREAM) WriteTo(writer io.Writer) (int64, error) { 134 c := common.WriteCounter{W: writer} 135 if frame.rawHeader == nil { 136 return c.N, errors.New("Error: Headers not written.") 137 } 138 if !frame.StreamID.Valid() { 139 return c.N, common.StreamIdTooLarge 140 } 141 if frame.StreamID.Zero() { 142 return c.N, common.StreamIdIsZero 143 } 144 if !frame.AssocStreamID.Valid() { 145 return c.N, common.StreamIdTooLarge 146 } 147 148 header := frame.rawHeader 149 length := 10 + len(header) 150 out := make([]byte, 18) 151 152 out[0] = 128 // Control bit and Version 153 out[1] = 3 // Version 154 out[2] = 0 // Type 155 out[3] = 1 // Type 156 out[4] = byte(frame.Flags) // Flags 157 out[5] = byte(length >> 16) // Length 158 out[6] = byte(length >> 8) // Length 159 out[7] = byte(length) // Length 160 out[8] = frame.StreamID.B1() // Stream ID 161 out[9] = frame.StreamID.B2() // Stream ID 162 out[10] = frame.StreamID.B3() // Stream ID 163 out[11] = frame.StreamID.B4() // Stream ID 164 out[12] = frame.AssocStreamID.B1() // Associated Stream ID 165 out[13] = frame.AssocStreamID.B2() // Associated Stream ID 166 out[14] = frame.AssocStreamID.B3() // Associated Stream ID 167 out[15] = frame.AssocStreamID.B4() // Associated Stream ID 168 out[16] = frame.Priority.Byte(3) // Priority and unused 169 out[17] = frame.Slot // Slot 170 171 err := common.WriteExactly(&c, out) 172 if err != nil { 173 return c.N, err 174 } 175 176 err = common.WriteExactly(&c, header) 177 if err != nil { 178 return c.N, err 179 } 180 181 return c.N, nil 182 } 183 184 // SPDY/3.1 185 type SYN_STREAMV3_1 struct { 186 Flags common.Flags 187 StreamID common.StreamID 188 AssocStreamID common.StreamID 189 Priority common.Priority 190 Header http.Header 191 rawHeader []byte 192 } 193 194 func (frame *SYN_STREAMV3_1) Compress(com common.Compressor) error { 195 if frame.rawHeader != nil { 196 return nil 197 } 198 199 data, err := com.Compress(frame.Header) 200 if err != nil { 201 return err 202 } 203 204 frame.rawHeader = data 205 return nil 206 } 207 208 func (frame *SYN_STREAMV3_1) Decompress(decom common.Decompressor) error { 209 if frame.Header != nil { 210 return nil 211 } 212 213 header, err := decom.Decompress(frame.rawHeader) 214 if err != nil { 215 return err 216 } 217 218 frame.Header = header 219 frame.rawHeader = nil 220 return nil 221 } 222 223 func (frame *SYN_STREAMV3_1) Name() string { 224 return "SYN_STREAM" 225 } 226 227 func (frame *SYN_STREAMV3_1) ReadFrom(reader io.Reader) (int64, error) { 228 c := common.ReadCounter{R: reader} 229 data, err := common.ReadExactly(&c, 18) 230 if err != nil { 231 return c.N, err 232 } 233 234 err = controlFrameCommonProcessing(data[:5], _SYN_STREAM, common.FLAG_FIN|common.FLAG_UNIDIRECTIONAL) 235 if err != nil { 236 return c.N, err 237 } 238 239 // Get and check length. 240 length := int(common.BytesToUint24(data[5:8])) 241 if length < 10 { 242 return c.N, common.IncorrectDataLength(length, 10) 243 } else if length > common.MAX_FRAME_SIZE-18 { 244 return c.N, common.FrameTooLarge 245 } 246 247 // Read in data. 248 header, err := common.ReadExactly(&c, length-10) 249 if err != nil { 250 return c.N, err 251 } 252 253 frame.Flags = common.Flags(data[4]) 254 frame.StreamID = common.StreamID(common.BytesToUint32(data[8:12])) 255 frame.AssocStreamID = common.StreamID(common.BytesToUint32(data[12:16])) 256 frame.Priority = common.Priority(data[16] >> 5) 257 frame.rawHeader = header 258 259 if !frame.StreamID.Valid() { 260 return c.N, common.StreamIdTooLarge 261 } 262 if frame.StreamID.Zero() { 263 return c.N, common.StreamIdIsZero 264 } 265 if !frame.AssocStreamID.Valid() { 266 return c.N, common.StreamIdTooLarge 267 } 268 269 return c.N, nil 270 } 271 272 func (frame *SYN_STREAMV3_1) String() string { 273 buf := new(bytes.Buffer) 274 flags := "" 275 if frame.Flags.FIN() { 276 flags += " common.FLAG_FIN" 277 } 278 if frame.Flags.UNIDIRECTIONAL() { 279 flags += " FLAG_UNIDIRECTIONAL" 280 } 281 if flags == "" { 282 flags = "[NONE]" 283 } else { 284 flags = flags[1:] 285 } 286 287 buf.WriteString("SYN_STREAM {\n\t") 288 buf.WriteString(fmt.Sprintf("Version: 3\n\t")) 289 buf.WriteString(fmt.Sprintf("Flags: %s\n\t", flags)) 290 buf.WriteString(fmt.Sprintf("Stream ID: %d\n\t", frame.StreamID)) 291 buf.WriteString(fmt.Sprintf("Associated Stream ID: %d\n\t", frame.AssocStreamID)) 292 buf.WriteString(fmt.Sprintf("Priority: %d\n\t", frame.Priority)) 293 buf.WriteString(fmt.Sprintf("Header: %#v\n}\n", frame.Header)) 294 295 return buf.String() 296 } 297 298 func (frame *SYN_STREAMV3_1) WriteTo(writer io.Writer) (int64, error) { 299 c := common.WriteCounter{W: writer} 300 if frame.rawHeader == nil { 301 return c.N, errors.New("Error: Headers not written.") 302 } 303 if !frame.StreamID.Valid() { 304 return c.N, common.StreamIdTooLarge 305 } 306 if frame.StreamID.Zero() { 307 return c.N, common.StreamIdIsZero 308 } 309 if !frame.AssocStreamID.Valid() { 310 return c.N, common.StreamIdTooLarge 311 } 312 313 header := frame.rawHeader 314 length := 10 + len(header) 315 out := make([]byte, 18) 316 317 out[0] = 128 // Control bit and Version 318 out[1] = 3 // Version 319 out[2] = 0 // Type 320 out[3] = 1 // Type 321 out[4] = byte(frame.Flags) // Flags 322 out[5] = byte(length >> 16) // Length 323 out[6] = byte(length >> 8) // Length 324 out[7] = byte(length) // Length 325 out[8] = frame.StreamID.B1() // Stream ID 326 out[9] = frame.StreamID.B2() // Stream ID 327 out[10] = frame.StreamID.B3() // Stream ID 328 out[11] = frame.StreamID.B4() // Stream ID 329 out[12] = frame.AssocStreamID.B1() // Associated Stream ID 330 out[13] = frame.AssocStreamID.B2() // Associated Stream ID 331 out[14] = frame.AssocStreamID.B3() // Associated Stream ID 332 out[15] = frame.AssocStreamID.B4() // Associated Stream ID 333 out[16] = frame.Priority.Byte(3) // Priority and unused 334 out[17] = 0 // Reserved 335 336 err := common.WriteExactly(&c, out) 337 if err != nil { 338 return c.N, err 339 } 340 341 err = common.WriteExactly(&c, header) 342 if err != nil { 343 return c.N, err 344 } 345 346 return c.N, nil 347 }