frame.go 30 KB

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