diff --git a/http3/frames.go b/http3/frames.go index 679f66c10b9..e096ac1a8c4 100644 --- a/http3/frames.go +++ b/http3/frames.go @@ -14,38 +14,39 @@ type frame interface{} func parseNextFrame(r io.Reader) (frame, error) { qr := quicvarint.NewReader(r) - t, err := quicvarint.Read(qr) - if err != nil { - return nil, err - } - l, err := quicvarint.Read(qr) - if err != nil { - return nil, err - } - - switch t { - case 0x0: - return &dataFrame{Length: l}, nil - case 0x1: - return &headersFrame{Length: l}, nil - case 0x4: - return parseSettingsFrame(r, l) - case 0x3: // CANCEL_PUSH - fallthrough - case 0x5: // PUSH_PROMISE - fallthrough - case 0x7: // GOAWAY - fallthrough - case 0xd: // MAX_PUSH_ID - fallthrough - case 0xe: // DUPLICATE_PUSH - fallthrough - default: - // skip over unknown frames - if _, err := io.CopyN(ioutil.Discard, qr, int64(l)); err != nil { + for { + t, err := quicvarint.Read(qr) + if err != nil { return nil, err } - return parseNextFrame(qr) + l, err := quicvarint.Read(qr) + if err != nil { + return nil, err + } + + switch t { + case 0x0: + return &dataFrame{Length: l}, nil + case 0x1: + return &headersFrame{Length: l}, nil + case 0x4: + return parseSettingsFrame(r, l) + case 0x3: // CANCEL_PUSH + fallthrough + case 0x5: // PUSH_PROMISE + fallthrough + case 0x7: // GOAWAY + fallthrough + case 0xd: // MAX_PUSH_ID + fallthrough + case 0xe: // DUPLICATE_PUSH + fallthrough + default: + // skip over unknown frames + if _, err := io.CopyN(ioutil.Discard, qr, int64(l)); err != nil { + return nil, err + } + } } }