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  }