checkFrameOrder reports an error if f is an invalid frame to return next from ReadFrame. Mostly it checks whether HEADERS and CONTINUATION frames are contiguous.
(f Frame)
| 596 | // next from ReadFrame. Mostly it checks whether HEADERS and |
| 597 | // CONTINUATION frames are contiguous. |
| 598 | func (h2f *Framer) checkFrameOrder(f Frame) error { |
| 599 | last := h2f.lastFrame |
| 600 | h2f.lastFrame = f |
| 601 | if h2f.AllowIllegalReads { |
| 602 | return nil |
| 603 | } |
| 604 | |
| 605 | fh := f.Header() |
| 606 | if h2f.lastHeaderStream != 0 { |
| 607 | if fh.Type != FrameContinuation { |
| 608 | return h2f.connError(ErrCodeProtocol, |
| 609 | fmt.Sprintf("got %s for stream %d; expected CONTINUATION following %s for stream %d", |
| 610 | fh.Type, fh.StreamID, |
| 611 | last.Header().Type, h2f.lastHeaderStream)) |
| 612 | } |
| 613 | if fh.StreamID != h2f.lastHeaderStream { |
| 614 | return h2f.connError(ErrCodeProtocol, |
| 615 | fmt.Sprintf("got CONTINUATION for stream %d; expected stream %d", |
| 616 | fh.StreamID, h2f.lastHeaderStream)) |
| 617 | } |
| 618 | } else if fh.Type == FrameContinuation { |
| 619 | return h2f.connError(ErrCodeProtocol, fmt.Sprintf("unexpected CONTINUATION for stream %d", fh.StreamID)) |
| 620 | } |
| 621 | |
| 622 | switch fh.Type { |
| 623 | case FrameHeaders, FrameContinuation: |
| 624 | if fh.Flags.Has(FlagHeadersEndHeaders) { |
| 625 | h2f.lastHeaderStream = 0 |
| 626 | } else { |
| 627 | h2f.lastHeaderStream = fh.StreamID |
| 628 | } |
| 629 | } |
| 630 | |
| 631 | return nil |
| 632 | } |
| 633 | |
| 634 | // A DataFrame conveys arbitrary, variable-length sequences of octets |
| 635 | // associated with a stream. |