...

Source file src/github.com/moby/spdystream/spdy/types.go

Documentation: github.com/moby/spdystream/spdy

     1  /*
     2     Copyright 2014-2021 Docker Inc.
     3  
     4     Licensed under the Apache License, Version 2.0 (the "License");
     5     you may not use this file except in compliance with the License.
     6     You may obtain a copy of the License at
     7  
     8         http://www.apache.org/licenses/LICENSE-2.0
     9  
    10     Unless required by applicable law or agreed to in writing, software
    11     distributed under the License is distributed on an "AS IS" BASIS,
    12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13     See the License for the specific language governing permissions and
    14     limitations under the License.
    15  */
    16  
    17  // Copyright 2011 The Go Authors. All rights reserved.
    18  // Use of this source code is governed by a BSD-style
    19  // license that can be found in the LICENSE file.
    20  
    21  // Package spdy implements the SPDY protocol (currently SPDY/3), described in
    22  // http://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3.
    23  package spdy
    24  
    25  import (
    26  	"bytes"
    27  	"compress/zlib"
    28  	"io"
    29  	"net/http"
    30  )
    31  
    32  // Version is the protocol version number that this package implements.
    33  const Version = 3
    34  
    35  // ControlFrameType stores the type field in a control frame header.
    36  type ControlFrameType uint16
    37  
    38  const (
    39  	TypeSynStream    ControlFrameType = 0x0001
    40  	TypeSynReply     ControlFrameType = 0x0002
    41  	TypeRstStream    ControlFrameType = 0x0003
    42  	TypeSettings     ControlFrameType = 0x0004
    43  	TypePing         ControlFrameType = 0x0006
    44  	TypeGoAway       ControlFrameType = 0x0007
    45  	TypeHeaders      ControlFrameType = 0x0008
    46  	TypeWindowUpdate ControlFrameType = 0x0009
    47  )
    48  
    49  // ControlFlags are the flags that can be set on a control frame.
    50  type ControlFlags uint8
    51  
    52  const (
    53  	ControlFlagFin                   ControlFlags = 0x01
    54  	ControlFlagUnidirectional        ControlFlags = 0x02
    55  	ControlFlagSettingsClearSettings ControlFlags = 0x01
    56  )
    57  
    58  // DataFlags are the flags that can be set on a data frame.
    59  type DataFlags uint8
    60  
    61  const (
    62  	DataFlagFin DataFlags = 0x01
    63  )
    64  
    65  // MaxDataLength is the maximum number of bytes that can be stored in one frame.
    66  const MaxDataLength = 1<<24 - 1
    67  
    68  // headerValueSepator separates multiple header values.
    69  const headerValueSeparator = "\x00"
    70  
    71  // Frame is a single SPDY frame in its unpacked in-memory representation. Use
    72  // Framer to read and write it.
    73  type Frame interface {
    74  	write(f *Framer) error
    75  }
    76  
    77  // ControlFrameHeader contains all the fields in a control frame header,
    78  // in its unpacked in-memory representation.
    79  type ControlFrameHeader struct {
    80  	// Note, high bit is the "Control" bit.
    81  	version   uint16 // spdy version number
    82  	frameType ControlFrameType
    83  	Flags     ControlFlags
    84  	length    uint32 // length of data field
    85  }
    86  
    87  type controlFrame interface {
    88  	Frame
    89  	read(h ControlFrameHeader, f *Framer) error
    90  }
    91  
    92  // StreamId represents a 31-bit value identifying the stream.
    93  type StreamId uint32
    94  
    95  // SynStreamFrame is the unpacked, in-memory representation of a SYN_STREAM
    96  // frame.
    97  type SynStreamFrame struct {
    98  	CFHeader             ControlFrameHeader
    99  	StreamId             StreamId
   100  	AssociatedToStreamId StreamId // stream id for a stream which this stream is associated to
   101  	Priority             uint8    // priority of this frame (3-bit)
   102  	Slot                 uint8    // index in the server's credential vector of the client certificate
   103  	Headers              http.Header
   104  }
   105  
   106  // SynReplyFrame is the unpacked, in-memory representation of a SYN_REPLY frame.
   107  type SynReplyFrame struct {
   108  	CFHeader ControlFrameHeader
   109  	StreamId StreamId
   110  	Headers  http.Header
   111  }
   112  
   113  // RstStreamStatus represents the status that led to a RST_STREAM.
   114  type RstStreamStatus uint32
   115  
   116  const (
   117  	ProtocolError RstStreamStatus = iota + 1
   118  	InvalidStream
   119  	RefusedStream
   120  	UnsupportedVersion
   121  	Cancel
   122  	InternalError
   123  	FlowControlError
   124  	StreamInUse
   125  	StreamAlreadyClosed
   126  	InvalidCredentials
   127  	FrameTooLarge
   128  )
   129  
   130  // RstStreamFrame is the unpacked, in-memory representation of a RST_STREAM
   131  // frame.
   132  type RstStreamFrame struct {
   133  	CFHeader ControlFrameHeader
   134  	StreamId StreamId
   135  	Status   RstStreamStatus
   136  }
   137  
   138  // SettingsFlag represents a flag in a SETTINGS frame.
   139  type SettingsFlag uint8
   140  
   141  const (
   142  	FlagSettingsPersistValue SettingsFlag = 0x1
   143  	FlagSettingsPersisted    SettingsFlag = 0x2
   144  )
   145  
   146  // SettingsFlag represents the id of an id/value pair in a SETTINGS frame.
   147  type SettingsId uint32
   148  
   149  const (
   150  	SettingsUploadBandwidth SettingsId = iota + 1
   151  	SettingsDownloadBandwidth
   152  	SettingsRoundTripTime
   153  	SettingsMaxConcurrentStreams
   154  	SettingsCurrentCwnd
   155  	SettingsDownloadRetransRate
   156  	SettingsInitialWindowSize
   157  	SettingsClientCretificateVectorSize
   158  )
   159  
   160  // SettingsFlagIdValue is the unpacked, in-memory representation of the
   161  // combined flag/id/value for a setting in a SETTINGS frame.
   162  type SettingsFlagIdValue struct {
   163  	Flag  SettingsFlag
   164  	Id    SettingsId
   165  	Value uint32
   166  }
   167  
   168  // SettingsFrame is the unpacked, in-memory representation of a SPDY
   169  // SETTINGS frame.
   170  type SettingsFrame struct {
   171  	CFHeader     ControlFrameHeader
   172  	FlagIdValues []SettingsFlagIdValue
   173  }
   174  
   175  // PingFrame is the unpacked, in-memory representation of a PING frame.
   176  type PingFrame struct {
   177  	CFHeader ControlFrameHeader
   178  	Id       uint32 // unique id for this ping, from server is even, from client is odd.
   179  }
   180  
   181  // GoAwayStatus represents the status in a GoAwayFrame.
   182  type GoAwayStatus uint32
   183  
   184  const (
   185  	GoAwayOK GoAwayStatus = iota
   186  	GoAwayProtocolError
   187  	GoAwayInternalError
   188  )
   189  
   190  // GoAwayFrame is the unpacked, in-memory representation of a GOAWAY frame.
   191  type GoAwayFrame struct {
   192  	CFHeader         ControlFrameHeader
   193  	LastGoodStreamId StreamId // last stream id which was accepted by sender
   194  	Status           GoAwayStatus
   195  }
   196  
   197  // HeadersFrame is the unpacked, in-memory representation of a HEADERS frame.
   198  type HeadersFrame struct {
   199  	CFHeader ControlFrameHeader
   200  	StreamId StreamId
   201  	Headers  http.Header
   202  }
   203  
   204  // WindowUpdateFrame is the unpacked, in-memory representation of a
   205  // WINDOW_UPDATE frame.
   206  type WindowUpdateFrame struct {
   207  	CFHeader        ControlFrameHeader
   208  	StreamId        StreamId
   209  	DeltaWindowSize uint32 // additional number of bytes to existing window size
   210  }
   211  
   212  // TODO: Implement credential frame and related methods.
   213  
   214  // DataFrame is the unpacked, in-memory representation of a DATA frame.
   215  type DataFrame struct {
   216  	// Note, high bit is the "Control" bit. Should be 0 for data frames.
   217  	StreamId StreamId
   218  	Flags    DataFlags
   219  	Data     []byte // payload data of this frame
   220  }
   221  
   222  // A SPDY specific error.
   223  type ErrorCode string
   224  
   225  const (
   226  	UnlowercasedHeaderName     ErrorCode = "header was not lowercased"
   227  	DuplicateHeaders           ErrorCode = "multiple headers with same name"
   228  	WrongCompressedPayloadSize ErrorCode = "compressed payload size was incorrect"
   229  	UnknownFrameType           ErrorCode = "unknown frame type"
   230  	InvalidControlFrame        ErrorCode = "invalid control frame"
   231  	InvalidDataFrame           ErrorCode = "invalid data frame"
   232  	InvalidHeaderPresent       ErrorCode = "frame contained invalid header"
   233  	ZeroStreamId               ErrorCode = "stream id zero is disallowed"
   234  )
   235  
   236  // Error contains both the type of error and additional values. StreamId is 0
   237  // if Error is not associated with a stream.
   238  type Error struct {
   239  	Err      ErrorCode
   240  	StreamId StreamId
   241  }
   242  
   243  func (e *Error) Error() string {
   244  	return string(e.Err)
   245  }
   246  
   247  var invalidReqHeaders = map[string]bool{
   248  	"Connection":        true,
   249  	"Host":              true,
   250  	"Keep-Alive":        true,
   251  	"Proxy-Connection":  true,
   252  	"Transfer-Encoding": true,
   253  }
   254  
   255  var invalidRespHeaders = map[string]bool{
   256  	"Connection":        true,
   257  	"Keep-Alive":        true,
   258  	"Proxy-Connection":  true,
   259  	"Transfer-Encoding": true,
   260  }
   261  
   262  // Framer handles serializing/deserializing SPDY frames, including compressing/
   263  // decompressing payloads.
   264  type Framer struct {
   265  	headerCompressionDisabled bool
   266  	w                         io.Writer
   267  	headerBuf                 *bytes.Buffer
   268  	headerCompressor          *zlib.Writer
   269  	r                         io.Reader
   270  	headerReader              io.LimitedReader
   271  	headerDecompressor        io.ReadCloser
   272  }
   273  
   274  // NewFramer allocates a new Framer for a given SPDY connection, represented by
   275  // a io.Writer and io.Reader. Note that Framer will read and write individual fields
   276  // from/to the Reader and Writer, so the caller should pass in an appropriately
   277  // buffered implementation to optimize performance.
   278  func NewFramer(w io.Writer, r io.Reader) (*Framer, error) {
   279  	compressBuf := new(bytes.Buffer)
   280  	compressor, err := zlib.NewWriterLevelDict(compressBuf, zlib.BestCompression, []byte(headerDictionary))
   281  	if err != nil {
   282  		return nil, err
   283  	}
   284  	framer := &Framer{
   285  		w:                w,
   286  		headerBuf:        compressBuf,
   287  		headerCompressor: compressor,
   288  		r:                r,
   289  	}
   290  	return framer, nil
   291  }
   292  

View as plain text