github.com/alejandroEsc/spdy@v0.0.0-20200317064415-01a02f0eb389/spdy2/frames/common.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 "bufio" 9 "errors" 10 11 "github.com/SlyMarbo/spdy/common" 12 ) 13 14 // ReadFrame reads and parses a frame from reader. 15 func ReadFrame(reader *bufio.Reader) (frame common.Frame, err error) { 16 start, err := reader.Peek(4) 17 if err != nil { 18 return nil, err 19 } 20 21 if start[0] != 128 { 22 frame = new(DATA) 23 _, err = frame.ReadFrom(reader) 24 return frame, err 25 } 26 27 switch common.BytesToUint16(start[2:4]) { 28 case _SYN_STREAM: 29 frame = new(SYN_STREAM) 30 case _SYN_REPLY: 31 frame = new(SYN_REPLY) 32 case _RST_STREAM: 33 frame = new(RST_STREAM) 34 case _SETTINGS: 35 frame = new(SETTINGS) 36 case _NOOP: 37 frame = new(NOOP) 38 case _PING: 39 frame = new(PING) 40 case _GOAWAY: 41 frame = new(GOAWAY) 42 case _HEADERS: 43 frame = new(HEADERS) 44 case _WINDOW_UPDATE: 45 frame = new(WINDOW_UPDATE) 46 47 default: 48 return nil, errors.New("Error Failed to parse frame type.") 49 } 50 51 _, err = frame.ReadFrom(reader) 52 return frame, err 53 } 54 55 // controlFrameCommonProcessing performs checks identical between 56 // all control frames. This includes the control bit, the version 57 // number, the type byte (which is checked against the byte 58 // provided), and the flags (which are checked against the bitwise 59 // OR of valid flags provided). 60 func controlFrameCommonProcessing(data []byte, frameType uint16, flags byte) error { 61 // Check it's a control frame. 62 if data[0] != 128 { 63 return common.IncorrectFrame(_DATA_FRAME, int(frameType), 2) 64 } 65 66 // Check version. 67 version := (uint16(data[0]&0x7f) << 8) + uint16(data[1]) 68 if version != 2 { 69 return common.UnsupportedVersion(version) 70 } 71 72 // Check its type. 73 realType := common.BytesToUint16(data[2:]) 74 if realType != frameType { 75 return common.IncorrectFrame(int(realType), int(frameType), 2) 76 } 77 78 // Check the flags. 79 if data[4] & ^flags != 0 { 80 return common.InvalidField("flags", int(data[4]), int(flags)) 81 } 82 83 return nil 84 } 85 86 // Frame types in SPDY/2 87 const ( 88 _SYN_STREAM = 1 89 _SYN_REPLY = 2 90 _RST_STREAM = 3 91 _SETTINGS = 4 92 _NOOP = 5 93 _PING = 6 94 _GOAWAY = 7 95 _HEADERS = 8 96 _WINDOW_UPDATE = 9 97 _CONTROL_FRAME = -1 98 _DATA_FRAME = -2 99 ) 100 101 // frameNames provides the name for a particular SPDY/2 102 // frame type. 103 var frameNames = map[int]string{ 104 _SYN_STREAM: "SYN_STREAM", 105 _SYN_REPLY: "SYN_REPLY", 106 _RST_STREAM: "RST_STREAM", 107 _SETTINGS: "SETTINGS", 108 _NOOP: "NOOP", 109 _PING: "PING", 110 _GOAWAY: "GOAWAY", 111 _HEADERS: "HEADERS", 112 _WINDOW_UPDATE: "WINDOW_UPDATE", 113 _CONTROL_FRAME: "CONTROL_FRAME", 114 _DATA_FRAME: "DATA_FRAME", 115 }