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