golang.org/x/net@v0.25.1-0.20240516223405-c87a5b62e243/http2/frame.go (about) 1 // Copyright 2014 The Go Authors. 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 http2 6 7 import ( 8 "bytes" 9 "encoding/binary" 10 "errors" 11 "fmt" 12 "io" 13 "log" 14 "strings" 15 "sync" 16 17 "golang.org/x/net/http/httpguts" 18 "golang.org/x/net/http2/hpack" 19 ) 20 21 const frameHeaderLen = 9 22 23 var padZeros = make([]byte, 255) // zeros for padding 24 25 // A FrameType is a registered frame type as defined in 26 // https://httpwg.org/specs/rfc7540.html#rfc.section.11.2 27 type FrameType uint8 28 29 const ( 30 FrameData FrameType = 0x0 31 FrameHeaders FrameType = 0x1 32 FramePriority FrameType = 0x2 33 FrameRSTStream FrameType = 0x3 34 FrameSettings FrameType = 0x4 35 FramePushPromise FrameType = 0x5 36 FramePing FrameType = 0x6 37 FrameGoAway FrameType = 0x7 38 FrameWindowUpdate FrameType = 0x8 39 FrameContinuation FrameType = 0x9 40 ) 41 42 var frameName = map[FrameType]string{ 43 FrameData: "DATA", 44 FrameHeaders: "HEADERS", 45 FramePriority: "PRIORITY", 46 FrameRSTStream: "RST_STREAM", 47 FrameSettings: "SETTINGS", 48 FramePushPromise: "PUSH_PROMISE", 49 FramePing: "PING", 50 FrameGoAway: "GOAWAY", 51 FrameWindowUpdate: "WINDOW_UPDATE", 52 FrameContinuation: "CONTINUATION", 53 } 54 55 func (t FrameType) String() string { 56 if s, ok := frameName[t]; ok { 57 return s 58 } 59 return fmt.Sprintf("UNKNOWN_FRAME_TYPE_%d", uint8(t)) 60 } 61 62 // Flags is a bitmask of HTTP/2 flags. 63 // The meaning of flags varies depending on the frame type. 64 type Flags uint8 65 66 // Has reports whether f contains all (0 or more) flags in v. 67 func (f Flags) Has(v Flags) bool { 68 return (f & v) == v 69 } 70 71 // Frame-specific FrameHeader flag bits. 72 const ( 73 // Data Frame 74 FlagDataEndStream Flags = 0x1 75 FlagDataPadded Flags = 0x8 76 77 // Headers Frame 78 FlagHeadersEndStream Flags = 0x1 79 FlagHeadersEndHeaders Flags = 0x4 80 FlagHeadersPadded Flags = 0x8 81 FlagHeadersPriority Flags = 0x20 82 83 // Settings Frame 84 FlagSettingsAck Flags = 0x1 85 86 // Ping Frame 87 FlagPingAck Flags = 0x1 88 89 // Continuation Frame 90 FlagContinuationEndHeaders Flags = 0x4 91 92 FlagPushPromiseEndHeaders Flags = 0x4 93 FlagPushPromisePadded Flags = 0x8 94 ) 95 96 var flagName = map[FrameType]map[Flags]string{ 97 FrameData: { 98 FlagDataEndStream: "END_STREAM", 99 FlagDataPadded: "PADDED", 100 }, 101 FrameHeaders: { 102 FlagHeadersEndStream: "END_STREAM", 103 FlagHeadersEndHeaders: "END_HEADERS", 104 FlagHeadersPadded: "PADDED", 105 FlagHeadersPriority: "PRIORITY", 106 }, 107 FrameSettings: { 108 FlagSettingsAck: "ACK", 109 }, 110 FramePing: { 111 FlagPingAck: "ACK", 112 }, 113 FrameContinuation: { 114 FlagContinuationEndHeaders: "END_HEADERS", 115 }, 116 FramePushPromise: { 117 FlagPushPromiseEndHeaders: "END_HEADERS", 118 FlagPushPromisePadded: "PADDED", 119 }, 120 } 121 122 // a frameParser parses a frame given its FrameHeader and payload 123 // bytes. The length of payload will always equal fh.Length (which 124 // might be 0). 125 type frameParser func(fc *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error) 126 127 var frameParsers = map[FrameType]frameParser{ 128 FrameData: parseDataFrame, 129 FrameHeaders: parseHeadersFrame, 130 FramePriority: parsePriorityFrame, 131 FrameRSTStream: parseRSTStreamFrame, 132 FrameSettings: parseSettingsFrame, 133 FramePushPromise: parsePushPromise, 134 FramePing: parsePingFrame, 135 FrameGoAway: parseGoAwayFrame, 136 FrameWindowUpdate: parseWindowUpdateFrame, 137 FrameContinuation: parseContinuationFrame, 138 } 139 140 func typeFrameParser(t FrameType) frameParser { 141 if f := frameParsers[t]; f != nil { 142 return f 143 } 144 return parseUnknownFrame 145 } 146 147 // A FrameHeader is the 9 byte header of all HTTP/2 frames. 148 // 149 // See https://httpwg.org/specs/rfc7540.html#FrameHeader 150 type FrameHeader struct { 151 valid bool // caller can access []byte fields in the Frame 152 153 // Type is the 1 byte frame type. There are ten standard frame 154 // types, but extension frame types may be written by WriteRawFrame 155 // and will be returned by ReadFrame (as UnknownFrame). 156 Type FrameType 157 158 // Flags are the 1 byte of 8 potential bit flags per frame. 159 // They are specific to the frame type. 160 Flags Flags 161 162 // Length is the length of the frame, not including the 9 byte header. 163 // The maximum size is one byte less than 16MB (uint24), but only 164 // frames up to 16KB are allowed without peer agreement. 165 Length uint32 166 167 // StreamID is which stream this frame is for. Certain frames 168 // are not stream-specific, in which case this field is 0. 169 StreamID uint32 170 } 171 172 // Header returns h. It exists so FrameHeaders can be embedded in other 173 // specific frame types and implement the Frame interface. 174 func (h FrameHeader) Header() FrameHeader { return h } 175 176 func (h FrameHeader) String() string { 177 var buf bytes.Buffer 178 buf.WriteString("[FrameHeader ") 179 h.writeDebug(&buf) 180 buf.WriteByte(']') 181 return buf.String() 182 } 183 184 func (h FrameHeader) writeDebug(buf *bytes.Buffer) { 185 buf.WriteString(h.Type.String()) 186 if h.Flags != 0 { 187 buf.WriteString(" flags=") 188 set := 0 189 for i := uint8(0); i < 8; i++ { 190 if h.Flags&(1<<i) == 0 { 191 continue 192 } 193 set++ 194 if set > 1 { 195 buf.WriteByte('|') 196 } 197 name := flagName[h.Type][Flags(1<<i)] 198 if name != "" { 199 buf.WriteString(name) 200 } else { 201 fmt.Fprintf(buf, "0x%x", 1<<i) 202 } 203 } 204 } 205 if h.StreamID != 0 { 206 fmt.Fprintf(buf, " stream=%d", h.StreamID) 207 } 208 fmt.Fprintf(buf, " len=%d", h.Length) 209 } 210 211 func (h *FrameHeader) checkValid() { 212 if !h.valid { 213 panic("Frame accessor called on non-owned Frame") 214 } 215 } 216 217 func (h *FrameHeader) invalidate() { h.valid = false } 218 219 // frame header bytes. 220 // Used only by ReadFrameHeader. 221 var fhBytes = sync.Pool{ 222 New: func() interface{} { 223 buf := make([]byte, frameHeaderLen) 224 return &buf 225 }, 226 } 227 228 // ReadFrameHeader reads 9 bytes from r and returns a FrameHeader. 229 // Most users should use Framer.ReadFrame instead. 230 func ReadFrameHeader(r io.Reader) (FrameHeader, error) { 231 bufp := fhBytes.Get().(*[]byte) 232 defer fhBytes.Put(bufp) 233 return readFrameHeader(*bufp, r) 234 } 235 236 func readFrameHeader(buf []byte, r io.Reader) (FrameHeader, error) { 237 _, err := io.ReadFull(r, buf[:frameHeaderLen]) 238 if err != nil { 239 return FrameHeader{}, err 240 } 241 return FrameHeader{ 242 Length: (uint32(buf[0])<<16 | uint32(buf[1])<<8 | uint32(buf[2])), 243 Type: FrameType(buf[3]), 244 Flags: Flags(buf[4]), 245 StreamID: binary.BigEndian.Uint32(buf[5:]) & (1<<31 - 1), 246 valid: true, 247 }, nil 248 } 249 250 // A Frame is the base interface implemented by all frame types. 251 // Callers will generally type-assert the specific frame type: 252 // *HeadersFrame, *SettingsFrame, *WindowUpdateFrame, etc. 253 // 254 // Frames are only valid until the next call to Framer.ReadFrame. 255 type Frame interface { 256 Header() FrameHeader 257 258 // invalidate is called by Framer.ReadFrame to make this 259 // frame's buffers as being invalid, since the subsequent 260 // frame will reuse them. 261 invalidate() 262 } 263 264 // A Framer reads and writes Frames. 265 type Framer struct { 266 r io.Reader 267 lastFrame Frame 268 errDetail error 269 270 // countError is a non-nil func that's called on a frame parse 271 // error with some unique error path token. It's initialized 272 // from Transport.CountError or Server.CountError. 273 countError func(errToken string) 274 275 // lastHeaderStream is non-zero if the last frame was an 276 // unfinished HEADERS/CONTINUATION. 277 lastHeaderStream uint32 278 279 maxReadSize uint32 280 headerBuf [frameHeaderLen]byte 281 282 // TODO: let getReadBuf be configurable, and use a less memory-pinning 283 // allocator in server.go to minimize memory pinned for many idle conns. 284 // Will probably also need to make frame invalidation have a hook too. 285 getReadBuf func(size uint32) []byte 286 readBuf []byte // cache for default getReadBuf 287 288 maxWriteSize uint32 // zero means unlimited; TODO: implement 289 290 w io.Writer 291 wbuf []byte 292 293 // AllowIllegalWrites permits the Framer's Write methods to 294 // write frames that do not conform to the HTTP/2 spec. This 295 // permits using the Framer to test other HTTP/2 296 // implementations' conformance to the spec. 297 // If false, the Write methods will prefer to return an error 298 // rather than comply. 299 AllowIllegalWrites bool 300 301 // AllowIllegalReads permits the Framer's ReadFrame method 302 // to return non-compliant frames or frame orders. 303 // This is for testing and permits using the Framer to test 304 // other HTTP/2 implementations' conformance to the spec. 305 // It is not compatible with ReadMetaHeaders. 306 AllowIllegalReads bool 307 308 // ReadMetaHeaders if non-nil causes ReadFrame to merge 309 // HEADERS and CONTINUATION frames together and return 310 // MetaHeadersFrame instead. 311 ReadMetaHeaders *hpack.Decoder 312 313 // MaxHeaderListSize is the http2 MAX_HEADER_LIST_SIZE. 314 // It's used only if ReadMetaHeaders is set; 0 means a sane default 315 // (currently 16MB) 316 // If the limit is hit, MetaHeadersFrame.Truncated is set true. 317 MaxHeaderListSize uint32 318 319 // TODO: track which type of frame & with which flags was sent 320 // last. Then return an error (unless AllowIllegalWrites) if 321 // we're in the middle of a header block and a 322 // non-Continuation or Continuation on a different stream is 323 // attempted to be written. 324 325 logReads, logWrites bool 326 327 debugFramer *Framer // only use for logging written writes 328 debugFramerBuf *bytes.Buffer 329 debugReadLoggerf func(string, ...interface{}) 330 debugWriteLoggerf func(string, ...interface{}) 331 332 frameCache *frameCache // nil if frames aren't reused (default) 333 } 334 335 func (fr *Framer) maxHeaderListSize() uint32 { 336 if fr.MaxHeaderListSize == 0 { 337 return 16 << 20 // sane default, per docs 338 } 339 return fr.MaxHeaderListSize 340 } 341 342 func (f *Framer) startWrite(ftype FrameType, flags Flags, streamID uint32) { 343 // Write the FrameHeader. 344 f.wbuf = append(f.wbuf[:0], 345 0, // 3 bytes of length, filled in in endWrite 346 0, 347 0, 348 byte(ftype), 349 byte(flags), 350 byte(streamID>>24), 351 byte(streamID>>16), 352 byte(streamID>>8), 353 byte(streamID)) 354 } 355 356 func (f *Framer) endWrite() error { 357 // Now that we know the final size, fill in the FrameHeader in 358 // the space previously reserved for it. Abuse append. 359 length := len(f.wbuf) - frameHeaderLen 360 if length >= (1 << 24) { 361 return ErrFrameTooLarge 362 } 363 _ = append(f.wbuf[:0], 364 byte(length>>16), 365 byte(length>>8), 366 byte(length)) 367 if f.logWrites { 368 f.logWrite() 369 } 370 371 n, err := f.w.Write(f.wbuf) 372 if err == nil && n != len(f.wbuf) { 373 err = io.ErrShortWrite 374 } 375 return err 376 } 377 378 func (f *Framer) logWrite() { 379 if f.debugFramer == nil { 380 f.debugFramerBuf = new(bytes.Buffer) 381 f.debugFramer = NewFramer(nil, f.debugFramerBuf) 382 f.debugFramer.logReads = false // we log it ourselves, saying "wrote" below 383 // Let us read anything, even if we accidentally wrote it 384 // in the wrong order: 385 f.debugFramer.AllowIllegalReads = true 386 } 387 f.debugFramerBuf.Write(f.wbuf) 388 fr, err := f.debugFramer.ReadFrame() 389 if err != nil { 390 f.debugWriteLoggerf("http2: Framer %p: failed to decode just-written frame", f) 391 return 392 } 393 f.debugWriteLoggerf("http2: Framer %p: wrote %v", f, summarizeFrame(fr)) 394 } 395 396 func (f *Framer) writeByte(v byte) { f.wbuf = append(f.wbuf, v) } 397 func (f *Framer) writeBytes(v []byte) { f.wbuf = append(f.wbuf, v...) } 398 func (f *Framer) writeUint16(v uint16) { f.wbuf = append(f.wbuf, byte(v>>8), byte(v)) } 399 func (f *Framer) writeUint32(v uint32) { 400 f.wbuf = append(f.wbuf, byte(v>>24), byte(v>>16), byte(v>>8), byte(v)) 401 } 402 403 const ( 404 minMaxFrameSize = 1 << 14 405 maxFrameSize = 1<<24 - 1 406 ) 407 408 // SetReuseFrames allows the Framer to reuse Frames. 409 // If called on a Framer, Frames returned by calls to ReadFrame are only 410 // valid until the next call to ReadFrame. 411 func (fr *Framer) SetReuseFrames() { 412 if fr.frameCache != nil { 413 return 414 } 415 fr.frameCache = &frameCache{} 416 } 417 418 type frameCache struct { 419 dataFrame DataFrame 420 } 421 422 func (fc *frameCache) getDataFrame() *DataFrame { 423 if fc == nil { 424 return &DataFrame{} 425 } 426 return &fc.dataFrame 427 } 428 429 // NewFramer returns a Framer that writes frames to w and reads them from r. 430 func NewFramer(w io.Writer, r io.Reader) *Framer { 431 fr := &Framer{ 432 w: w, 433 r: r, 434 countError: func(string) {}, 435 logReads: logFrameReads, 436 logWrites: logFrameWrites, 437 debugReadLoggerf: log.Printf, 438 debugWriteLoggerf: log.Printf, 439 } 440 fr.getReadBuf = func(size uint32) []byte { 441 if cap(fr.readBuf) >= int(size) { 442 return fr.readBuf[:size] 443 } 444 fr.readBuf = make([]byte, size) 445 return fr.readBuf 446 } 447 fr.SetMaxReadFrameSize(maxFrameSize) 448 return fr 449 } 450 451 // SetMaxReadFrameSize sets the maximum size of a frame 452 // that will be read by a subsequent call to ReadFrame. 453 // It is the caller's responsibility to advertise this 454 // limit with a SETTINGS frame. 455 func (fr *Framer) SetMaxReadFrameSize(v uint32) { 456 if v > maxFrameSize { 457 v = maxFrameSize 458 } 459 fr.maxReadSize = v 460 } 461 462 // ErrorDetail returns a more detailed error of the last error 463 // returned by Framer.ReadFrame. For instance, if ReadFrame 464 // returns a StreamError with code PROTOCOL_ERROR, ErrorDetail 465 // will say exactly what was invalid. ErrorDetail is not guaranteed 466 // to return a non-nil value and like the rest of the http2 package, 467 // its return value is not protected by an API compatibility promise. 468 // ErrorDetail is reset after the next call to ReadFrame. 469 func (fr *Framer) ErrorDetail() error { 470 return fr.errDetail 471 } 472 473 // ErrFrameTooLarge is returned from Framer.ReadFrame when the peer 474 // sends a frame that is larger than declared with SetMaxReadFrameSize. 475 var ErrFrameTooLarge = errors.New("http2: frame too large") 476 477 // terminalReadFrameError reports whether err is an unrecoverable 478 // error from ReadFrame and no other frames should be read. 479 func terminalReadFrameError(err error) bool { 480 if _, ok := err.(StreamError); ok { 481 return false 482 } 483 return err != nil 484 } 485 486 // ReadFrame reads a single frame. The returned Frame is only valid 487 // until the next call to ReadFrame. 488 // 489 // If the frame is larger than previously set with SetMaxReadFrameSize, the 490 // returned error is ErrFrameTooLarge. Other errors may be of type 491 // ConnectionError, StreamError, or anything else from the underlying 492 // reader. 493 // 494 // If ReadFrame returns an error and a non-nil Frame, the Frame's StreamID 495 // indicates the stream responsible for the error. 496 func (fr *Framer) ReadFrame() (Frame, error) { 497 fr.errDetail = nil 498 if fr.lastFrame != nil { 499 fr.lastFrame.invalidate() 500 } 501 fh, err := readFrameHeader(fr.headerBuf[:], fr.r) 502 if err != nil { 503 return nil, err 504 } 505 if fh.Length > fr.maxReadSize { 506 return nil, ErrFrameTooLarge 507 } 508 payload := fr.getReadBuf(fh.Length) 509 if _, err := io.ReadFull(fr.r, payload); err != nil { 510 return nil, err 511 } 512 f, err := typeFrameParser(fh.Type)(fr.frameCache, fh, fr.countError, payload) 513 if err != nil { 514 if ce, ok := err.(connError); ok { 515 return nil, fr.connError(ce.Code, ce.Reason) 516 } 517 return nil, err 518 } 519 if err := fr.checkFrameOrder(f); err != nil { 520 return nil, err 521 } 522 if fr.logReads { 523 fr.debugReadLoggerf("http2: Framer %p: read %v", fr, summarizeFrame(f)) 524 } 525 if fh.Type == FrameHeaders && fr.ReadMetaHeaders != nil { 526 return fr.readMetaFrame(f.(*HeadersFrame)) 527 } 528 return f, nil 529 } 530 531 // connError returns ConnectionError(code) but first 532 // stashes away a public reason to the caller can optionally relay it 533 // to the peer before hanging up on them. This might help others debug 534 // their implementations. 535 func (fr *Framer) connError(code ErrCode, reason string) error { 536 fr.errDetail = errors.New(reason) 537 return ConnectionError(code) 538 } 539 540 // checkFrameOrder reports an error if f is an invalid frame to return 541 // next from ReadFrame. Mostly it checks whether HEADERS and 542 // CONTINUATION frames are contiguous. 543 func (fr *Framer) checkFrameOrder(f Frame) error { 544 last := fr.lastFrame 545 fr.lastFrame = f 546 if fr.AllowIllegalReads { 547 return nil 548 } 549 550 fh := f.Header() 551 if fr.lastHeaderStream != 0 { 552 if fh.Type != FrameContinuation { 553 return fr.connError(ErrCodeProtocol, 554 fmt.Sprintf("got %s for stream %d; expected CONTINUATION following %s for stream %d", 555 fh.Type, fh.StreamID, 556 last.Header().Type, fr.lastHeaderStream)) 557 } 558 if fh.StreamID != fr.lastHeaderStream { 559 return fr.connError(ErrCodeProtocol, 560 fmt.Sprintf("got CONTINUATION for stream %d; expected stream %d", 561 fh.StreamID, fr.lastHeaderStream)) 562 } 563 } else if fh.Type == FrameContinuation { 564 return fr.connError(ErrCodeProtocol, fmt.Sprintf("unexpected CONTINUATION for stream %d", fh.StreamID)) 565 } 566 567 switch fh.Type { 568 case FrameHeaders, FrameContinuation: 569 if fh.Flags.Has(FlagHeadersEndHeaders) { 570 fr.lastHeaderStream = 0 571 } else { 572 fr.lastHeaderStream = fh.StreamID 573 } 574 } 575 576 return nil 577 } 578 579 // A DataFrame conveys arbitrary, variable-length sequences of octets 580 // associated with a stream. 581 // See https://httpwg.org/specs/rfc7540.html#rfc.section.6.1 582 type DataFrame struct { 583 FrameHeader 584 data []byte 585 } 586 587 func (f *DataFrame) StreamEnded() bool { 588 return f.FrameHeader.Flags.Has(FlagDataEndStream) 589 } 590 591 // Data returns the frame's data octets, not including any padding 592 // size byte or padding suffix bytes. 593 // The caller must not retain the returned memory past the next 594 // call to ReadFrame. 595 func (f *DataFrame) Data() []byte { 596 f.checkValid() 597 return f.data 598 } 599 600 func parseDataFrame(fc *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error) { 601 if fh.StreamID == 0 { 602 // DATA frames MUST be associated with a stream. If a 603 // DATA frame is received whose stream identifier 604 // field is 0x0, the recipient MUST respond with a 605 // connection error (Section 5.4.1) of type 606 // PROTOCOL_ERROR. 607 countError("frame_data_stream_0") 608 return nil, connError{ErrCodeProtocol, "DATA frame with stream ID 0"} 609 } 610 f := fc.getDataFrame() 611 f.FrameHeader = fh 612 613 var padSize byte 614 if fh.Flags.Has(FlagDataPadded) { 615 var err error 616 payload, padSize, err = readByte(payload) 617 if err != nil { 618 countError("frame_data_pad_byte_short") 619 return nil, err 620 } 621 } 622 if int(padSize) > len(payload) { 623 // If the length of the padding is greater than the 624 // length of the frame payload, the recipient MUST 625 // treat this as a connection error. 626 // Filed: https://github.com/http2/http2-spec/issues/610 627 countError("frame_data_pad_too_big") 628 return nil, connError{ErrCodeProtocol, "pad size larger than data payload"} 629 } 630 f.data = payload[:len(payload)-int(padSize)] 631 return f, nil 632 } 633 634 var ( 635 errStreamID = errors.New("invalid stream ID") 636 errDepStreamID = errors.New("invalid dependent stream ID") 637 errPadLength = errors.New("pad length too large") 638 errPadBytes = errors.New("padding bytes must all be zeros unless AllowIllegalWrites is enabled") 639 ) 640 641 func validStreamIDOrZero(streamID uint32) bool { 642 return streamID&(1<<31) == 0 643 } 644 645 func validStreamID(streamID uint32) bool { 646 return streamID != 0 && streamID&(1<<31) == 0 647 } 648 649 // WriteData writes a DATA frame. 650 // 651 // It will perform exactly one Write to the underlying Writer. 652 // It is the caller's responsibility not to violate the maximum frame size 653 // and to not call other Write methods concurrently. 654 func (f *Framer) WriteData(streamID uint32, endStream bool, data []byte) error { 655 return f.WriteDataPadded(streamID, endStream, data, nil) 656 } 657 658 // WriteDataPadded writes a DATA frame with optional padding. 659 // 660 // If pad is nil, the padding bit is not sent. 661 // The length of pad must not exceed 255 bytes. 662 // The bytes of pad must all be zero, unless f.AllowIllegalWrites is set. 663 // 664 // It will perform exactly one Write to the underlying Writer. 665 // It is the caller's responsibility not to violate the maximum frame size 666 // and to not call other Write methods concurrently. 667 func (f *Framer) WriteDataPadded(streamID uint32, endStream bool, data, pad []byte) error { 668 if err := f.startWriteDataPadded(streamID, endStream, data, pad); err != nil { 669 return err 670 } 671 return f.endWrite() 672 } 673 674 // startWriteDataPadded is WriteDataPadded, but only writes the frame to the Framer's internal buffer. 675 // The caller should call endWrite to flush the frame to the underlying writer. 676 func (f *Framer) startWriteDataPadded(streamID uint32, endStream bool, data, pad []byte) error { 677 if !validStreamID(streamID) && !f.AllowIllegalWrites { 678 return errStreamID 679 } 680 if len(pad) > 0 { 681 if len(pad) > 255 { 682 return errPadLength 683 } 684 if !f.AllowIllegalWrites { 685 for _, b := range pad { 686 if b != 0 { 687 // "Padding octets MUST be set to zero when sending." 688 return errPadBytes 689 } 690 } 691 } 692 } 693 var flags Flags 694 if endStream { 695 flags |= FlagDataEndStream 696 } 697 if pad != nil { 698 flags |= FlagDataPadded 699 } 700 f.startWrite(FrameData, flags, streamID) 701 if pad != nil { 702 f.wbuf = append(f.wbuf, byte(len(pad))) 703 } 704 f.wbuf = append(f.wbuf, data...) 705 f.wbuf = append(f.wbuf, pad...) 706 return nil 707 } 708 709 // A SettingsFrame conveys configuration parameters that affect how 710 // endpoints communicate, such as preferences and constraints on peer 711 // behavior. 712 // 713 // See https://httpwg.org/specs/rfc7540.html#SETTINGS 714 type SettingsFrame struct { 715 FrameHeader 716 p []byte 717 } 718 719 func parseSettingsFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) { 720 if fh.Flags.Has(FlagSettingsAck) && fh.Length > 0 { 721 // When this (ACK 0x1) bit is set, the payload of the 722 // SETTINGS frame MUST be empty. Receipt of a 723 // SETTINGS frame with the ACK flag set and a length 724 // field value other than 0 MUST be treated as a 725 // connection error (Section 5.4.1) of type 726 // FRAME_SIZE_ERROR. 727 countError("frame_settings_ack_with_length") 728 return nil, ConnectionError(ErrCodeFrameSize) 729 } 730 if fh.StreamID != 0 { 731 // SETTINGS frames always apply to a connection, 732 // never a single stream. The stream identifier for a 733 // SETTINGS frame MUST be zero (0x0). If an endpoint 734 // receives a SETTINGS frame whose stream identifier 735 // field is anything other than 0x0, the endpoint MUST 736 // respond with a connection error (Section 5.4.1) of 737 // type PROTOCOL_ERROR. 738 countError("frame_settings_has_stream") 739 return nil, ConnectionError(ErrCodeProtocol) 740 } 741 if len(p)%6 != 0 { 742 countError("frame_settings_mod_6") 743 // Expecting even number of 6 byte settings. 744 return nil, ConnectionError(ErrCodeFrameSize) 745 } 746 f := &SettingsFrame{FrameHeader: fh, p: p} 747 if v, ok := f.Value(SettingInitialWindowSize); ok && v > (1<<31)-1 { 748 countError("frame_settings_window_size_too_big") 749 // Values above the maximum flow control window size of 2^31 - 1 MUST 750 // be treated as a connection error (Section 5.4.1) of type 751 // FLOW_CONTROL_ERROR. 752 return nil, ConnectionError(ErrCodeFlowControl) 753 } 754 return f, nil 755 } 756 757 func (f *SettingsFrame) IsAck() bool { 758 return f.FrameHeader.Flags.Has(FlagSettingsAck) 759 } 760 761 func (f *SettingsFrame) Value(id SettingID) (v uint32, ok bool) { 762 f.checkValid() 763 for i := 0; i < f.NumSettings(); i++ { 764 if s := f.Setting(i); s.ID == id { 765 return s.Val, true 766 } 767 } 768 return 0, false 769 } 770 771 // Setting returns the setting from the frame at the given 0-based index. 772 // The index must be >= 0 and less than f.NumSettings(). 773 func (f *SettingsFrame) Setting(i int) Setting { 774 buf := f.p 775 return Setting{ 776 ID: SettingID(binary.BigEndian.Uint16(buf[i*6 : i*6+2])), 777 Val: binary.BigEndian.Uint32(buf[i*6+2 : i*6+6]), 778 } 779 } 780 781 func (f *SettingsFrame) NumSettings() int { return len(f.p) / 6 } 782 783 // HasDuplicates reports whether f contains any duplicate setting IDs. 784 func (f *SettingsFrame) HasDuplicates() bool { 785 num := f.NumSettings() 786 if num == 0 { 787 return false 788 } 789 // If it's small enough (the common case), just do the n^2 790 // thing and avoid a map allocation. 791 if num < 10 { 792 for i := 0; i < num; i++ { 793 idi := f.Setting(i).ID 794 for j := i + 1; j < num; j++ { 795 idj := f.Setting(j).ID 796 if idi == idj { 797 return true 798 } 799 } 800 } 801 return false 802 } 803 seen := map[SettingID]bool{} 804 for i := 0; i < num; i++ { 805 id := f.Setting(i).ID 806 if seen[id] { 807 return true 808 } 809 seen[id] = true 810 } 811 return false 812 } 813 814 // ForeachSetting runs fn for each setting. 815 // It stops and returns the first error. 816 func (f *SettingsFrame) ForeachSetting(fn func(Setting) error) error { 817 f.checkValid() 818 for i := 0; i < f.NumSettings(); i++ { 819 if err := fn(f.Setting(i)); err != nil { 820 return err 821 } 822 } 823 return nil 824 } 825 826 // WriteSettings writes a SETTINGS frame with zero or more settings 827 // specified and the ACK bit not set. 828 // 829 // It will perform exactly one Write to the underlying Writer. 830 // It is the caller's responsibility to not call other Write methods concurrently. 831 func (f *Framer) WriteSettings(settings ...Setting) error { 832 f.startWrite(FrameSettings, 0, 0) 833 for _, s := range settings { 834 f.writeUint16(uint16(s.ID)) 835 f.writeUint32(s.Val) 836 } 837 return f.endWrite() 838 } 839 840 // WriteSettingsAck writes an empty SETTINGS frame with the ACK bit set. 841 // 842 // It will perform exactly one Write to the underlying Writer. 843 // It is the caller's responsibility to not call other Write methods concurrently. 844 func (f *Framer) WriteSettingsAck() error { 845 f.startWrite(FrameSettings, FlagSettingsAck, 0) 846 return f.endWrite() 847 } 848 849 // A PingFrame is a mechanism for measuring a minimal round trip time 850 // from the sender, as well as determining whether an idle connection 851 // is still functional. 852 // See https://httpwg.org/specs/rfc7540.html#rfc.section.6.7 853 type PingFrame struct { 854 FrameHeader 855 Data [8]byte 856 } 857 858 func (f *PingFrame) IsAck() bool { return f.Flags.Has(FlagPingAck) } 859 860 func parsePingFrame(_ *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error) { 861 if len(payload) != 8 { 862 countError("frame_ping_length") 863 return nil, ConnectionError(ErrCodeFrameSize) 864 } 865 if fh.StreamID != 0 { 866 countError("frame_ping_has_stream") 867 return nil, ConnectionError(ErrCodeProtocol) 868 } 869 f := &PingFrame{FrameHeader: fh} 870 copy(f.Data[:], payload) 871 return f, nil 872 } 873 874 func (f *Framer) WritePing(ack bool, data [8]byte) error { 875 var flags Flags 876 if ack { 877 flags = FlagPingAck 878 } 879 f.startWrite(FramePing, flags, 0) 880 f.writeBytes(data[:]) 881 return f.endWrite() 882 } 883 884 // A GoAwayFrame informs the remote peer to stop creating streams on this connection. 885 // See https://httpwg.org/specs/rfc7540.html#rfc.section.6.8 886 type GoAwayFrame struct { 887 FrameHeader 888 LastStreamID uint32 889 ErrCode ErrCode 890 debugData []byte 891 } 892 893 // DebugData returns any debug data in the GOAWAY frame. Its contents 894 // are not defined. 895 // The caller must not retain the returned memory past the next 896 // call to ReadFrame. 897 func (f *GoAwayFrame) DebugData() []byte { 898 f.checkValid() 899 return f.debugData 900 } 901 902 func parseGoAwayFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) { 903 if fh.StreamID != 0 { 904 countError("frame_goaway_has_stream") 905 return nil, ConnectionError(ErrCodeProtocol) 906 } 907 if len(p) < 8 { 908 countError("frame_goaway_short") 909 return nil, ConnectionError(ErrCodeFrameSize) 910 } 911 return &GoAwayFrame{ 912 FrameHeader: fh, 913 LastStreamID: binary.BigEndian.Uint32(p[:4]) & (1<<31 - 1), 914 ErrCode: ErrCode(binary.BigEndian.Uint32(p[4:8])), 915 debugData: p[8:], 916 }, nil 917 } 918 919 func (f *Framer) WriteGoAway(maxStreamID uint32, code ErrCode, debugData []byte) error { 920 f.startWrite(FrameGoAway, 0, 0) 921 f.writeUint32(maxStreamID & (1<<31 - 1)) 922 f.writeUint32(uint32(code)) 923 f.writeBytes(debugData) 924 return f.endWrite() 925 } 926 927 // An UnknownFrame is the frame type returned when the frame type is unknown 928 // or no specific frame type parser exists. 929 type UnknownFrame struct { 930 FrameHeader 931 p []byte 932 } 933 934 // Payload returns the frame's payload (after the header). It is not 935 // valid to call this method after a subsequent call to 936 // Framer.ReadFrame, nor is it valid to retain the returned slice. 937 // The memory is owned by the Framer and is invalidated when the next 938 // frame is read. 939 func (f *UnknownFrame) Payload() []byte { 940 f.checkValid() 941 return f.p 942 } 943 944 func parseUnknownFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) { 945 return &UnknownFrame{fh, p}, nil 946 } 947 948 // A WindowUpdateFrame is used to implement flow control. 949 // See https://httpwg.org/specs/rfc7540.html#rfc.section.6.9 950 type WindowUpdateFrame struct { 951 FrameHeader 952 Increment uint32 // never read with high bit set 953 } 954 955 func parseWindowUpdateFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) { 956 if len(p) != 4 { 957 countError("frame_windowupdate_bad_len") 958 return nil, ConnectionError(ErrCodeFrameSize) 959 } 960 inc := binary.BigEndian.Uint32(p[:4]) & 0x7fffffff // mask off high reserved bit 961 if inc == 0 { 962 // A receiver MUST treat the receipt of a 963 // WINDOW_UPDATE frame with an flow control window 964 // increment of 0 as a stream error (Section 5.4.2) of 965 // type PROTOCOL_ERROR; errors on the connection flow 966 // control window MUST be treated as a connection 967 // error (Section 5.4.1). 968 if fh.StreamID == 0 { 969 countError("frame_windowupdate_zero_inc_conn") 970 return nil, ConnectionError(ErrCodeProtocol) 971 } 972 countError("frame_windowupdate_zero_inc_stream") 973 return nil, streamError(fh.StreamID, ErrCodeProtocol) 974 } 975 return &WindowUpdateFrame{ 976 FrameHeader: fh, 977 Increment: inc, 978 }, nil 979 } 980 981 // WriteWindowUpdate writes a WINDOW_UPDATE frame. 982 // The increment value must be between 1 and 2,147,483,647, inclusive. 983 // If the Stream ID is zero, the window update applies to the 984 // connection as a whole. 985 func (f *Framer) WriteWindowUpdate(streamID, incr uint32) error { 986 // "The legal range for the increment to the flow control window is 1 to 2^31-1 (2,147,483,647) octets." 987 if (incr < 1 || incr > 2147483647) && !f.AllowIllegalWrites { 988 return errors.New("illegal window increment value") 989 } 990 f.startWrite(FrameWindowUpdate, 0, streamID) 991 f.writeUint32(incr) 992 return f.endWrite() 993 } 994 995 // A HeadersFrame is used to open a stream and additionally carries a 996 // header block fragment. 997 type HeadersFrame struct { 998 FrameHeader 999 1000 // Priority is set if FlagHeadersPriority is set in the FrameHeader. 1001 Priority PriorityParam 1002 1003 headerFragBuf []byte // not owned 1004 } 1005 1006 func (f *HeadersFrame) HeaderBlockFragment() []byte { 1007 f.checkValid() 1008 return f.headerFragBuf 1009 } 1010 1011 func (f *HeadersFrame) HeadersEnded() bool { 1012 return f.FrameHeader.Flags.Has(FlagHeadersEndHeaders) 1013 } 1014 1015 func (f *HeadersFrame) StreamEnded() bool { 1016 return f.FrameHeader.Flags.Has(FlagHeadersEndStream) 1017 } 1018 1019 func (f *HeadersFrame) HasPriority() bool { 1020 return f.FrameHeader.Flags.Has(FlagHeadersPriority) 1021 } 1022 1023 func parseHeadersFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (_ Frame, err error) { 1024 hf := &HeadersFrame{ 1025 FrameHeader: fh, 1026 } 1027 if fh.StreamID == 0 { 1028 // HEADERS frames MUST be associated with a stream. If a HEADERS frame 1029 // is received whose stream identifier field is 0x0, the recipient MUST 1030 // respond with a connection error (Section 5.4.1) of type 1031 // PROTOCOL_ERROR. 1032 countError("frame_headers_zero_stream") 1033 return nil, connError{ErrCodeProtocol, "HEADERS frame with stream ID 0"} 1034 } 1035 var padLength uint8 1036 if fh.Flags.Has(FlagHeadersPadded) { 1037 if p, padLength, err = readByte(p); err != nil { 1038 countError("frame_headers_pad_short") 1039 return 1040 } 1041 } 1042 if fh.Flags.Has(FlagHeadersPriority) { 1043 var v uint32 1044 p, v, err = readUint32(p) 1045 if err != nil { 1046 countError("frame_headers_prio_short") 1047 return nil, err 1048 } 1049 hf.Priority.StreamDep = v & 0x7fffffff 1050 hf.Priority.Exclusive = (v != hf.Priority.StreamDep) // high bit was set 1051 p, hf.Priority.Weight, err = readByte(p) 1052 if err != nil { 1053 countError("frame_headers_prio_weight_short") 1054 return nil, err 1055 } 1056 } 1057 if len(p)-int(padLength) < 0 { 1058 countError("frame_headers_pad_too_big") 1059 return nil, streamError(fh.StreamID, ErrCodeProtocol) 1060 } 1061 hf.headerFragBuf = p[:len(p)-int(padLength)] 1062 return hf, nil 1063 } 1064 1065 // HeadersFrameParam are the parameters for writing a HEADERS frame. 1066 type HeadersFrameParam struct { 1067 // StreamID is the required Stream ID to initiate. 1068 StreamID uint32 1069 // BlockFragment is part (or all) of a Header Block. 1070 BlockFragment []byte 1071 1072 // EndStream indicates that the header block is the last that 1073 // the endpoint will send for the identified stream. Setting 1074 // this flag causes the stream to enter one of "half closed" 1075 // states. 1076 EndStream bool 1077 1078 // EndHeaders indicates that this frame contains an entire 1079 // header block and is not followed by any 1080 // CONTINUATION frames. 1081 EndHeaders bool 1082 1083 // PadLength is the optional number of bytes of zeros to add 1084 // to this frame. 1085 PadLength uint8 1086 1087 // Priority, if non-zero, includes stream priority information 1088 // in the HEADER frame. 1089 Priority PriorityParam 1090 } 1091 1092 // WriteHeaders writes a single HEADERS frame. 1093 // 1094 // This is a low-level header writing method. Encoding headers and 1095 // splitting them into any necessary CONTINUATION frames is handled 1096 // elsewhere. 1097 // 1098 // It will perform exactly one Write to the underlying Writer. 1099 // It is the caller's responsibility to not call other Write methods concurrently. 1100 func (f *Framer) WriteHeaders(p HeadersFrameParam) error { 1101 if !validStreamID(p.StreamID) && !f.AllowIllegalWrites { 1102 return errStreamID 1103 } 1104 var flags Flags 1105 if p.PadLength != 0 { 1106 flags |= FlagHeadersPadded 1107 } 1108 if p.EndStream { 1109 flags |= FlagHeadersEndStream 1110 } 1111 if p.EndHeaders { 1112 flags |= FlagHeadersEndHeaders 1113 } 1114 if !p.Priority.IsZero() { 1115 flags |= FlagHeadersPriority 1116 } 1117 f.startWrite(FrameHeaders, flags, p.StreamID) 1118 if p.PadLength != 0 { 1119 f.writeByte(p.PadLength) 1120 } 1121 if !p.Priority.IsZero() { 1122 v := p.Priority.StreamDep 1123 if !validStreamIDOrZero(v) && !f.AllowIllegalWrites { 1124 return errDepStreamID 1125 } 1126 if p.Priority.Exclusive { 1127 v |= 1 << 31 1128 } 1129 f.writeUint32(v) 1130 f.writeByte(p.Priority.Weight) 1131 } 1132 f.wbuf = append(f.wbuf, p.BlockFragment...) 1133 f.wbuf = append(f.wbuf, padZeros[:p.PadLength]...) 1134 return f.endWrite() 1135 } 1136 1137 // A PriorityFrame specifies the sender-advised priority of a stream. 1138 // See https://httpwg.org/specs/rfc7540.html#rfc.section.6.3 1139 type PriorityFrame struct { 1140 FrameHeader 1141 PriorityParam 1142 } 1143 1144 // PriorityParam are the stream prioritzation parameters. 1145 type PriorityParam struct { 1146 // StreamDep is a 31-bit stream identifier for the 1147 // stream that this stream depends on. Zero means no 1148 // dependency. 1149 StreamDep uint32 1150 1151 // Exclusive is whether the dependency is exclusive. 1152 Exclusive bool 1153 1154 // Weight is the stream's zero-indexed weight. It should be 1155 // set together with StreamDep, or neither should be set. Per 1156 // the spec, "Add one to the value to obtain a weight between 1157 // 1 and 256." 1158 Weight uint8 1159 } 1160 1161 func (p PriorityParam) IsZero() bool { 1162 return p == PriorityParam{} 1163 } 1164 1165 func parsePriorityFrame(_ *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error) { 1166 if fh.StreamID == 0 { 1167 countError("frame_priority_zero_stream") 1168 return nil, connError{ErrCodeProtocol, "PRIORITY frame with stream ID 0"} 1169 } 1170 if len(payload) != 5 { 1171 countError("frame_priority_bad_length") 1172 return nil, connError{ErrCodeFrameSize, fmt.Sprintf("PRIORITY frame payload size was %d; want 5", len(payload))} 1173 } 1174 v := binary.BigEndian.Uint32(payload[:4]) 1175 streamID := v & 0x7fffffff // mask off high bit 1176 return &PriorityFrame{ 1177 FrameHeader: fh, 1178 PriorityParam: PriorityParam{ 1179 Weight: payload[4], 1180 StreamDep: streamID, 1181 Exclusive: streamID != v, // was high bit set? 1182 }, 1183 }, nil 1184 } 1185 1186 // WritePriority writes a PRIORITY frame. 1187 // 1188 // It will perform exactly one Write to the underlying Writer. 1189 // It is the caller's responsibility to not call other Write methods concurrently. 1190 func (f *Framer) WritePriority(streamID uint32, p PriorityParam) error { 1191 if !validStreamID(streamID) && !f.AllowIllegalWrites { 1192 return errStreamID 1193 } 1194 if !validStreamIDOrZero(p.StreamDep) { 1195 return errDepStreamID 1196 } 1197 f.startWrite(FramePriority, 0, streamID) 1198 v := p.StreamDep 1199 if p.Exclusive { 1200 v |= 1 << 31 1201 } 1202 f.writeUint32(v) 1203 f.writeByte(p.Weight) 1204 return f.endWrite() 1205 } 1206 1207 // A RSTStreamFrame allows for abnormal termination of a stream. 1208 // See https://httpwg.org/specs/rfc7540.html#rfc.section.6.4 1209 type RSTStreamFrame struct { 1210 FrameHeader 1211 ErrCode ErrCode 1212 } 1213 1214 func parseRSTStreamFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) { 1215 if len(p) != 4 { 1216 countError("frame_rststream_bad_len") 1217 return nil, ConnectionError(ErrCodeFrameSize) 1218 } 1219 if fh.StreamID == 0 { 1220 countError("frame_rststream_zero_stream") 1221 return nil, ConnectionError(ErrCodeProtocol) 1222 } 1223 return &RSTStreamFrame{fh, ErrCode(binary.BigEndian.Uint32(p[:4]))}, nil 1224 } 1225 1226 // WriteRSTStream writes a RST_STREAM frame. 1227 // 1228 // It will perform exactly one Write to the underlying Writer. 1229 // It is the caller's responsibility to not call other Write methods concurrently. 1230 func (f *Framer) WriteRSTStream(streamID uint32, code ErrCode) error { 1231 if !validStreamID(streamID) && !f.AllowIllegalWrites { 1232 return errStreamID 1233 } 1234 f.startWrite(FrameRSTStream, 0, streamID) 1235 f.writeUint32(uint32(code)) 1236 return f.endWrite() 1237 } 1238 1239 // A ContinuationFrame is used to continue a sequence of header block fragments. 1240 // See https://httpwg.org/specs/rfc7540.html#rfc.section.6.10 1241 type ContinuationFrame struct { 1242 FrameHeader 1243 headerFragBuf []byte 1244 } 1245 1246 func parseContinuationFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) { 1247 if fh.StreamID == 0 { 1248 countError("frame_continuation_zero_stream") 1249 return nil, connError{ErrCodeProtocol, "CONTINUATION frame with stream ID 0"} 1250 } 1251 return &ContinuationFrame{fh, p}, nil 1252 } 1253 1254 func (f *ContinuationFrame) HeaderBlockFragment() []byte { 1255 f.checkValid() 1256 return f.headerFragBuf 1257 } 1258 1259 func (f *ContinuationFrame) HeadersEnded() bool { 1260 return f.FrameHeader.Flags.Has(FlagContinuationEndHeaders) 1261 } 1262 1263 // WriteContinuation writes a CONTINUATION frame. 1264 // 1265 // It will perform exactly one Write to the underlying Writer. 1266 // It is the caller's responsibility to not call other Write methods concurrently. 1267 func (f *Framer) WriteContinuation(streamID uint32, endHeaders bool, headerBlockFragment []byte) error { 1268 if !validStreamID(streamID) && !f.AllowIllegalWrites { 1269 return errStreamID 1270 } 1271 var flags Flags 1272 if endHeaders { 1273 flags |= FlagContinuationEndHeaders 1274 } 1275 f.startWrite(FrameContinuation, flags, streamID) 1276 f.wbuf = append(f.wbuf, headerBlockFragment...) 1277 return f.endWrite() 1278 } 1279 1280 // A PushPromiseFrame is used to initiate a server stream. 1281 // See https://httpwg.org/specs/rfc7540.html#rfc.section.6.6 1282 type PushPromiseFrame struct { 1283 FrameHeader 1284 PromiseID uint32 1285 headerFragBuf []byte // not owned 1286 } 1287 1288 func (f *PushPromiseFrame) HeaderBlockFragment() []byte { 1289 f.checkValid() 1290 return f.headerFragBuf 1291 } 1292 1293 func (f *PushPromiseFrame) HeadersEnded() bool { 1294 return f.FrameHeader.Flags.Has(FlagPushPromiseEndHeaders) 1295 } 1296 1297 func parsePushPromise(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (_ Frame, err error) { 1298 pp := &PushPromiseFrame{ 1299 FrameHeader: fh, 1300 } 1301 if pp.StreamID == 0 { 1302 // PUSH_PROMISE frames MUST be associated with an existing, 1303 // peer-initiated stream. The stream identifier of a 1304 // PUSH_PROMISE frame indicates the stream it is associated 1305 // with. If the stream identifier field specifies the value 1306 // 0x0, a recipient MUST respond with a connection error 1307 // (Section 5.4.1) of type PROTOCOL_ERROR. 1308 countError("frame_pushpromise_zero_stream") 1309 return nil, ConnectionError(ErrCodeProtocol) 1310 } 1311 // The PUSH_PROMISE frame includes optional padding. 1312 // Padding fields and flags are identical to those defined for DATA frames 1313 var padLength uint8 1314 if fh.Flags.Has(FlagPushPromisePadded) { 1315 if p, padLength, err = readByte(p); err != nil { 1316 countError("frame_pushpromise_pad_short") 1317 return 1318 } 1319 } 1320 1321 p, pp.PromiseID, err = readUint32(p) 1322 if err != nil { 1323 countError("frame_pushpromise_promiseid_short") 1324 return 1325 } 1326 pp.PromiseID = pp.PromiseID & (1<<31 - 1) 1327 1328 if int(padLength) > len(p) { 1329 // like the DATA frame, error out if padding is longer than the body. 1330 countError("frame_pushpromise_pad_too_big") 1331 return nil, ConnectionError(ErrCodeProtocol) 1332 } 1333 pp.headerFragBuf = p[:len(p)-int(padLength)] 1334 return pp, nil 1335 } 1336 1337 // PushPromiseParam are the parameters for writing a PUSH_PROMISE frame. 1338 type PushPromiseParam struct { 1339 // StreamID is the required Stream ID to initiate. 1340 StreamID uint32 1341 1342 // PromiseID is the required Stream ID which this 1343 // Push Promises 1344 PromiseID uint32 1345 1346 // BlockFragment is part (or all) of a Header Block. 1347 BlockFragment []byte 1348 1349 // EndHeaders indicates that this frame contains an entire 1350 // header block and is not followed by any 1351 // CONTINUATION frames. 1352 EndHeaders bool 1353 1354 // PadLength is the optional number of bytes of zeros to add 1355 // to this frame. 1356 PadLength uint8 1357 } 1358 1359 // WritePushPromise writes a single PushPromise Frame. 1360 // 1361 // As with Header Frames, This is the low level call for writing 1362 // individual frames. Continuation frames are handled elsewhere. 1363 // 1364 // It will perform exactly one Write to the underlying Writer. 1365 // It is the caller's responsibility to not call other Write methods concurrently. 1366 func (f *Framer) WritePushPromise(p PushPromiseParam) error { 1367 if !validStreamID(p.StreamID) && !f.AllowIllegalWrites { 1368 return errStreamID 1369 } 1370 var flags Flags 1371 if p.PadLength != 0 { 1372 flags |= FlagPushPromisePadded 1373 } 1374 if p.EndHeaders { 1375 flags |= FlagPushPromiseEndHeaders 1376 } 1377 f.startWrite(FramePushPromise, flags, p.StreamID) 1378 if p.PadLength != 0 { 1379 f.writeByte(p.PadLength) 1380 } 1381 if !validStreamID(p.PromiseID) && !f.AllowIllegalWrites { 1382 return errStreamID 1383 } 1384 f.writeUint32(p.PromiseID) 1385 f.wbuf = append(f.wbuf, p.BlockFragment...) 1386 f.wbuf = append(f.wbuf, padZeros[:p.PadLength]...) 1387 return f.endWrite() 1388 } 1389 1390 // WriteRawFrame writes a raw frame. This can be used to write 1391 // extension frames unknown to this package. 1392 func (f *Framer) WriteRawFrame(t FrameType, flags Flags, streamID uint32, payload []byte) error { 1393 f.startWrite(t, flags, streamID) 1394 f.writeBytes(payload) 1395 return f.endWrite() 1396 } 1397 1398 func readByte(p []byte) (remain []byte, b byte, err error) { 1399 if len(p) == 0 { 1400 return nil, 0, io.ErrUnexpectedEOF 1401 } 1402 return p[1:], p[0], nil 1403 } 1404 1405 func readUint32(p []byte) (remain []byte, v uint32, err error) { 1406 if len(p) < 4 { 1407 return nil, 0, io.ErrUnexpectedEOF 1408 } 1409 return p[4:], binary.BigEndian.Uint32(p[:4]), nil 1410 } 1411 1412 type streamEnder interface { 1413 StreamEnded() bool 1414 } 1415 1416 type headersEnder interface { 1417 HeadersEnded() bool 1418 } 1419 1420 type headersOrContinuation interface { 1421 headersEnder 1422 HeaderBlockFragment() []byte 1423 } 1424 1425 // A MetaHeadersFrame is the representation of one HEADERS frame and 1426 // zero or more contiguous CONTINUATION frames and the decoding of 1427 // their HPACK-encoded contents. 1428 // 1429 // This type of frame does not appear on the wire and is only returned 1430 // by the Framer when Framer.ReadMetaHeaders is set. 1431 type MetaHeadersFrame struct { 1432 *HeadersFrame 1433 1434 // Fields are the fields contained in the HEADERS and 1435 // CONTINUATION frames. The underlying slice is owned by the 1436 // Framer and must not be retained after the next call to 1437 // ReadFrame. 1438 // 1439 // Fields are guaranteed to be in the correct http2 order and 1440 // not have unknown pseudo header fields or invalid header 1441 // field names or values. Required pseudo header fields may be 1442 // missing, however. Use the MetaHeadersFrame.Pseudo accessor 1443 // method access pseudo headers. 1444 Fields []hpack.HeaderField 1445 1446 // Truncated is whether the max header list size limit was hit 1447 // and Fields is incomplete. The hpack decoder state is still 1448 // valid, however. 1449 Truncated bool 1450 } 1451 1452 // PseudoValue returns the given pseudo header field's value. 1453 // The provided pseudo field should not contain the leading colon. 1454 func (mh *MetaHeadersFrame) PseudoValue(pseudo string) string { 1455 for _, hf := range mh.Fields { 1456 if !hf.IsPseudo() { 1457 return "" 1458 } 1459 if hf.Name[1:] == pseudo { 1460 return hf.Value 1461 } 1462 } 1463 return "" 1464 } 1465 1466 // RegularFields returns the regular (non-pseudo) header fields of mh. 1467 // The caller does not own the returned slice. 1468 func (mh *MetaHeadersFrame) RegularFields() []hpack.HeaderField { 1469 for i, hf := range mh.Fields { 1470 if !hf.IsPseudo() { 1471 return mh.Fields[i:] 1472 } 1473 } 1474 return nil 1475 } 1476 1477 // PseudoFields returns the pseudo header fields of mh. 1478 // The caller does not own the returned slice. 1479 func (mh *MetaHeadersFrame) PseudoFields() []hpack.HeaderField { 1480 for i, hf := range mh.Fields { 1481 if !hf.IsPseudo() { 1482 return mh.Fields[:i] 1483 } 1484 } 1485 return mh.Fields 1486 } 1487 1488 func (mh *MetaHeadersFrame) checkPseudos() error { 1489 var isRequest, isResponse bool 1490 pf := mh.PseudoFields() 1491 for i, hf := range pf { 1492 switch hf.Name { 1493 case ":method", ":path", ":scheme", ":authority": 1494 isRequest = true 1495 case ":status": 1496 isResponse = true 1497 default: 1498 return pseudoHeaderError(hf.Name) 1499 } 1500 // Check for duplicates. 1501 // This would be a bad algorithm, but N is 4. 1502 // And this doesn't allocate. 1503 for _, hf2 := range pf[:i] { 1504 if hf.Name == hf2.Name { 1505 return duplicatePseudoHeaderError(hf.Name) 1506 } 1507 } 1508 } 1509 if isRequest && isResponse { 1510 return errMixPseudoHeaderTypes 1511 } 1512 return nil 1513 } 1514 1515 func (fr *Framer) maxHeaderStringLen() int { 1516 v := int(fr.maxHeaderListSize()) 1517 if v < 0 { 1518 // If maxHeaderListSize overflows an int, use no limit (0). 1519 return 0 1520 } 1521 return v 1522 } 1523 1524 // readMetaFrame returns 0 or more CONTINUATION frames from fr and 1525 // merge them into the provided hf and returns a MetaHeadersFrame 1526 // with the decoded hpack values. 1527 func (fr *Framer) readMetaFrame(hf *HeadersFrame) (Frame, error) { 1528 if fr.AllowIllegalReads { 1529 return nil, errors.New("illegal use of AllowIllegalReads with ReadMetaHeaders") 1530 } 1531 mh := &MetaHeadersFrame{ 1532 HeadersFrame: hf, 1533 } 1534 var remainSize = fr.maxHeaderListSize() 1535 var sawRegular bool 1536 1537 var invalid error // pseudo header field errors 1538 hdec := fr.ReadMetaHeaders 1539 hdec.SetEmitEnabled(true) 1540 hdec.SetMaxStringLength(fr.maxHeaderStringLen()) 1541 hdec.SetEmitFunc(func(hf hpack.HeaderField) { 1542 if VerboseLogs && fr.logReads { 1543 fr.debugReadLoggerf("http2: decoded hpack field %+v", hf) 1544 } 1545 if !httpguts.ValidHeaderFieldValue(hf.Value) { 1546 // Don't include the value in the error, because it may be sensitive. 1547 invalid = headerFieldValueError(hf.Name) 1548 } 1549 isPseudo := strings.HasPrefix(hf.Name, ":") 1550 if isPseudo { 1551 if sawRegular { 1552 invalid = errPseudoAfterRegular 1553 } 1554 } else { 1555 sawRegular = true 1556 if !validWireHeaderFieldName(hf.Name) { 1557 invalid = headerFieldNameError(hf.Name) 1558 } 1559 } 1560 1561 if invalid != nil { 1562 hdec.SetEmitEnabled(false) 1563 return 1564 } 1565 1566 size := hf.Size() 1567 if size > remainSize { 1568 hdec.SetEmitEnabled(false) 1569 mh.Truncated = true 1570 remainSize = 0 1571 return 1572 } 1573 remainSize -= size 1574 1575 mh.Fields = append(mh.Fields, hf) 1576 }) 1577 // Lose reference to MetaHeadersFrame: 1578 defer hdec.SetEmitFunc(func(hf hpack.HeaderField) {}) 1579 1580 var hc headersOrContinuation = hf 1581 for { 1582 frag := hc.HeaderBlockFragment() 1583 1584 // Avoid parsing large amounts of headers that we will then discard. 1585 // If the sender exceeds the max header list size by too much, 1586 // skip parsing the fragment and close the connection. 1587 // 1588 // "Too much" is either any CONTINUATION frame after we've already 1589 // exceeded the max header list size (in which case remainSize is 0), 1590 // or a frame whose encoded size is more than twice the remaining 1591 // header list bytes we're willing to accept. 1592 if int64(len(frag)) > int64(2*remainSize) { 1593 if VerboseLogs { 1594 log.Printf("http2: header list too large") 1595 } 1596 // It would be nice to send a RST_STREAM before sending the GOAWAY, 1597 // but the structure of the server's frame writer makes this difficult. 1598 return mh, ConnectionError(ErrCodeProtocol) 1599 } 1600 1601 // Also close the connection after any CONTINUATION frame following an 1602 // invalid header, since we stop tracking the size of the headers after 1603 // an invalid one. 1604 if invalid != nil { 1605 if VerboseLogs { 1606 log.Printf("http2: invalid header: %v", invalid) 1607 } 1608 // It would be nice to send a RST_STREAM before sending the GOAWAY, 1609 // but the structure of the server's frame writer makes this difficult. 1610 return mh, ConnectionError(ErrCodeProtocol) 1611 } 1612 1613 if _, err := hdec.Write(frag); err != nil { 1614 return mh, ConnectionError(ErrCodeCompression) 1615 } 1616 1617 if hc.HeadersEnded() { 1618 break 1619 } 1620 if f, err := fr.ReadFrame(); err != nil { 1621 return nil, err 1622 } else { 1623 hc = f.(*ContinuationFrame) // guaranteed by checkFrameOrder 1624 } 1625 } 1626 1627 mh.HeadersFrame.headerFragBuf = nil 1628 mh.HeadersFrame.invalidate() 1629 1630 if err := hdec.Close(); err != nil { 1631 return mh, ConnectionError(ErrCodeCompression) 1632 } 1633 if invalid != nil { 1634 fr.errDetail = invalid 1635 if VerboseLogs { 1636 log.Printf("http2: invalid header: %v", invalid) 1637 } 1638 return nil, StreamError{mh.StreamID, ErrCodeProtocol, invalid} 1639 } 1640 if err := mh.checkPseudos(); err != nil { 1641 fr.errDetail = err 1642 if VerboseLogs { 1643 log.Printf("http2: invalid pseudo headers: %v", err) 1644 } 1645 return nil, StreamError{mh.StreamID, ErrCodeProtocol, err} 1646 } 1647 return mh, nil 1648 } 1649 1650 func summarizeFrame(f Frame) string { 1651 var buf bytes.Buffer 1652 f.Header().writeDebug(&buf) 1653 switch f := f.(type) { 1654 case *SettingsFrame: 1655 n := 0 1656 f.ForeachSetting(func(s Setting) error { 1657 n++ 1658 if n == 1 { 1659 buf.WriteString(", settings:") 1660 } 1661 fmt.Fprintf(&buf, " %v=%v,", s.ID, s.Val) 1662 return nil 1663 }) 1664 if n > 0 { 1665 buf.Truncate(buf.Len() - 1) // remove trailing comma 1666 } 1667 case *DataFrame: 1668 data := f.Data() 1669 const max = 256 1670 if len(data) > max { 1671 data = data[:max] 1672 } 1673 fmt.Fprintf(&buf, " data=%q", data) 1674 if len(f.Data()) > max { 1675 fmt.Fprintf(&buf, " (%d bytes omitted)", len(f.Data())-max) 1676 } 1677 case *WindowUpdateFrame: 1678 if f.StreamID == 0 { 1679 buf.WriteString(" (conn)") 1680 } 1681 fmt.Fprintf(&buf, " incr=%v", f.Increment) 1682 case *PingFrame: 1683 fmt.Fprintf(&buf, " ping=%q", f.Data[:]) 1684 case *GoAwayFrame: 1685 fmt.Fprintf(&buf, " LastStreamID=%v ErrCode=%v Debug=%q", 1686 f.LastStreamID, f.ErrCode, f.debugData) 1687 case *RSTStreamFrame: 1688 fmt.Fprintf(&buf, " ErrCode=%v", f.ErrCode) 1689 } 1690 return buf.String() 1691 }