github.com/blixtra/rkt@v0.8.1-0.20160204105720-ab0d1add1a43/Godeps/_workspace/src/golang.org/x/net/http2/frame.go (about)

     1  // Copyright 2014 The Go Authors.
     2  // See https://code.google.com/p/go/source/browse/CONTRIBUTORS
     3  // Licensed under the same terms as Go itself:
     4  // https://code.google.com/p/go/source/browse/LICENSE
     5  
     6  package http2
     7  
     8  import (
     9  	"bytes"
    10  	"encoding/binary"
    11  	"errors"
    12  	"fmt"
    13  	"io"
    14  	"sync"
    15  )
    16  
    17  const frameHeaderLen = 9
    18  
    19  var padZeros = make([]byte, 255) // zeros for padding
    20  
    21  // A FrameType is a registered frame type as defined in
    22  // http://http2.github.io/http2-spec/#rfc.section.11.2
    23  type FrameType uint8
    24  
    25  const (
    26  	FrameData         FrameType = 0x0
    27  	FrameHeaders      FrameType = 0x1
    28  	FramePriority     FrameType = 0x2
    29  	FrameRSTStream    FrameType = 0x3
    30  	FrameSettings     FrameType = 0x4
    31  	FramePushPromise  FrameType = 0x5
    32  	FramePing         FrameType = 0x6
    33  	FrameGoAway       FrameType = 0x7
    34  	FrameWindowUpdate FrameType = 0x8
    35  	FrameContinuation FrameType = 0x9
    36  )
    37  
    38  var frameName = map[FrameType]string{
    39  	FrameData:         "DATA",
    40  	FrameHeaders:      "HEADERS",
    41  	FramePriority:     "PRIORITY",
    42  	FrameRSTStream:    "RST_STREAM",
    43  	FrameSettings:     "SETTINGS",
    44  	FramePushPromise:  "PUSH_PROMISE",
    45  	FramePing:         "PING",
    46  	FrameGoAway:       "GOAWAY",
    47  	FrameWindowUpdate: "WINDOW_UPDATE",
    48  	FrameContinuation: "CONTINUATION",
    49  }
    50  
    51  func (t FrameType) String() string {
    52  	if s, ok := frameName[t]; ok {
    53  		return s
    54  	}
    55  	return fmt.Sprintf("UNKNOWN_FRAME_TYPE_%d", uint8(t))
    56  }
    57  
    58  // Flags is a bitmask of HTTP/2 flags.
    59  // The meaning of flags varies depending on the frame type.
    60  type Flags uint8
    61  
    62  // Has reports whether f contains all (0 or more) flags in v.
    63  func (f Flags) Has(v Flags) bool {
    64  	return (f & v) == v
    65  }
    66  
    67  // Frame-specific FrameHeader flag bits.
    68  const (
    69  	// Data Frame
    70  	FlagDataEndStream Flags = 0x1
    71  	FlagDataPadded    Flags = 0x8
    72  
    73  	// Headers Frame
    74  	FlagHeadersEndStream  Flags = 0x1
    75  	FlagHeadersEndHeaders Flags = 0x4
    76  	FlagHeadersPadded     Flags = 0x8
    77  	FlagHeadersPriority   Flags = 0x20
    78  
    79  	// Settings Frame
    80  	FlagSettingsAck Flags = 0x1
    81  
    82  	// Ping Frame
    83  	FlagPingAck Flags = 0x1
    84  
    85  	// Continuation Frame
    86  	FlagContinuationEndHeaders Flags = 0x4
    87  
    88  	FlagPushPromiseEndHeaders Flags = 0x4
    89  	FlagPushPromisePadded     Flags = 0x8
    90  )
    91  
    92  var flagName = map[FrameType]map[Flags]string{
    93  	FrameData: {
    94  		FlagDataEndStream: "END_STREAM",
    95  		FlagDataPadded:    "PADDED",
    96  	},
    97  	FrameHeaders: {
    98  		FlagHeadersEndStream:  "END_STREAM",
    99  		FlagHeadersEndHeaders: "END_HEADERS",
   100  		FlagHeadersPadded:     "PADDED",
   101  		FlagHeadersPriority:   "PRIORITY",
   102  	},
   103  	FrameSettings: {
   104  		FlagSettingsAck: "ACK",
   105  	},
   106  	FramePing: {
   107  		FlagPingAck: "ACK",
   108  	},
   109  	FrameContinuation: {
   110  		FlagContinuationEndHeaders: "END_HEADERS",
   111  	},
   112  	FramePushPromise: {
   113  		FlagPushPromiseEndHeaders: "END_HEADERS",
   114  		FlagPushPromisePadded:     "PADDED",
   115  	},
   116  }
   117  
   118  // a frameParser parses a frame given its FrameHeader and payload
   119  // bytes. The length of payload will always equal fh.Length (which
   120  // might be 0).
   121  type frameParser func(fh FrameHeader, payload []byte) (Frame, error)
   122  
   123  var frameParsers = map[FrameType]frameParser{
   124  	FrameData:         parseDataFrame,
   125  	FrameHeaders:      parseHeadersFrame,
   126  	FramePriority:     parsePriorityFrame,
   127  	FrameRSTStream:    parseRSTStreamFrame,
   128  	FrameSettings:     parseSettingsFrame,
   129  	FramePushPromise:  parsePushPromise,
   130  	FramePing:         parsePingFrame,
   131  	FrameGoAway:       parseGoAwayFrame,
   132  	FrameWindowUpdate: parseWindowUpdateFrame,
   133  	FrameContinuation: parseContinuationFrame,
   134  }
   135  
   136  func typeFrameParser(t FrameType) frameParser {
   137  	if f := frameParsers[t]; f != nil {
   138  		return f
   139  	}
   140  	return parseUnknownFrame
   141  }
   142  
   143  // A FrameHeader is the 9 byte header of all HTTP/2 frames.
   144  //
   145  // See http://http2.github.io/http2-spec/#FrameHeader
   146  type FrameHeader struct {
   147  	valid bool // caller can access []byte fields in the Frame
   148  
   149  	// Type is the 1 byte frame type. There are ten standard frame
   150  	// types, but extension frame types may be written by WriteRawFrame
   151  	// and will be returned by ReadFrame (as UnknownFrame).
   152  	Type FrameType
   153  
   154  	// Flags are the 1 byte of 8 potential bit flags per frame.
   155  	// They are specific to the frame type.
   156  	Flags Flags
   157  
   158  	// Length is the length of the frame, not including the 9 byte header.
   159  	// The maximum size is one byte less than 16MB (uint24), but only
   160  	// frames up to 16KB are allowed without peer agreement.
   161  	Length uint32
   162  
   163  	// StreamID is which stream this frame is for. Certain frames
   164  	// are not stream-specific, in which case this field is 0.
   165  	StreamID uint32
   166  }
   167  
   168  // Header returns h. It exists so FrameHeaders can be embedded in other
   169  // specific frame types and implement the Frame interface.
   170  func (h FrameHeader) Header() FrameHeader { return h }
   171  
   172  func (h FrameHeader) String() string {
   173  	var buf bytes.Buffer
   174  	buf.WriteString("[FrameHeader ")
   175  	buf.WriteString(h.Type.String())
   176  	if h.Flags != 0 {
   177  		buf.WriteString(" flags=")
   178  		set := 0
   179  		for i := uint8(0); i < 8; i++ {
   180  			if h.Flags&(1<<i) == 0 {
   181  				continue
   182  			}
   183  			set++
   184  			if set > 1 {
   185  				buf.WriteByte('|')
   186  			}
   187  			name := flagName[h.Type][Flags(1<<i)]
   188  			if name != "" {
   189  				buf.WriteString(name)
   190  			} else {
   191  				fmt.Fprintf(&buf, "0x%x", 1<<i)
   192  			}
   193  		}
   194  	}
   195  	if h.StreamID != 0 {
   196  		fmt.Fprintf(&buf, " stream=%d", h.StreamID)
   197  	}
   198  	fmt.Fprintf(&buf, " len=%d]", h.Length)
   199  	return buf.String()
   200  }
   201  
   202  func (h *FrameHeader) checkValid() {
   203  	if !h.valid {
   204  		panic("Frame accessor called on non-owned Frame")
   205  	}
   206  }
   207  
   208  func (h *FrameHeader) invalidate() { h.valid = false }
   209  
   210  // frame header bytes.
   211  // Used only by ReadFrameHeader.
   212  var fhBytes = sync.Pool{
   213  	New: func() interface{} {
   214  		buf := make([]byte, frameHeaderLen)
   215  		return &buf
   216  	},
   217  }
   218  
   219  // ReadFrameHeader reads 9 bytes from r and returns a FrameHeader.
   220  // Most users should use Framer.ReadFrame instead.
   221  func ReadFrameHeader(r io.Reader) (FrameHeader, error) {
   222  	bufp := fhBytes.Get().(*[]byte)
   223  	defer fhBytes.Put(bufp)
   224  	return readFrameHeader(*bufp, r)
   225  }
   226  
   227  func readFrameHeader(buf []byte, r io.Reader) (FrameHeader, error) {
   228  	_, err := io.ReadFull(r, buf[:frameHeaderLen])
   229  	if err != nil {
   230  		return FrameHeader{}, err
   231  	}
   232  	return FrameHeader{
   233  		Length:   (uint32(buf[0])<<16 | uint32(buf[1])<<8 | uint32(buf[2])),
   234  		Type:     FrameType(buf[3]),
   235  		Flags:    Flags(buf[4]),
   236  		StreamID: binary.BigEndian.Uint32(buf[5:]) & (1<<31 - 1),
   237  		valid:    true,
   238  	}, nil
   239  }
   240  
   241  // A Frame is the base interface implemented by all frame types.
   242  // Callers will generally type-assert the specific frame type:
   243  // *HeadersFrame, *SettingsFrame, *WindowUpdateFrame, etc.
   244  //
   245  // Frames are only valid until the next call to Framer.ReadFrame.
   246  type Frame interface {
   247  	Header() FrameHeader
   248  
   249  	// invalidate is called by Framer.ReadFrame to make this
   250  	// frame's buffers as being invalid, since the subsequent
   251  	// frame will reuse them.
   252  	invalidate()
   253  }
   254  
   255  // A Framer reads and writes Frames.
   256  type Framer struct {
   257  	r         io.Reader
   258  	lastFrame Frame
   259  
   260  	maxReadSize uint32
   261  	headerBuf   [frameHeaderLen]byte
   262  
   263  	// TODO: let getReadBuf be configurable, and use a less memory-pinning
   264  	// allocator in server.go to minimize memory pinned for many idle conns.
   265  	// Will probably also need to make frame invalidation have a hook too.
   266  	getReadBuf func(size uint32) []byte
   267  	readBuf    []byte // cache for default getReadBuf
   268  
   269  	maxWriteSize uint32 // zero means unlimited; TODO: implement
   270  
   271  	w    io.Writer
   272  	wbuf []byte
   273  
   274  	// AllowIllegalWrites permits the Framer's Write methods to
   275  	// write frames that do not conform to the HTTP/2 spec.  This
   276  	// permits using the Framer to test other HTTP/2
   277  	// implementations' conformance to the spec.
   278  	// If false, the Write methods will prefer to return an error
   279  	// rather than comply.
   280  	AllowIllegalWrites bool
   281  
   282  	// TODO: track which type of frame & with which flags was sent
   283  	// last.  Then return an error (unless AllowIllegalWrites) if
   284  	// we're in the middle of a header block and a
   285  	// non-Continuation or Continuation on a different stream is
   286  	// attempted to be written.
   287  }
   288  
   289  func (f *Framer) startWrite(ftype FrameType, flags Flags, streamID uint32) {
   290  	// Write the FrameHeader.
   291  	f.wbuf = append(f.wbuf[:0],
   292  		0, // 3 bytes of length, filled in in endWrite
   293  		0,
   294  		0,
   295  		byte(ftype),
   296  		byte(flags),
   297  		byte(streamID>>24),
   298  		byte(streamID>>16),
   299  		byte(streamID>>8),
   300  		byte(streamID))
   301  }
   302  
   303  func (f *Framer) endWrite() error {
   304  	// Now that we know the final size, fill in the FrameHeader in
   305  	// the space previously reserved for it. Abuse append.
   306  	length := len(f.wbuf) - frameHeaderLen
   307  	if length >= (1 << 24) {
   308  		return ErrFrameTooLarge
   309  	}
   310  	_ = append(f.wbuf[:0],
   311  		byte(length>>16),
   312  		byte(length>>8),
   313  		byte(length))
   314  	n, err := f.w.Write(f.wbuf)
   315  	if err == nil && n != len(f.wbuf) {
   316  		err = io.ErrShortWrite
   317  	}
   318  	return err
   319  }
   320  
   321  func (f *Framer) writeByte(v byte)     { f.wbuf = append(f.wbuf, v) }
   322  func (f *Framer) writeBytes(v []byte)  { f.wbuf = append(f.wbuf, v...) }
   323  func (f *Framer) writeUint16(v uint16) { f.wbuf = append(f.wbuf, byte(v>>8), byte(v)) }
   324  func (f *Framer) writeUint32(v uint32) {
   325  	f.wbuf = append(f.wbuf, byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
   326  }
   327  
   328  const (
   329  	minMaxFrameSize = 1 << 14
   330  	maxFrameSize    = 1<<24 - 1
   331  )
   332  
   333  // NewFramer returns a Framer that writes frames to w and reads them from r.
   334  func NewFramer(w io.Writer, r io.Reader) *Framer {
   335  	fr := &Framer{
   336  		w: w,
   337  		r: r,
   338  	}
   339  	fr.getReadBuf = func(size uint32) []byte {
   340  		if cap(fr.readBuf) >= int(size) {
   341  			return fr.readBuf[:size]
   342  		}
   343  		fr.readBuf = make([]byte, size)
   344  		return fr.readBuf
   345  	}
   346  	fr.SetMaxReadFrameSize(maxFrameSize)
   347  	return fr
   348  }
   349  
   350  // SetMaxReadFrameSize sets the maximum size of a frame
   351  // that will be read by a subsequent call to ReadFrame.
   352  // It is the caller's responsibility to advertise this
   353  // limit with a SETTINGS frame.
   354  func (fr *Framer) SetMaxReadFrameSize(v uint32) {
   355  	if v > maxFrameSize {
   356  		v = maxFrameSize
   357  	}
   358  	fr.maxReadSize = v
   359  }
   360  
   361  // ErrFrameTooLarge is returned from Framer.ReadFrame when the peer
   362  // sends a frame that is larger than declared with SetMaxReadFrameSize.
   363  var ErrFrameTooLarge = errors.New("http2: frame too large")
   364  
   365  // ReadFrame reads a single frame. The returned Frame is only valid
   366  // until the next call to ReadFrame.
   367  // If the frame is larger than previously set with SetMaxReadFrameSize,
   368  // the returned error is ErrFrameTooLarge.
   369  func (fr *Framer) ReadFrame() (Frame, error) {
   370  	if fr.lastFrame != nil {
   371  		fr.lastFrame.invalidate()
   372  	}
   373  	fh, err := readFrameHeader(fr.headerBuf[:], fr.r)
   374  	if err != nil {
   375  		return nil, err
   376  	}
   377  	if fh.Length > fr.maxReadSize {
   378  		return nil, ErrFrameTooLarge
   379  	}
   380  	payload := fr.getReadBuf(fh.Length)
   381  	if _, err := io.ReadFull(fr.r, payload); err != nil {
   382  		return nil, err
   383  	}
   384  	f, err := typeFrameParser(fh.Type)(fh, payload)
   385  	if err != nil {
   386  		return nil, err
   387  	}
   388  	fr.lastFrame = f
   389  	return f, nil
   390  }
   391  
   392  // A DataFrame conveys arbitrary, variable-length sequences of octets
   393  // associated with a stream.
   394  // See http://http2.github.io/http2-spec/#rfc.section.6.1
   395  type DataFrame struct {
   396  	FrameHeader
   397  	data []byte
   398  }
   399  
   400  func (f *DataFrame) StreamEnded() bool {
   401  	return f.FrameHeader.Flags.Has(FlagDataEndStream)
   402  }
   403  
   404  // Data returns the frame's data octets, not including any padding
   405  // size byte or padding suffix bytes.
   406  // The caller must not retain the returned memory past the next
   407  // call to ReadFrame.
   408  func (f *DataFrame) Data() []byte {
   409  	f.checkValid()
   410  	return f.data
   411  }
   412  
   413  func parseDataFrame(fh FrameHeader, payload []byte) (Frame, error) {
   414  	if fh.StreamID == 0 {
   415  		// DATA frames MUST be associated with a stream. If a
   416  		// DATA frame is received whose stream identifier
   417  		// field is 0x0, the recipient MUST respond with a
   418  		// connection error (Section 5.4.1) of type
   419  		// PROTOCOL_ERROR.
   420  		return nil, ConnectionError(ErrCodeProtocol)
   421  	}
   422  	f := &DataFrame{
   423  		FrameHeader: fh,
   424  	}
   425  	var padSize byte
   426  	if fh.Flags.Has(FlagDataPadded) {
   427  		var err error
   428  		payload, padSize, err = readByte(payload)
   429  		if err != nil {
   430  			return nil, err
   431  		}
   432  	}
   433  	if int(padSize) > len(payload) {
   434  		// If the length of the padding is greater than the
   435  		// length of the frame payload, the recipient MUST
   436  		// treat this as a connection error.
   437  		// Filed: https://github.com/http2/http2-spec/issues/610
   438  		return nil, ConnectionError(ErrCodeProtocol)
   439  	}
   440  	f.data = payload[:len(payload)-int(padSize)]
   441  	return f, nil
   442  }
   443  
   444  var errStreamID = errors.New("invalid streamid")
   445  
   446  func validStreamID(streamID uint32) bool {
   447  	return streamID != 0 && streamID&(1<<31) == 0
   448  }
   449  
   450  // WriteData writes a DATA frame.
   451  //
   452  // It will perform exactly one Write to the underlying Writer.
   453  // It is the caller's responsibility to not call other Write methods concurrently.
   454  func (f *Framer) WriteData(streamID uint32, endStream bool, data []byte) error {
   455  	// TODO: ignoring padding for now. will add when somebody cares.
   456  	if !validStreamID(streamID) && !f.AllowIllegalWrites {
   457  		return errStreamID
   458  	}
   459  	var flags Flags
   460  	if endStream {
   461  		flags |= FlagDataEndStream
   462  	}
   463  	f.startWrite(FrameData, flags, streamID)
   464  	f.wbuf = append(f.wbuf, data...)
   465  	return f.endWrite()
   466  }
   467  
   468  // A SettingsFrame conveys configuration parameters that affect how
   469  // endpoints communicate, such as preferences and constraints on peer
   470  // behavior.
   471  //
   472  // See http://http2.github.io/http2-spec/#SETTINGS
   473  type SettingsFrame struct {
   474  	FrameHeader
   475  	p []byte
   476  }
   477  
   478  func parseSettingsFrame(fh FrameHeader, p []byte) (Frame, error) {
   479  	if fh.Flags.Has(FlagSettingsAck) && fh.Length > 0 {
   480  		// When this (ACK 0x1) bit is set, the payload of the
   481  		// SETTINGS frame MUST be empty.  Receipt of a
   482  		// SETTINGS frame with the ACK flag set and a length
   483  		// field value other than 0 MUST be treated as a
   484  		// connection error (Section 5.4.1) of type
   485  		// FRAME_SIZE_ERROR.
   486  		return nil, ConnectionError(ErrCodeFrameSize)
   487  	}
   488  	if fh.StreamID != 0 {
   489  		// SETTINGS frames always apply to a connection,
   490  		// never a single stream.  The stream identifier for a
   491  		// SETTINGS frame MUST be zero (0x0).  If an endpoint
   492  		// receives a SETTINGS frame whose stream identifier
   493  		// field is anything other than 0x0, the endpoint MUST
   494  		// respond with a connection error (Section 5.4.1) of
   495  		// type PROTOCOL_ERROR.
   496  		return nil, ConnectionError(ErrCodeProtocol)
   497  	}
   498  	if len(p)%6 != 0 {
   499  		// Expecting even number of 6 byte settings.
   500  		return nil, ConnectionError(ErrCodeFrameSize)
   501  	}
   502  	f := &SettingsFrame{FrameHeader: fh, p: p}
   503  	if v, ok := f.Value(SettingInitialWindowSize); ok && v > (1<<31)-1 {
   504  		// Values above the maximum flow control window size of 2^31 - 1 MUST
   505  		// be treated as a connection error (Section 5.4.1) of type
   506  		// FLOW_CONTROL_ERROR.
   507  		return nil, ConnectionError(ErrCodeFlowControl)
   508  	}
   509  	return f, nil
   510  }
   511  
   512  func (f *SettingsFrame) IsAck() bool {
   513  	return f.FrameHeader.Flags.Has(FlagSettingsAck)
   514  }
   515  
   516  func (f *SettingsFrame) Value(s SettingID) (v uint32, ok bool) {
   517  	f.checkValid()
   518  	buf := f.p
   519  	for len(buf) > 0 {
   520  		settingID := SettingID(binary.BigEndian.Uint16(buf[:2]))
   521  		if settingID == s {
   522  			return binary.BigEndian.Uint32(buf[2:6]), true
   523  		}
   524  		buf = buf[6:]
   525  	}
   526  	return 0, false
   527  }
   528  
   529  // ForeachSetting runs fn for each setting.
   530  // It stops and returns the first error.
   531  func (f *SettingsFrame) ForeachSetting(fn func(Setting) error) error {
   532  	f.checkValid()
   533  	buf := f.p
   534  	for len(buf) > 0 {
   535  		if err := fn(Setting{
   536  			SettingID(binary.BigEndian.Uint16(buf[:2])),
   537  			binary.BigEndian.Uint32(buf[2:6]),
   538  		}); err != nil {
   539  			return err
   540  		}
   541  		buf = buf[6:]
   542  	}
   543  	return nil
   544  }
   545  
   546  // WriteSettings writes a SETTINGS frame with zero or more settings
   547  // specified and the ACK bit not set.
   548  //
   549  // It will perform exactly one Write to the underlying Writer.
   550  // It is the caller's responsibility to not call other Write methods concurrently.
   551  func (f *Framer) WriteSettings(settings ...Setting) error {
   552  	f.startWrite(FrameSettings, 0, 0)
   553  	for _, s := range settings {
   554  		f.writeUint16(uint16(s.ID))
   555  		f.writeUint32(s.Val)
   556  	}
   557  	return f.endWrite()
   558  }
   559  
   560  // WriteSettings writes an empty SETTINGS frame with the ACK bit set.
   561  //
   562  // It will perform exactly one Write to the underlying Writer.
   563  // It is the caller's responsibility to not call other Write methods concurrently.
   564  func (f *Framer) WriteSettingsAck() error {
   565  	f.startWrite(FrameSettings, FlagSettingsAck, 0)
   566  	return f.endWrite()
   567  }
   568  
   569  // A PingFrame is a mechanism for measuring a minimal round trip time
   570  // from the sender, as well as determining whether an idle connection
   571  // is still functional.
   572  // See http://http2.github.io/http2-spec/#rfc.section.6.7
   573  type PingFrame struct {
   574  	FrameHeader
   575  	Data [8]byte
   576  }
   577  
   578  func parsePingFrame(fh FrameHeader, payload []byte) (Frame, error) {
   579  	if len(payload) != 8 {
   580  		return nil, ConnectionError(ErrCodeFrameSize)
   581  	}
   582  	if fh.StreamID != 0 {
   583  		return nil, ConnectionError(ErrCodeProtocol)
   584  	}
   585  	f := &PingFrame{FrameHeader: fh}
   586  	copy(f.Data[:], payload)
   587  	return f, nil
   588  }
   589  
   590  func (f *Framer) WritePing(ack bool, data [8]byte) error {
   591  	var flags Flags
   592  	if ack {
   593  		flags = FlagPingAck
   594  	}
   595  	f.startWrite(FramePing, flags, 0)
   596  	f.writeBytes(data[:])
   597  	return f.endWrite()
   598  }
   599  
   600  // A GoAwayFrame informs the remote peer to stop creating streams on this connection.
   601  // See http://http2.github.io/http2-spec/#rfc.section.6.8
   602  type GoAwayFrame struct {
   603  	FrameHeader
   604  	LastStreamID uint32
   605  	ErrCode      ErrCode
   606  	debugData    []byte
   607  }
   608  
   609  // DebugData returns any debug data in the GOAWAY frame. Its contents
   610  // are not defined.
   611  // The caller must not retain the returned memory past the next
   612  // call to ReadFrame.
   613  func (f *GoAwayFrame) DebugData() []byte {
   614  	f.checkValid()
   615  	return f.debugData
   616  }
   617  
   618  func parseGoAwayFrame(fh FrameHeader, p []byte) (Frame, error) {
   619  	if fh.StreamID != 0 {
   620  		return nil, ConnectionError(ErrCodeProtocol)
   621  	}
   622  	if len(p) < 8 {
   623  		return nil, ConnectionError(ErrCodeFrameSize)
   624  	}
   625  	return &GoAwayFrame{
   626  		FrameHeader:  fh,
   627  		LastStreamID: binary.BigEndian.Uint32(p[:4]) & (1<<31 - 1),
   628  		ErrCode:      ErrCode(binary.BigEndian.Uint32(p[4:8])),
   629  		debugData:    p[8:],
   630  	}, nil
   631  }
   632  
   633  func (f *Framer) WriteGoAway(maxStreamID uint32, code ErrCode, debugData []byte) error {
   634  	f.startWrite(FrameGoAway, 0, 0)
   635  	f.writeUint32(maxStreamID & (1<<31 - 1))
   636  	f.writeUint32(uint32(code))
   637  	f.writeBytes(debugData)
   638  	return f.endWrite()
   639  }
   640  
   641  // An UnknownFrame is the frame type returned when the frame type is unknown
   642  // or no specific frame type parser exists.
   643  type UnknownFrame struct {
   644  	FrameHeader
   645  	p []byte
   646  }
   647  
   648  // Payload returns the frame's payload (after the header).  It is not
   649  // valid to call this method after a subsequent call to
   650  // Framer.ReadFrame, nor is it valid to retain the returned slice.
   651  // The memory is owned by the Framer and is invalidated when the next
   652  // frame is read.
   653  func (f *UnknownFrame) Payload() []byte {
   654  	f.checkValid()
   655  	return f.p
   656  }
   657  
   658  func parseUnknownFrame(fh FrameHeader, p []byte) (Frame, error) {
   659  	return &UnknownFrame{fh, p}, nil
   660  }
   661  
   662  // A WindowUpdateFrame is used to implement flow control.
   663  // See http://http2.github.io/http2-spec/#rfc.section.6.9
   664  type WindowUpdateFrame struct {
   665  	FrameHeader
   666  	Increment uint32
   667  }
   668  
   669  func parseWindowUpdateFrame(fh FrameHeader, p []byte) (Frame, error) {
   670  	if len(p) != 4 {
   671  		return nil, ConnectionError(ErrCodeFrameSize)
   672  	}
   673  	inc := binary.BigEndian.Uint32(p[:4]) & 0x7fffffff // mask off high reserved bit
   674  	if inc == 0 {
   675  		// A receiver MUST treat the receipt of a
   676  		// WINDOW_UPDATE frame with an flow control window
   677  		// increment of 0 as a stream error (Section 5.4.2) of
   678  		// type PROTOCOL_ERROR; errors on the connection flow
   679  		// control window MUST be treated as a connection
   680  		// error (Section 5.4.1).
   681  		if fh.StreamID == 0 {
   682  			return nil, ConnectionError(ErrCodeProtocol)
   683  		}
   684  		return nil, StreamError{fh.StreamID, ErrCodeProtocol}
   685  	}
   686  	return &WindowUpdateFrame{
   687  		FrameHeader: fh,
   688  		Increment:   inc,
   689  	}, nil
   690  }
   691  
   692  // WriteWindowUpdate writes a WINDOW_UPDATE frame.
   693  // The increment value must be between 1 and 2,147,483,647, inclusive.
   694  // If the Stream ID is zero, the window update applies to the
   695  // connection as a whole.
   696  func (f *Framer) WriteWindowUpdate(streamID, incr uint32) error {
   697  	// "The legal range for the increment to the flow control window is 1 to 2^31-1 (2,147,483,647) octets."
   698  	if (incr < 1 || incr > 2147483647) && !f.AllowIllegalWrites {
   699  		return errors.New("illegal window increment value")
   700  	}
   701  	f.startWrite(FrameWindowUpdate, 0, streamID)
   702  	f.writeUint32(incr)
   703  	return f.endWrite()
   704  }
   705  
   706  // A HeadersFrame is used to open a stream and additionally carries a
   707  // header block fragment.
   708  type HeadersFrame struct {
   709  	FrameHeader
   710  
   711  	// Priority is set if FlagHeadersPriority is set in the FrameHeader.
   712  	Priority PriorityParam
   713  
   714  	headerFragBuf []byte // not owned
   715  }
   716  
   717  func (f *HeadersFrame) HeaderBlockFragment() []byte {
   718  	f.checkValid()
   719  	return f.headerFragBuf
   720  }
   721  
   722  func (f *HeadersFrame) HeadersEnded() bool {
   723  	return f.FrameHeader.Flags.Has(FlagHeadersEndHeaders)
   724  }
   725  
   726  func (f *HeadersFrame) StreamEnded() bool {
   727  	return f.FrameHeader.Flags.Has(FlagHeadersEndStream)
   728  }
   729  
   730  func (f *HeadersFrame) HasPriority() bool {
   731  	return f.FrameHeader.Flags.Has(FlagHeadersPriority)
   732  }
   733  
   734  func parseHeadersFrame(fh FrameHeader, p []byte) (_ Frame, err error) {
   735  	hf := &HeadersFrame{
   736  		FrameHeader: fh,
   737  	}
   738  	if fh.StreamID == 0 {
   739  		// HEADERS frames MUST be associated with a stream.  If a HEADERS frame
   740  		// is received whose stream identifier field is 0x0, the recipient MUST
   741  		// respond with a connection error (Section 5.4.1) of type
   742  		// PROTOCOL_ERROR.
   743  		return nil, ConnectionError(ErrCodeProtocol)
   744  	}
   745  	var padLength uint8
   746  	if fh.Flags.Has(FlagHeadersPadded) {
   747  		if p, padLength, err = readByte(p); err != nil {
   748  			return
   749  		}
   750  	}
   751  	if fh.Flags.Has(FlagHeadersPriority) {
   752  		var v uint32
   753  		p, v, err = readUint32(p)
   754  		if err != nil {
   755  			return nil, err
   756  		}
   757  		hf.Priority.StreamDep = v & 0x7fffffff
   758  		hf.Priority.Exclusive = (v != hf.Priority.StreamDep) // high bit was set
   759  		p, hf.Priority.Weight, err = readByte(p)
   760  		if err != nil {
   761  			return nil, err
   762  		}
   763  	}
   764  	if len(p)-int(padLength) <= 0 {
   765  		return nil, StreamError{fh.StreamID, ErrCodeProtocol}
   766  	}
   767  	hf.headerFragBuf = p[:len(p)-int(padLength)]
   768  	return hf, nil
   769  }
   770  
   771  // HeadersFrameParam are the parameters for writing a HEADERS frame.
   772  type HeadersFrameParam struct {
   773  	// StreamID is the required Stream ID to initiate.
   774  	StreamID uint32
   775  	// BlockFragment is part (or all) of a Header Block.
   776  	BlockFragment []byte
   777  
   778  	// EndStream indicates that the header block is the last that
   779  	// the endpoint will send for the identified stream. Setting
   780  	// this flag causes the stream to enter one of "half closed"
   781  	// states.
   782  	EndStream bool
   783  
   784  	// EndHeaders indicates that this frame contains an entire
   785  	// header block and is not followed by any
   786  	// CONTINUATION frames.
   787  	EndHeaders bool
   788  
   789  	// PadLength is the optional number of bytes of zeros to add
   790  	// to this frame.
   791  	PadLength uint8
   792  
   793  	// Priority, if non-zero, includes stream priority information
   794  	// in the HEADER frame.
   795  	Priority PriorityParam
   796  }
   797  
   798  // WriteHeaders writes a single HEADERS frame.
   799  //
   800  // This is a low-level header writing method. Encoding headers and
   801  // splitting them into any necessary CONTINUATION frames is handled
   802  // elsewhere.
   803  //
   804  // It will perform exactly one Write to the underlying Writer.
   805  // It is the caller's responsibility to not call other Write methods concurrently.
   806  func (f *Framer) WriteHeaders(p HeadersFrameParam) error {
   807  	if !validStreamID(p.StreamID) && !f.AllowIllegalWrites {
   808  		return errStreamID
   809  	}
   810  	var flags Flags
   811  	if p.PadLength != 0 {
   812  		flags |= FlagHeadersPadded
   813  	}
   814  	if p.EndStream {
   815  		flags |= FlagHeadersEndStream
   816  	}
   817  	if p.EndHeaders {
   818  		flags |= FlagHeadersEndHeaders
   819  	}
   820  	if !p.Priority.IsZero() {
   821  		flags |= FlagHeadersPriority
   822  	}
   823  	f.startWrite(FrameHeaders, flags, p.StreamID)
   824  	if p.PadLength != 0 {
   825  		f.writeByte(p.PadLength)
   826  	}
   827  	if !p.Priority.IsZero() {
   828  		v := p.Priority.StreamDep
   829  		if !validStreamID(v) && !f.AllowIllegalWrites {
   830  			return errors.New("invalid dependent stream id")
   831  		}
   832  		if p.Priority.Exclusive {
   833  			v |= 1 << 31
   834  		}
   835  		f.writeUint32(v)
   836  		f.writeByte(p.Priority.Weight)
   837  	}
   838  	f.wbuf = append(f.wbuf, p.BlockFragment...)
   839  	f.wbuf = append(f.wbuf, padZeros[:p.PadLength]...)
   840  	return f.endWrite()
   841  }
   842  
   843  // A PriorityFrame specifies the sender-advised priority of a stream.
   844  // See http://http2.github.io/http2-spec/#rfc.section.6.3
   845  type PriorityFrame struct {
   846  	FrameHeader
   847  	PriorityParam
   848  }
   849  
   850  // PriorityParam are the stream prioritzation parameters.
   851  type PriorityParam struct {
   852  	// StreamDep is a 31-bit stream identifier for the
   853  	// stream that this stream depends on. Zero means no
   854  	// dependency.
   855  	StreamDep uint32
   856  
   857  	// Exclusive is whether the dependency is exclusive.
   858  	Exclusive bool
   859  
   860  	// Weight is the stream's zero-indexed weight. It should be
   861  	// set together with StreamDep, or neither should be set.  Per
   862  	// the spec, "Add one to the value to obtain a weight between
   863  	// 1 and 256."
   864  	Weight uint8
   865  }
   866  
   867  func (p PriorityParam) IsZero() bool {
   868  	return p == PriorityParam{}
   869  }
   870  
   871  func parsePriorityFrame(fh FrameHeader, payload []byte) (Frame, error) {
   872  	if fh.StreamID == 0 {
   873  		return nil, ConnectionError(ErrCodeProtocol)
   874  	}
   875  	if len(payload) != 5 {
   876  		return nil, ConnectionError(ErrCodeFrameSize)
   877  	}
   878  	v := binary.BigEndian.Uint32(payload[:4])
   879  	streamID := v & 0x7fffffff // mask off high bit
   880  	return &PriorityFrame{
   881  		FrameHeader: fh,
   882  		PriorityParam: PriorityParam{
   883  			Weight:    payload[4],
   884  			StreamDep: streamID,
   885  			Exclusive: streamID != v, // was high bit set?
   886  		},
   887  	}, nil
   888  }
   889  
   890  // WritePriority writes a PRIORITY frame.
   891  //
   892  // It will perform exactly one Write to the underlying Writer.
   893  // It is the caller's responsibility to not call other Write methods concurrently.
   894  func (f *Framer) WritePriority(streamID uint32, p PriorityParam) error {
   895  	if !validStreamID(streamID) && !f.AllowIllegalWrites {
   896  		return errStreamID
   897  	}
   898  	f.startWrite(FramePriority, 0, streamID)
   899  	v := p.StreamDep
   900  	if p.Exclusive {
   901  		v |= 1 << 31
   902  	}
   903  	f.writeUint32(v)
   904  	f.writeByte(p.Weight)
   905  	return f.endWrite()
   906  }
   907  
   908  // A RSTStreamFrame allows for abnormal termination of a stream.
   909  // See http://http2.github.io/http2-spec/#rfc.section.6.4
   910  type RSTStreamFrame struct {
   911  	FrameHeader
   912  	ErrCode ErrCode
   913  }
   914  
   915  func parseRSTStreamFrame(fh FrameHeader, p []byte) (Frame, error) {
   916  	if len(p) != 4 {
   917  		return nil, ConnectionError(ErrCodeFrameSize)
   918  	}
   919  	if fh.StreamID == 0 {
   920  		return nil, ConnectionError(ErrCodeProtocol)
   921  	}
   922  	return &RSTStreamFrame{fh, ErrCode(binary.BigEndian.Uint32(p[:4]))}, nil
   923  }
   924  
   925  // WriteRSTStream writes a RST_STREAM frame.
   926  //
   927  // It will perform exactly one Write to the underlying Writer.
   928  // It is the caller's responsibility to not call other Write methods concurrently.
   929  func (f *Framer) WriteRSTStream(streamID uint32, code ErrCode) error {
   930  	if !validStreamID(streamID) && !f.AllowIllegalWrites {
   931  		return errStreamID
   932  	}
   933  	f.startWrite(FrameRSTStream, 0, streamID)
   934  	f.writeUint32(uint32(code))
   935  	return f.endWrite()
   936  }
   937  
   938  // A ContinuationFrame is used to continue a sequence of header block fragments.
   939  // See http://http2.github.io/http2-spec/#rfc.section.6.10
   940  type ContinuationFrame struct {
   941  	FrameHeader
   942  	headerFragBuf []byte
   943  }
   944  
   945  func parseContinuationFrame(fh FrameHeader, p []byte) (Frame, error) {
   946  	return &ContinuationFrame{fh, p}, nil
   947  }
   948  
   949  func (f *ContinuationFrame) StreamEnded() bool {
   950  	return f.FrameHeader.Flags.Has(FlagDataEndStream)
   951  }
   952  
   953  func (f *ContinuationFrame) HeaderBlockFragment() []byte {
   954  	f.checkValid()
   955  	return f.headerFragBuf
   956  }
   957  
   958  func (f *ContinuationFrame) HeadersEnded() bool {
   959  	return f.FrameHeader.Flags.Has(FlagContinuationEndHeaders)
   960  }
   961  
   962  // WriteContinuation writes a CONTINUATION frame.
   963  //
   964  // It will perform exactly one Write to the underlying Writer.
   965  // It is the caller's responsibility to not call other Write methods concurrently.
   966  func (f *Framer) WriteContinuation(streamID uint32, endHeaders bool, headerBlockFragment []byte) error {
   967  	if !validStreamID(streamID) && !f.AllowIllegalWrites {
   968  		return errStreamID
   969  	}
   970  	var flags Flags
   971  	if endHeaders {
   972  		flags |= FlagContinuationEndHeaders
   973  	}
   974  	f.startWrite(FrameContinuation, flags, streamID)
   975  	f.wbuf = append(f.wbuf, headerBlockFragment...)
   976  	return f.endWrite()
   977  }
   978  
   979  // A PushPromiseFrame is used to initiate a server stream.
   980  // See http://http2.github.io/http2-spec/#rfc.section.6.6
   981  type PushPromiseFrame struct {
   982  	FrameHeader
   983  	PromiseID     uint32
   984  	headerFragBuf []byte // not owned
   985  }
   986  
   987  func (f *PushPromiseFrame) HeaderBlockFragment() []byte {
   988  	f.checkValid()
   989  	return f.headerFragBuf
   990  }
   991  
   992  func (f *PushPromiseFrame) HeadersEnded() bool {
   993  	return f.FrameHeader.Flags.Has(FlagPushPromiseEndHeaders)
   994  }
   995  
   996  func parsePushPromise(fh FrameHeader, p []byte) (_ Frame, err error) {
   997  	pp := &PushPromiseFrame{
   998  		FrameHeader: fh,
   999  	}
  1000  	if pp.StreamID == 0 {
  1001  		// PUSH_PROMISE frames MUST be associated with an existing,
  1002  		// peer-initiated stream. The stream identifier of a
  1003  		// PUSH_PROMISE frame indicates the stream it is associated
  1004  		// with. If the stream identifier field specifies the value
  1005  		// 0x0, a recipient MUST respond with a connection error
  1006  		// (Section 5.4.1) of type PROTOCOL_ERROR.
  1007  		return nil, ConnectionError(ErrCodeProtocol)
  1008  	}
  1009  	// The PUSH_PROMISE frame includes optional padding.
  1010  	// Padding fields and flags are identical to those defined for DATA frames
  1011  	var padLength uint8
  1012  	if fh.Flags.Has(FlagPushPromisePadded) {
  1013  		if p, padLength, err = readByte(p); err != nil {
  1014  			return
  1015  		}
  1016  	}
  1017  
  1018  	p, pp.PromiseID, err = readUint32(p)
  1019  	if err != nil {
  1020  		return
  1021  	}
  1022  	pp.PromiseID = pp.PromiseID & (1<<31 - 1)
  1023  
  1024  	if int(padLength) > len(p) {
  1025  		// like the DATA frame, error out if padding is longer than the body.
  1026  		return nil, ConnectionError(ErrCodeProtocol)
  1027  	}
  1028  	pp.headerFragBuf = p[:len(p)-int(padLength)]
  1029  	return pp, nil
  1030  }
  1031  
  1032  // PushPromiseParam are the parameters for writing a PUSH_PROMISE frame.
  1033  type PushPromiseParam struct {
  1034  	// StreamID is the required Stream ID to initiate.
  1035  	StreamID uint32
  1036  
  1037  	// PromiseID is the required Stream ID which this
  1038  	// Push Promises
  1039  	PromiseID uint32
  1040  
  1041  	// BlockFragment is part (or all) of a Header Block.
  1042  	BlockFragment []byte
  1043  
  1044  	// EndHeaders indicates that this frame contains an entire
  1045  	// header block and is not followed by any
  1046  	// CONTINUATION frames.
  1047  	EndHeaders bool
  1048  
  1049  	// PadLength is the optional number of bytes of zeros to add
  1050  	// to this frame.
  1051  	PadLength uint8
  1052  }
  1053  
  1054  // WritePushPromise writes a single PushPromise Frame.
  1055  //
  1056  // As with Header Frames, This is the low level call for writing
  1057  // individual frames. Continuation frames are handled elsewhere.
  1058  //
  1059  // It will perform exactly one Write to the underlying Writer.
  1060  // It is the caller's responsibility to not call other Write methods concurrently.
  1061  func (f *Framer) WritePushPromise(p PushPromiseParam) error {
  1062  	if !validStreamID(p.StreamID) && !f.AllowIllegalWrites {
  1063  		return errStreamID
  1064  	}
  1065  	var flags Flags
  1066  	if p.PadLength != 0 {
  1067  		flags |= FlagPushPromisePadded
  1068  	}
  1069  	if p.EndHeaders {
  1070  		flags |= FlagPushPromiseEndHeaders
  1071  	}
  1072  	f.startWrite(FramePushPromise, flags, p.StreamID)
  1073  	if p.PadLength != 0 {
  1074  		f.writeByte(p.PadLength)
  1075  	}
  1076  	if !validStreamID(p.PromiseID) && !f.AllowIllegalWrites {
  1077  		return errStreamID
  1078  	}
  1079  	f.writeUint32(p.PromiseID)
  1080  	f.wbuf = append(f.wbuf, p.BlockFragment...)
  1081  	f.wbuf = append(f.wbuf, padZeros[:p.PadLength]...)
  1082  	return f.endWrite()
  1083  }
  1084  
  1085  // WriteRawFrame writes a raw frame. This can be used to write
  1086  // extension frames unknown to this package.
  1087  func (f *Framer) WriteRawFrame(t FrameType, flags Flags, streamID uint32, payload []byte) error {
  1088  	f.startWrite(t, flags, streamID)
  1089  	f.writeBytes(payload)
  1090  	return f.endWrite()
  1091  }
  1092  
  1093  func readByte(p []byte) (remain []byte, b byte, err error) {
  1094  	if len(p) == 0 {
  1095  		return nil, 0, io.ErrUnexpectedEOF
  1096  	}
  1097  	return p[1:], p[0], nil
  1098  }
  1099  
  1100  func readUint32(p []byte) (remain []byte, v uint32, err error) {
  1101  	if len(p) < 4 {
  1102  		return nil, 0, io.ErrUnexpectedEOF
  1103  	}
  1104  	return p[4:], binary.BigEndian.Uint32(p[:4]), nil
  1105  }
  1106  
  1107  type streamEnder interface {
  1108  	StreamEnded() bool
  1109  }
  1110  
  1111  type headersEnder interface {
  1112  	HeadersEnded() bool
  1113  }