github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/vendor_skip/golang.org/x/net/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 func (fr *Framer) ReadFrame() (Frame, error) { 494 fr.errDetail = nil 495 if fr.lastFrame != nil { 496 fr.lastFrame.invalidate() 497 } 498 fh, err := readFrameHeader(fr.headerBuf[:], fr.r) 499 if err != nil { 500 return nil, err 501 } 502 if fh.Length > fr.maxReadSize { 503 return nil, ErrFrameTooLarge 504 } 505 payload := fr.getReadBuf(fh.Length) 506 if _, err := io.ReadFull(fr.r, payload); err != nil { 507 return nil, err 508 } 509 f, err := typeFrameParser(fh.Type)(fr.frameCache, fh, fr.countError, payload) 510 if err != nil { 511 if ce, ok := err.(connError); ok { 512 return nil, fr.connError(ce.Code, ce.Reason) 513 } 514 return nil, err 515 } 516 if err := fr.checkFrameOrder(f); err != nil { 517 return nil, err 518 } 519 if fr.logReads { 520 fr.debugReadLoggerf("http2: Framer %p: read %v", fr, summarizeFrame(f)) 521 } 522 if fh.Type == FrameHeaders && fr.ReadMetaHeaders != nil { 523 return fr.readMetaFrame(f.(*HeadersFrame)) 524 } 525 return f, nil 526 } 527 528 // connError returns ConnectionError(code) but first 529 // stashes away a public reason to the caller can optionally relay it 530 // to the peer before hanging up on them. This might help others debug 531 // their implementations. 532 func (fr *Framer) connError(code ErrCode, reason string) error { 533 fr.errDetail = errors.New(reason) 534 return ConnectionError(code) 535 } 536 537 // checkFrameOrder reports an error if f is an invalid frame to return 538 // next from ReadFrame. Mostly it checks whether HEADERS and 539 // CONTINUATION frames are contiguous. 540 func (fr *Framer) checkFrameOrder(f Frame) error { 541 last := fr.lastFrame 542 fr.lastFrame = f 543 if fr.AllowIllegalReads { 544 return nil 545 } 546 547 fh := f.Header() 548 if fr.lastHeaderStream != 0 { 549 if fh.Type != FrameContinuation { 550 return fr.connError(ErrCodeProtocol, 551 fmt.Sprintf("got %s for stream %d; expected CONTINUATION following %s for stream %d", 552 fh.Type, fh.StreamID, 553 last.Header().Type, fr.lastHeaderStream)) 554 } 555 if fh.StreamID != fr.lastHeaderStream { 556 return fr.connError(ErrCodeProtocol, 557 fmt.Sprintf("got CONTINUATION for stream %d; expected stream %d", 558 fh.StreamID, fr.lastHeaderStream)) 559 } 560 } else if fh.Type == FrameContinuation { 561 return fr.connError(ErrCodeProtocol, fmt.Sprintf("unexpected CONTINUATION for stream %d", fh.StreamID)) 562 } 563 564 switch fh.Type { 565 case FrameHeaders, FrameContinuation: 566 if fh.Flags.Has(FlagHeadersEndHeaders) { 567 fr.lastHeaderStream = 0 568 } else { 569 fr.lastHeaderStream = fh.StreamID 570 } 571 } 572 573 return nil 574 } 575 576 // A DataFrame conveys arbitrary, variable-length sequences of octets 577 // associated with a stream. 578 // See https://httpwg.org/specs/rfc7540.html#rfc.section.6.1 579 type DataFrame struct { 580 FrameHeader 581 data []byte 582 } 583 584 func (f *DataFrame) StreamEnded() bool { 585 return f.FrameHeader.Flags.Has(FlagDataEndStream) 586 } 587 588 // Data returns the frame's data octets, not including any padding 589 // size byte or padding suffix bytes. 590 // The caller must not retain the returned memory past the next 591 // call to ReadFrame. 592 func (f *DataFrame) Data() []byte { 593 f.checkValid() 594 return f.data 595 } 596 597 func parseDataFrame(fc *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error) { 598 if fh.StreamID == 0 { 599 // DATA frames MUST be associated with a stream. If a 600 // DATA frame is received whose stream identifier 601 // field is 0x0, the recipient MUST respond with a 602 // connection error (Section 5.4.1) of type 603 // PROTOCOL_ERROR. 604 countError("frame_data_stream_0") 605 return nil, connError{ErrCodeProtocol, "DATA frame with stream ID 0"} 606 } 607 f := fc.getDataFrame() 608 f.FrameHeader = fh 609 610 var padSize byte 611 if fh.Flags.Has(FlagDataPadded) { 612 var err error 613 payload, padSize, err = readByte(payload) 614 if err != nil { 615 countError("frame_data_pad_byte_short") 616 return nil, err 617 } 618 } 619 if int(padSize) > len(payload) { 620 // If the length of the padding is greater than the 621 // length of the frame payload, the recipient MUST 622 // treat this as a connection error. 623 // Filed: https://github.com/http2/http2-spec/issues/610 624 countError("frame_data_pad_too_big") 625 return nil, connError{ErrCodeProtocol, "pad size larger than data payload"} 626 } 627 f.data = payload[:len(payload)-int(padSize)] 628 return f, nil 629 } 630 631 var ( 632 errStreamID = errors.New("invalid stream ID") 633 errDepStreamID = errors.New("invalid dependent stream ID") 634 errPadLength = errors.New("pad length too large") 635 errPadBytes = errors.New("padding bytes must all be zeros unless AllowIllegalWrites is enabled") 636 ) 637 638 func validStreamIDOrZero(streamID uint32) bool { 639 return streamID&(1<<31) == 0 640 } 641 642 func validStreamID(streamID uint32) bool { 643 return streamID != 0 && streamID&(1<<31) == 0 644 } 645 646 // WriteData writes a DATA frame. 647 // 648 // It will perform exactly one Write to the underlying Writer. 649 // It is the caller's responsibility not to violate the maximum frame size 650 // and to not call other Write methods concurrently. 651 func (f *Framer) WriteData(streamID uint32, endStream bool, data []byte) error { 652 return f.WriteDataPadded(streamID, endStream, data, nil) 653 } 654 655 // WriteDataPadded writes a DATA frame with optional padding. 656 // 657 // If pad is nil, the padding bit is not sent. 658 // The length of pad must not exceed 255 bytes. 659 // The bytes of pad must all be zero, unless f.AllowIllegalWrites is set. 660 // 661 // It will perform exactly one Write to the underlying Writer. 662 // It is the caller's responsibility not to violate the maximum frame size 663 // and to not call other Write methods concurrently. 664 func (f *Framer) WriteDataPadded(streamID uint32, endStream bool, data, pad []byte) error { 665 if err := f.startWriteDataPadded(streamID, endStream, data, pad); err != nil { 666 return err 667 } 668 return f.endWrite() 669 } 670 671 // startWriteDataPadded is WriteDataPadded, but only writes the frame to the Framer's internal buffer. 672 // The caller should call endWrite to flush the frame to the underlying writer. 673 func (f *Framer) startWriteDataPadded(streamID uint32, endStream bool, data, pad []byte) error { 674 if !validStreamID(streamID) && !f.AllowIllegalWrites { 675 return errStreamID 676 } 677 if len(pad) > 0 { 678 if len(pad) > 255 { 679 return errPadLength 680 } 681 if !f.AllowIllegalWrites { 682 for _, b := range pad { 683 if b != 0 { 684 // "Padding octets MUST be set to zero when sending." 685 return errPadBytes 686 } 687 } 688 } 689 } 690 var flags Flags 691 if endStream { 692 flags |= FlagDataEndStream 693 } 694 if pad != nil { 695 flags |= FlagDataPadded 696 } 697 f.startWrite(FrameData, flags, streamID) 698 if pad != nil { 699 f.wbuf = append(f.wbuf, byte(len(pad))) 700 } 701 f.wbuf = append(f.wbuf, data...) 702 f.wbuf = append(f.wbuf, pad...) 703 return nil 704 } 705 706 // A SettingsFrame conveys configuration parameters that affect how 707 // endpoints communicate, such as preferences and constraints on peer 708 // behavior. 709 // 710 // See https://httpwg.org/specs/rfc7540.html#SETTINGS 711 type SettingsFrame struct { 712 FrameHeader 713 p []byte 714 } 715 716 func parseSettingsFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) { 717 if fh.Flags.Has(FlagSettingsAck) && fh.Length > 0 { 718 // When this (ACK 0x1) bit is set, the payload of the 719 // SETTINGS frame MUST be empty. Receipt of a 720 // SETTINGS frame with the ACK flag set and a length 721 // field value other than 0 MUST be treated as a 722 // connection error (Section 5.4.1) of type 723 // FRAME_SIZE_ERROR. 724 countError("frame_settings_ack_with_length") 725 return nil, ConnectionError(ErrCodeFrameSize) 726 } 727 if fh.StreamID != 0 { 728 // SETTINGS frames always apply to a connection, 729 // never a single stream. The stream identifier for a 730 // SETTINGS frame MUST be zero (0x0). If an endpoint 731 // receives a SETTINGS frame whose stream identifier 732 // field is anything other than 0x0, the endpoint MUST 733 // respond with a connection error (Section 5.4.1) of 734 // type PROTOCOL_ERROR. 735 countError("frame_settings_has_stream") 736 return nil, ConnectionError(ErrCodeProtocol) 737 } 738 if len(p)%6 != 0 { 739 countError("frame_settings_mod_6") 740 // Expecting even number of 6 byte settings. 741 return nil, ConnectionError(ErrCodeFrameSize) 742 } 743 f := &SettingsFrame{FrameHeader: fh, p: p} 744 if v, ok := f.Value(SettingInitialWindowSize); ok && v > (1<<31)-1 { 745 countError("frame_settings_window_size_too_big") 746 // Values above the maximum flow control window size of 2^31 - 1 MUST 747 // be treated as a connection error (Section 5.4.1) of type 748 // FLOW_CONTROL_ERROR. 749 return nil, ConnectionError(ErrCodeFlowControl) 750 } 751 return f, nil 752 } 753 754 func (f *SettingsFrame) IsAck() bool { 755 return f.FrameHeader.Flags.Has(FlagSettingsAck) 756 } 757 758 func (f *SettingsFrame) Value(id SettingID) (v uint32, ok bool) { 759 f.checkValid() 760 for i := 0; i < f.NumSettings(); i++ { 761 if s := f.Setting(i); s.ID == id { 762 return s.Val, true 763 } 764 } 765 return 0, false 766 } 767 768 // Setting returns the setting from the frame at the given 0-based index. 769 // The index must be >= 0 and less than f.NumSettings(). 770 func (f *SettingsFrame) Setting(i int) Setting { 771 buf := f.p 772 return Setting{ 773 ID: SettingID(binary.BigEndian.Uint16(buf[i*6 : i*6+2])), 774 Val: binary.BigEndian.Uint32(buf[i*6+2 : i*6+6]), 775 } 776 } 777 778 func (f *SettingsFrame) NumSettings() int { return len(f.p) / 6 } 779 780 // HasDuplicates reports whether f contains any duplicate setting IDs. 781 func (f *SettingsFrame) HasDuplicates() bool { 782 num := f.NumSettings() 783 if num == 0 { 784 return false 785 } 786 // If it's small enough (the common case), just do the n^2 787 // thing and avoid a map allocation. 788 if num < 10 { 789 for i := 0; i < num; i++ { 790 idi := f.Setting(i).ID 791 for j := i + 1; j < num; j++ { 792 idj := f.Setting(j).ID 793 if idi == idj { 794 return true 795 } 796 } 797 } 798 return false 799 } 800 seen := map[SettingID]bool{} 801 for i := 0; i < num; i++ { 802 id := f.Setting(i).ID 803 if seen[id] { 804 return true 805 } 806 seen[id] = true 807 } 808 return false 809 } 810 811 // ForeachSetting runs fn for each setting. 812 // It stops and returns the first error. 813 func (f *SettingsFrame) ForeachSetting(fn func(Setting) error) error { 814 f.checkValid() 815 for i := 0; i < f.NumSettings(); i++ { 816 if err := fn(f.Setting(i)); err != nil { 817 return err 818 } 819 } 820 return nil 821 } 822 823 // WriteSettings writes a SETTINGS frame with zero or more settings 824 // specified and the ACK bit not set. 825 // 826 // It will perform exactly one Write to the underlying Writer. 827 // It is the caller's responsibility to not call other Write methods concurrently. 828 func (f *Framer) WriteSettings(settings ...Setting) error { 829 f.startWrite(FrameSettings, 0, 0) 830 for _, s := range settings { 831 f.writeUint16(uint16(s.ID)) 832 f.writeUint32(s.Val) 833 } 834 return f.endWrite() 835 } 836 837 // WriteSettingsAck writes an empty SETTINGS frame with the ACK bit set. 838 // 839 // It will perform exactly one Write to the underlying Writer. 840 // It is the caller's responsibility to not call other Write methods concurrently. 841 func (f *Framer) WriteSettingsAck() error { 842 f.startWrite(FrameSettings, FlagSettingsAck, 0) 843 return f.endWrite() 844 } 845 846 // A PingFrame is a mechanism for measuring a minimal round trip time 847 // from the sender, as well as determining whether an idle connection 848 // is still functional. 849 // See https://httpwg.org/specs/rfc7540.html#rfc.section.6.7 850 type PingFrame struct { 851 FrameHeader 852 Data [8]byte 853 } 854 855 func (f *PingFrame) IsAck() bool { return f.Flags.Has(FlagPingAck) } 856 857 func parsePingFrame(_ *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error) { 858 if len(payload) != 8 { 859 countError("frame_ping_length") 860 return nil, ConnectionError(ErrCodeFrameSize) 861 } 862 if fh.StreamID != 0 { 863 countError("frame_ping_has_stream") 864 return nil, ConnectionError(ErrCodeProtocol) 865 } 866 f := &PingFrame{FrameHeader: fh} 867 copy(f.Data[:], payload) 868 return f, nil 869 } 870 871 func (f *Framer) WritePing(ack bool, data [8]byte) error { 872 var flags Flags 873 if ack { 874 flags = FlagPingAck 875 } 876 f.startWrite(FramePing, flags, 0) 877 f.writeBytes(data[:]) 878 return f.endWrite() 879 } 880 881 // A GoAwayFrame informs the remote peer to stop creating streams on this connection. 882 // See https://httpwg.org/specs/rfc7540.html#rfc.section.6.8 883 type GoAwayFrame struct { 884 FrameHeader 885 LastStreamID uint32 886 ErrCode ErrCode 887 debugData []byte 888 } 889 890 // DebugData returns any debug data in the GOAWAY frame. Its contents 891 // are not defined. 892 // The caller must not retain the returned memory past the next 893 // call to ReadFrame. 894 func (f *GoAwayFrame) DebugData() []byte { 895 f.checkValid() 896 return f.debugData 897 } 898 899 func parseGoAwayFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) { 900 if fh.StreamID != 0 { 901 countError("frame_goaway_has_stream") 902 return nil, ConnectionError(ErrCodeProtocol) 903 } 904 if len(p) < 8 { 905 countError("frame_goaway_short") 906 return nil, ConnectionError(ErrCodeFrameSize) 907 } 908 return &GoAwayFrame{ 909 FrameHeader: fh, 910 LastStreamID: binary.BigEndian.Uint32(p[:4]) & (1<<31 - 1), 911 ErrCode: ErrCode(binary.BigEndian.Uint32(p[4:8])), 912 debugData: p[8:], 913 }, nil 914 } 915 916 func (f *Framer) WriteGoAway(maxStreamID uint32, code ErrCode, debugData []byte) error { 917 f.startWrite(FrameGoAway, 0, 0) 918 f.writeUint32(maxStreamID & (1<<31 - 1)) 919 f.writeUint32(uint32(code)) 920 f.writeBytes(debugData) 921 return f.endWrite() 922 } 923 924 // An UnknownFrame is the frame type returned when the frame type is unknown 925 // or no specific frame type parser exists. 926 type UnknownFrame struct { 927 FrameHeader 928 p []byte 929 } 930 931 // Payload returns the frame's payload (after the header). It is not 932 // valid to call this method after a subsequent call to 933 // Framer.ReadFrame, nor is it valid to retain the returned slice. 934 // The memory is owned by the Framer and is invalidated when the next 935 // frame is read. 936 func (f *UnknownFrame) Payload() []byte { 937 f.checkValid() 938 return f.p 939 } 940 941 func parseUnknownFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) { 942 return &UnknownFrame{fh, p}, nil 943 } 944 945 // A WindowUpdateFrame is used to implement flow control. 946 // See https://httpwg.org/specs/rfc7540.html#rfc.section.6.9 947 type WindowUpdateFrame struct { 948 FrameHeader 949 Increment uint32 // never read with high bit set 950 } 951 952 func parseWindowUpdateFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) { 953 if len(p) != 4 { 954 countError("frame_windowupdate_bad_len") 955 return nil, ConnectionError(ErrCodeFrameSize) 956 } 957 inc := binary.BigEndian.Uint32(p[:4]) & 0x7fffffff // mask off high reserved bit 958 if inc == 0 { 959 // A receiver MUST treat the receipt of a 960 // WINDOW_UPDATE frame with an flow control window 961 // increment of 0 as a stream error (Section 5.4.2) of 962 // type PROTOCOL_ERROR; errors on the connection flow 963 // control window MUST be treated as a connection 964 // error (Section 5.4.1). 965 if fh.StreamID == 0 { 966 countError("frame_windowupdate_zero_inc_conn") 967 return nil, ConnectionError(ErrCodeProtocol) 968 } 969 countError("frame_windowupdate_zero_inc_stream") 970 return nil, streamError(fh.StreamID, ErrCodeProtocol) 971 } 972 return &WindowUpdateFrame{ 973 FrameHeader: fh, 974 Increment: inc, 975 }, nil 976 } 977 978 // WriteWindowUpdate writes a WINDOW_UPDATE frame. 979 // The increment value must be between 1 and 2,147,483,647, inclusive. 980 // If the Stream ID is zero, the window update applies to the 981 // connection as a whole. 982 func (f *Framer) WriteWindowUpdate(streamID, incr uint32) error { 983 // "The legal range for the increment to the flow control window is 1 to 2^31-1 (2,147,483,647) octets." 984 if (incr < 1 || incr > 2147483647) && !f.AllowIllegalWrites { 985 return errors.New("illegal window increment value") 986 } 987 f.startWrite(FrameWindowUpdate, 0, streamID) 988 f.writeUint32(incr) 989 return f.endWrite() 990 } 991 992 // A HeadersFrame is used to open a stream and additionally carries a 993 // header block fragment. 994 type HeadersFrame struct { 995 FrameHeader 996 997 // Priority is set if FlagHeadersPriority is set in the FrameHeader. 998 Priority PriorityParam 999 1000 headerFragBuf []byte // not owned 1001 } 1002 1003 func (f *HeadersFrame) HeaderBlockFragment() []byte { 1004 f.checkValid() 1005 return f.headerFragBuf 1006 } 1007 1008 func (f *HeadersFrame) HeadersEnded() bool { 1009 return f.FrameHeader.Flags.Has(FlagHeadersEndHeaders) 1010 } 1011 1012 func (f *HeadersFrame) StreamEnded() bool { 1013 return f.FrameHeader.Flags.Has(FlagHeadersEndStream) 1014 } 1015 1016 func (f *HeadersFrame) HasPriority() bool { 1017 return f.FrameHeader.Flags.Has(FlagHeadersPriority) 1018 } 1019 1020 func parseHeadersFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (_ Frame, err error) { 1021 hf := &HeadersFrame{ 1022 FrameHeader: fh, 1023 } 1024 if fh.StreamID == 0 { 1025 // HEADERS frames MUST be associated with a stream. If a HEADERS frame 1026 // is received whose stream identifier field is 0x0, the recipient MUST 1027 // respond with a connection error (Section 5.4.1) of type 1028 // PROTOCOL_ERROR. 1029 countError("frame_headers_zero_stream") 1030 return nil, connError{ErrCodeProtocol, "HEADERS frame with stream ID 0"} 1031 } 1032 var padLength uint8 1033 if fh.Flags.Has(FlagHeadersPadded) { 1034 if p, padLength, err = readByte(p); err != nil { 1035 countError("frame_headers_pad_short") 1036 return 1037 } 1038 } 1039 if fh.Flags.Has(FlagHeadersPriority) { 1040 var v uint32 1041 p, v, err = readUint32(p) 1042 if err != nil { 1043 countError("frame_headers_prio_short") 1044 return nil, err 1045 } 1046 hf.Priority.StreamDep = v & 0x7fffffff 1047 hf.Priority.Exclusive = (v != hf.Priority.StreamDep) // high bit was set 1048 p, hf.Priority.Weight, err = readByte(p) 1049 if err != nil { 1050 countError("frame_headers_prio_weight_short") 1051 return nil, err 1052 } 1053 } 1054 if len(p)-int(padLength) < 0 { 1055 countError("frame_headers_pad_too_big") 1056 return nil, streamError(fh.StreamID, ErrCodeProtocol) 1057 } 1058 hf.headerFragBuf = p[:len(p)-int(padLength)] 1059 return hf, nil 1060 } 1061 1062 // HeadersFrameParam are the parameters for writing a HEADERS frame. 1063 type HeadersFrameParam struct { 1064 // StreamID is the required Stream ID to initiate. 1065 StreamID uint32 1066 // BlockFragment is part (or all) of a Header Block. 1067 BlockFragment []byte 1068 1069 // EndStream indicates that the header block is the last that 1070 // the endpoint will send for the identified stream. Setting 1071 // this flag causes the stream to enter one of "half closed" 1072 // states. 1073 EndStream bool 1074 1075 // EndHeaders indicates that this frame contains an entire 1076 // header block and is not followed by any 1077 // CONTINUATION frames. 1078 EndHeaders bool 1079 1080 // PadLength is the optional number of bytes of zeros to add 1081 // to this frame. 1082 PadLength uint8 1083 1084 // Priority, if non-zero, includes stream priority information 1085 // in the HEADER frame. 1086 Priority PriorityParam 1087 } 1088 1089 // WriteHeaders writes a single HEADERS frame. 1090 // 1091 // This is a low-level header writing method. Encoding headers and 1092 // splitting them into any necessary CONTINUATION frames is handled 1093 // elsewhere. 1094 // 1095 // It will perform exactly one Write to the underlying Writer. 1096 // It is the caller's responsibility to not call other Write methods concurrently. 1097 func (f *Framer) WriteHeaders(p HeadersFrameParam) error { 1098 if !validStreamID(p.StreamID) && !f.AllowIllegalWrites { 1099 return errStreamID 1100 } 1101 var flags Flags 1102 if p.PadLength != 0 { 1103 flags |= FlagHeadersPadded 1104 } 1105 if p.EndStream { 1106 flags |= FlagHeadersEndStream 1107 } 1108 if p.EndHeaders { 1109 flags |= FlagHeadersEndHeaders 1110 } 1111 if !p.Priority.IsZero() { 1112 flags |= FlagHeadersPriority 1113 } 1114 f.startWrite(FrameHeaders, flags, p.StreamID) 1115 if p.PadLength != 0 { 1116 f.writeByte(p.PadLength) 1117 } 1118 if !p.Priority.IsZero() { 1119 v := p.Priority.StreamDep 1120 if !validStreamIDOrZero(v) && !f.AllowIllegalWrites { 1121 return errDepStreamID 1122 } 1123 if p.Priority.Exclusive { 1124 v |= 1 << 31 1125 } 1126 f.writeUint32(v) 1127 f.writeByte(p.Priority.Weight) 1128 } 1129 f.wbuf = append(f.wbuf, p.BlockFragment...) 1130 f.wbuf = append(f.wbuf, padZeros[:p.PadLength]...) 1131 return f.endWrite() 1132 } 1133 1134 // A PriorityFrame specifies the sender-advised priority of a stream. 1135 // See https://httpwg.org/specs/rfc7540.html#rfc.section.6.3 1136 type PriorityFrame struct { 1137 FrameHeader 1138 PriorityParam 1139 } 1140 1141 // PriorityParam are the stream prioritzation parameters. 1142 type PriorityParam struct { 1143 // StreamDep is a 31-bit stream identifier for the 1144 // stream that this stream depends on. Zero means no 1145 // dependency. 1146 StreamDep uint32 1147 1148 // Exclusive is whether the dependency is exclusive. 1149 Exclusive bool 1150 1151 // Weight is the stream's zero-indexed weight. It should be 1152 // set together with StreamDep, or neither should be set. Per 1153 // the spec, "Add one to the value to obtain a weight between 1154 // 1 and 256." 1155 Weight uint8 1156 } 1157 1158 func (p PriorityParam) IsZero() bool { 1159 return p == PriorityParam{} 1160 } 1161 1162 func parsePriorityFrame(_ *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error) { 1163 if fh.StreamID == 0 { 1164 countError("frame_priority_zero_stream") 1165 return nil, connError{ErrCodeProtocol, "PRIORITY frame with stream ID 0"} 1166 } 1167 if len(payload) != 5 { 1168 countError("frame_priority_bad_length") 1169 return nil, connError{ErrCodeFrameSize, fmt.Sprintf("PRIORITY frame payload size was %d; want 5", len(payload))} 1170 } 1171 v := binary.BigEndian.Uint32(payload[:4]) 1172 streamID := v & 0x7fffffff // mask off high bit 1173 return &PriorityFrame{ 1174 FrameHeader: fh, 1175 PriorityParam: PriorityParam{ 1176 Weight: payload[4], 1177 StreamDep: streamID, 1178 Exclusive: streamID != v, // was high bit set? 1179 }, 1180 }, nil 1181 } 1182 1183 // WritePriority writes a PRIORITY frame. 1184 // 1185 // It will perform exactly one Write to the underlying Writer. 1186 // It is the caller's responsibility to not call other Write methods concurrently. 1187 func (f *Framer) WritePriority(streamID uint32, p PriorityParam) error { 1188 if !validStreamID(streamID) && !f.AllowIllegalWrites { 1189 return errStreamID 1190 } 1191 if !validStreamIDOrZero(p.StreamDep) { 1192 return errDepStreamID 1193 } 1194 f.startWrite(FramePriority, 0, streamID) 1195 v := p.StreamDep 1196 if p.Exclusive { 1197 v |= 1 << 31 1198 } 1199 f.writeUint32(v) 1200 f.writeByte(p.Weight) 1201 return f.endWrite() 1202 } 1203 1204 // A RSTStreamFrame allows for abnormal termination of a stream. 1205 // See https://httpwg.org/specs/rfc7540.html#rfc.section.6.4 1206 type RSTStreamFrame struct { 1207 FrameHeader 1208 ErrCode ErrCode 1209 } 1210 1211 func parseRSTStreamFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) { 1212 if len(p) != 4 { 1213 countError("frame_rststream_bad_len") 1214 return nil, ConnectionError(ErrCodeFrameSize) 1215 } 1216 if fh.StreamID == 0 { 1217 countError("frame_rststream_zero_stream") 1218 return nil, ConnectionError(ErrCodeProtocol) 1219 } 1220 return &RSTStreamFrame{fh, ErrCode(binary.BigEndian.Uint32(p[:4]))}, nil 1221 } 1222 1223 // WriteRSTStream writes a RST_STREAM frame. 1224 // 1225 // It will perform exactly one Write to the underlying Writer. 1226 // It is the caller's responsibility to not call other Write methods concurrently. 1227 func (f *Framer) WriteRSTStream(streamID uint32, code ErrCode) error { 1228 if !validStreamID(streamID) && !f.AllowIllegalWrites { 1229 return errStreamID 1230 } 1231 f.startWrite(FrameRSTStream, 0, streamID) 1232 f.writeUint32(uint32(code)) 1233 return f.endWrite() 1234 } 1235 1236 // A ContinuationFrame is used to continue a sequence of header block fragments. 1237 // See https://httpwg.org/specs/rfc7540.html#rfc.section.6.10 1238 type ContinuationFrame struct { 1239 FrameHeader 1240 headerFragBuf []byte 1241 } 1242 1243 func parseContinuationFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) { 1244 if fh.StreamID == 0 { 1245 countError("frame_continuation_zero_stream") 1246 return nil, connError{ErrCodeProtocol, "CONTINUATION frame with stream ID 0"} 1247 } 1248 return &ContinuationFrame{fh, p}, nil 1249 } 1250 1251 func (f *ContinuationFrame) HeaderBlockFragment() []byte { 1252 f.checkValid() 1253 return f.headerFragBuf 1254 } 1255 1256 func (f *ContinuationFrame) HeadersEnded() bool { 1257 return f.FrameHeader.Flags.Has(FlagContinuationEndHeaders) 1258 } 1259 1260 // WriteContinuation writes a CONTINUATION frame. 1261 // 1262 // It will perform exactly one Write to the underlying Writer. 1263 // It is the caller's responsibility to not call other Write methods concurrently. 1264 func (f *Framer) WriteContinuation(streamID uint32, endHeaders bool, headerBlockFragment []byte) error { 1265 if !validStreamID(streamID) && !f.AllowIllegalWrites { 1266 return errStreamID 1267 } 1268 var flags Flags 1269 if endHeaders { 1270 flags |= FlagContinuationEndHeaders 1271 } 1272 f.startWrite(FrameContinuation, flags, streamID) 1273 f.wbuf = append(f.wbuf, headerBlockFragment...) 1274 return f.endWrite() 1275 } 1276 1277 // A PushPromiseFrame is used to initiate a server stream. 1278 // See https://httpwg.org/specs/rfc7540.html#rfc.section.6.6 1279 type PushPromiseFrame struct { 1280 FrameHeader 1281 PromiseID uint32 1282 headerFragBuf []byte // not owned 1283 } 1284 1285 func (f *PushPromiseFrame) HeaderBlockFragment() []byte { 1286 f.checkValid() 1287 return f.headerFragBuf 1288 } 1289 1290 func (f *PushPromiseFrame) HeadersEnded() bool { 1291 return f.FrameHeader.Flags.Has(FlagPushPromiseEndHeaders) 1292 } 1293 1294 func parsePushPromise(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (_ Frame, err error) { 1295 pp := &PushPromiseFrame{ 1296 FrameHeader: fh, 1297 } 1298 if pp.StreamID == 0 { 1299 // PUSH_PROMISE frames MUST be associated with an existing, 1300 // peer-initiated stream. The stream identifier of a 1301 // PUSH_PROMISE frame indicates the stream it is associated 1302 // with. If the stream identifier field specifies the value 1303 // 0x0, a recipient MUST respond with a connection error 1304 // (Section 5.4.1) of type PROTOCOL_ERROR. 1305 countError("frame_pushpromise_zero_stream") 1306 return nil, ConnectionError(ErrCodeProtocol) 1307 } 1308 // The PUSH_PROMISE frame includes optional padding. 1309 // Padding fields and flags are identical to those defined for DATA frames 1310 var padLength uint8 1311 if fh.Flags.Has(FlagPushPromisePadded) { 1312 if p, padLength, err = readByte(p); err != nil { 1313 countError("frame_pushpromise_pad_short") 1314 return 1315 } 1316 } 1317 1318 p, pp.PromiseID, err = readUint32(p) 1319 if err != nil { 1320 countError("frame_pushpromise_promiseid_short") 1321 return 1322 } 1323 pp.PromiseID = pp.PromiseID & (1<<31 - 1) 1324 1325 if int(padLength) > len(p) { 1326 // like the DATA frame, error out if padding is longer than the body. 1327 countError("frame_pushpromise_pad_too_big") 1328 return nil, ConnectionError(ErrCodeProtocol) 1329 } 1330 pp.headerFragBuf = p[:len(p)-int(padLength)] 1331 return pp, nil 1332 } 1333 1334 // PushPromiseParam are the parameters for writing a PUSH_PROMISE frame. 1335 type PushPromiseParam struct { 1336 // StreamID is the required Stream ID to initiate. 1337 StreamID uint32 1338 1339 // PromiseID is the required Stream ID which this 1340 // Push Promises 1341 PromiseID uint32 1342 1343 // BlockFragment is part (or all) of a Header Block. 1344 BlockFragment []byte 1345 1346 // EndHeaders indicates that this frame contains an entire 1347 // header block and is not followed by any 1348 // CONTINUATION frames. 1349 EndHeaders bool 1350 1351 // PadLength is the optional number of bytes of zeros to add 1352 // to this frame. 1353 PadLength uint8 1354 } 1355 1356 // WritePushPromise writes a single PushPromise Frame. 1357 // 1358 // As with Header Frames, This is the low level call for writing 1359 // individual frames. Continuation frames are handled elsewhere. 1360 // 1361 // It will perform exactly one Write to the underlying Writer. 1362 // It is the caller's responsibility to not call other Write methods concurrently. 1363 func (f *Framer) WritePushPromise(p PushPromiseParam) error { 1364 if !validStreamID(p.StreamID) && !f.AllowIllegalWrites { 1365 return errStreamID 1366 } 1367 var flags Flags 1368 if p.PadLength != 0 { 1369 flags |= FlagPushPromisePadded 1370 } 1371 if p.EndHeaders { 1372 flags |= FlagPushPromiseEndHeaders 1373 } 1374 f.startWrite(FramePushPromise, flags, p.StreamID) 1375 if p.PadLength != 0 { 1376 f.writeByte(p.PadLength) 1377 } 1378 if !validStreamID(p.PromiseID) && !f.AllowIllegalWrites { 1379 return errStreamID 1380 } 1381 f.writeUint32(p.PromiseID) 1382 f.wbuf = append(f.wbuf, p.BlockFragment...) 1383 f.wbuf = append(f.wbuf, padZeros[:p.PadLength]...) 1384 return f.endWrite() 1385 } 1386 1387 // WriteRawFrame writes a raw frame. This can be used to write 1388 // extension frames unknown to this package. 1389 func (f *Framer) WriteRawFrame(t FrameType, flags Flags, streamID uint32, payload []byte) error { 1390 f.startWrite(t, flags, streamID) 1391 f.writeBytes(payload) 1392 return f.endWrite() 1393 } 1394 1395 func readByte(p []byte) (remain []byte, b byte, err error) { 1396 if len(p) == 0 { 1397 return nil, 0, io.ErrUnexpectedEOF 1398 } 1399 return p[1:], p[0], nil 1400 } 1401 1402 func readUint32(p []byte) (remain []byte, v uint32, err error) { 1403 if len(p) < 4 { 1404 return nil, 0, io.ErrUnexpectedEOF 1405 } 1406 return p[4:], binary.BigEndian.Uint32(p[:4]), nil 1407 } 1408 1409 type streamEnder interface { 1410 StreamEnded() bool 1411 } 1412 1413 type headersEnder interface { 1414 HeadersEnded() bool 1415 } 1416 1417 type headersOrContinuation interface { 1418 headersEnder 1419 HeaderBlockFragment() []byte 1420 } 1421 1422 // A MetaHeadersFrame is the representation of one HEADERS frame and 1423 // zero or more contiguous CONTINUATION frames and the decoding of 1424 // their HPACK-encoded contents. 1425 // 1426 // This type of frame does not appear on the wire and is only returned 1427 // by the Framer when Framer.ReadMetaHeaders is set. 1428 type MetaHeadersFrame struct { 1429 *HeadersFrame 1430 1431 // Fields are the fields contained in the HEADERS and 1432 // CONTINUATION frames. The underlying slice is owned by the 1433 // Framer and must not be retained after the next call to 1434 // ReadFrame. 1435 // 1436 // Fields are guaranteed to be in the correct http2 order and 1437 // not have unknown pseudo header fields or invalid header 1438 // field names or values. Required pseudo header fields may be 1439 // missing, however. Use the MetaHeadersFrame.Pseudo accessor 1440 // method access pseudo headers. 1441 Fields []hpack.HeaderField 1442 1443 // Truncated is whether the max header list size limit was hit 1444 // and Fields is incomplete. The hpack decoder state is still 1445 // valid, however. 1446 Truncated bool 1447 } 1448 1449 // PseudoValue returns the given pseudo header field's value. 1450 // The provided pseudo field should not contain the leading colon. 1451 func (mh *MetaHeadersFrame) PseudoValue(pseudo string) string { 1452 for _, hf := range mh.Fields { 1453 if !hf.IsPseudo() { 1454 return "" 1455 } 1456 if hf.Name[1:] == pseudo { 1457 return hf.Value 1458 } 1459 } 1460 return "" 1461 } 1462 1463 // RegularFields returns the regular (non-pseudo) header fields of mh. 1464 // The caller does not own the returned slice. 1465 func (mh *MetaHeadersFrame) RegularFields() []hpack.HeaderField { 1466 for i, hf := range mh.Fields { 1467 if !hf.IsPseudo() { 1468 return mh.Fields[i:] 1469 } 1470 } 1471 return nil 1472 } 1473 1474 // PseudoFields returns the pseudo header fields of mh. 1475 // The caller does not own the returned slice. 1476 func (mh *MetaHeadersFrame) PseudoFields() []hpack.HeaderField { 1477 for i, hf := range mh.Fields { 1478 if !hf.IsPseudo() { 1479 return mh.Fields[:i] 1480 } 1481 } 1482 return mh.Fields 1483 } 1484 1485 func (mh *MetaHeadersFrame) checkPseudos() error { 1486 var isRequest, isResponse bool 1487 pf := mh.PseudoFields() 1488 for i, hf := range pf { 1489 switch hf.Name { 1490 case ":method", ":path", ":scheme", ":authority": 1491 isRequest = true 1492 case ":status": 1493 isResponse = true 1494 default: 1495 return pseudoHeaderError(hf.Name) 1496 } 1497 // Check for duplicates. 1498 // This would be a bad algorithm, but N is 4. 1499 // And this doesn't allocate. 1500 for _, hf2 := range pf[:i] { 1501 if hf.Name == hf2.Name { 1502 return duplicatePseudoHeaderError(hf.Name) 1503 } 1504 } 1505 } 1506 if isRequest && isResponse { 1507 return errMixPseudoHeaderTypes 1508 } 1509 return nil 1510 } 1511 1512 func (fr *Framer) maxHeaderStringLen() int { 1513 v := int(fr.maxHeaderListSize()) 1514 if v < 0 { 1515 // If maxHeaderListSize overflows an int, use no limit (0). 1516 return 0 1517 } 1518 return v 1519 } 1520 1521 // readMetaFrame returns 0 or more CONTINUATION frames from fr and 1522 // merge them into the provided hf and returns a MetaHeadersFrame 1523 // with the decoded hpack values. 1524 func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) { 1525 if fr.AllowIllegalReads { 1526 return nil, errors.New("illegal use of AllowIllegalReads with ReadMetaHeaders") 1527 } 1528 mh := &MetaHeadersFrame{ 1529 HeadersFrame: hf, 1530 } 1531 var remainSize = fr.maxHeaderListSize() 1532 var sawRegular bool 1533 1534 var invalid error // pseudo header field errors 1535 hdec := fr.ReadMetaHeaders 1536 hdec.SetEmitEnabled(true) 1537 hdec.SetMaxStringLength(fr.maxHeaderStringLen()) 1538 hdec.SetEmitFunc(func(hf hpack.HeaderField) { 1539 if VerboseLogs && fr.logReads { 1540 fr.debugReadLoggerf("http2: decoded hpack field %+v", hf) 1541 } 1542 if !httpguts.ValidHeaderFieldValue(hf.Value) { 1543 // Don't include the value in the error, because it may be sensitive. 1544 invalid = headerFieldValueError(hf.Name) 1545 } 1546 isPseudo := strings.HasPrefix(hf.Name, ":") 1547 if isPseudo { 1548 if sawRegular { 1549 invalid = errPseudoAfterRegular 1550 } 1551 } else { 1552 sawRegular = true 1553 if !validWireHeaderFieldName(hf.Name) { 1554 invalid = headerFieldNameError(hf.Name) 1555 } 1556 } 1557 1558 if invalid != nil { 1559 hdec.SetEmitEnabled(false) 1560 return 1561 } 1562 1563 size := hf.Size() 1564 if size > remainSize { 1565 hdec.SetEmitEnabled(false) 1566 mh.Truncated = true 1567 return 1568 } 1569 remainSize -= size 1570 1571 mh.Fields = append(mh.Fields, hf) 1572 }) 1573 // Lose reference to MetaHeadersFrame: 1574 defer hdec.SetEmitFunc(func(hf hpack.HeaderField) {}) 1575 1576 var hc headersOrContinuation = hf 1577 for { 1578 frag := hc.HeaderBlockFragment() 1579 if _, err := hdec.Write(frag); err != nil { 1580 return nil, ConnectionError(ErrCodeCompression) 1581 } 1582 1583 if hc.HeadersEnded() { 1584 break 1585 } 1586 if f, err := fr.ReadFrame(); err != nil { 1587 return nil, err 1588 } else { 1589 hc = f.(*ContinuationFrame) // guaranteed by checkFrameOrder 1590 } 1591 } 1592 1593 mh.HeadersFrame.headerFragBuf = nil 1594 mh.HeadersFrame.invalidate() 1595 1596 if err := hdec.Close(); err != nil { 1597 return nil, ConnectionError(ErrCodeCompression) 1598 } 1599 if invalid != nil { 1600 fr.errDetail = invalid 1601 if VerboseLogs { 1602 log.Printf("http2: invalid header: %v", invalid) 1603 } 1604 return nil, StreamError{mh.StreamID, ErrCodeProtocol, invalid} 1605 } 1606 if err := mh.checkPseudos(); err != nil { 1607 fr.errDetail = err 1608 if VerboseLogs { 1609 log.Printf("http2: invalid pseudo headers: %v", err) 1610 } 1611 return nil, StreamError{mh.StreamID, ErrCodeProtocol, err} 1612 } 1613 return mh, nil 1614 } 1615 1616 func summarizeFrame(f Frame) string { 1617 var buf bytes.Buffer 1618 f.Header().writeDebug(&buf) 1619 switch f := f.(type) { 1620 case *SettingsFrame: 1621 n := 0 1622 f.ForeachSetting(func(s Setting) error { 1623 n++ 1624 if n == 1 { 1625 buf.WriteString(", settings:") 1626 } 1627 fmt.Fprintf(&buf, " %v=%v,", s.ID, s.Val) 1628 return nil 1629 }) 1630 if n > 0 { 1631 buf.Truncate(buf.Len() - 1) // remove trailing comma 1632 } 1633 case *DataFrame: 1634 data := f.Data() 1635 const max = 256 1636 if len(data) > max { 1637 data = data[:max] 1638 } 1639 fmt.Fprintf(&buf, " data=%q", data) 1640 if len(f.Data()) > max { 1641 fmt.Fprintf(&buf, " (%d bytes omitted)", len(f.Data())-max) 1642 } 1643 case *WindowUpdateFrame: 1644 if f.StreamID == 0 { 1645 buf.WriteString(" (conn)") 1646 } 1647 fmt.Fprintf(&buf, " incr=%v", f.Increment) 1648 case *PingFrame: 1649 fmt.Fprintf(&buf, " ping=%q", f.Data[:]) 1650 case *GoAwayFrame: 1651 fmt.Fprintf(&buf, " LastStreamID=%v ErrCode=%v Debug=%q", 1652 f.LastStreamID, f.ErrCode, f.debugData) 1653 case *RSTStreamFrame: 1654 fmt.Fprintf(&buf, " ErrCode=%v", f.ErrCode) 1655 } 1656 return buf.String() 1657 }