1
2
3
4
5 package http2
6
7 import (
8 "bytes"
9 "encoding/binary"
10 "errors"
11 "fmt"
12 "io"
13 "log"
14 "slices"
15 "strings"
16 "sync"
17
18 "net/http/internal/httpsfv"
19
20 "golang.org/x/net/http2/hpack"
21
22 "golang.org/x/net/http/httpguts"
23 )
24
25 const frameHeaderLen = 9
26
27 var padZeros = make([]byte, 255)
28
29
30
31
32 type FrameType uint8
33
34 const (
35 FrameData FrameType = 0x0
36 FrameHeaders FrameType = 0x1
37 FramePriority FrameType = 0x2
38 FrameRSTStream FrameType = 0x3
39 FrameSettings FrameType = 0x4
40 FramePushPromise FrameType = 0x5
41 FramePing FrameType = 0x6
42 FrameGoAway FrameType = 0x7
43 FrameWindowUpdate FrameType = 0x8
44 FrameContinuation FrameType = 0x9
45 FramePriorityUpdate FrameType = 0x10
46 )
47
48 var frameNames = [...]string{
49 FrameData: "DATA",
50 FrameHeaders: "HEADERS",
51 FramePriority: "PRIORITY",
52 FrameRSTStream: "RST_STREAM",
53 FrameSettings: "SETTINGS",
54 FramePushPromise: "PUSH_PROMISE",
55 FramePing: "PING",
56 FrameGoAway: "GOAWAY",
57 FrameWindowUpdate: "WINDOW_UPDATE",
58 FrameContinuation: "CONTINUATION",
59 FramePriorityUpdate: "PRIORITY_UPDATE",
60 }
61
62 func (t FrameType) String() string {
63 if int(t) < len(frameNames) {
64 return frameNames[t]
65 }
66 return fmt.Sprintf("UNKNOWN_FRAME_TYPE_%d", t)
67 }
68
69
70
71 type Flags uint8
72
73
74 func (f Flags) Has(v Flags) bool {
75 return (f & v) == v
76 }
77
78
79 const (
80
81 FlagDataEndStream Flags = 0x1
82 FlagDataPadded Flags = 0x8
83
84
85 FlagHeadersEndStream Flags = 0x1
86 FlagHeadersEndHeaders Flags = 0x4
87 FlagHeadersPadded Flags = 0x8
88 FlagHeadersPriority Flags = 0x20
89
90
91 FlagSettingsAck Flags = 0x1
92
93
94 FlagPingAck Flags = 0x1
95
96
97 FlagContinuationEndHeaders Flags = 0x4
98
99 FlagPushPromiseEndHeaders Flags = 0x4
100 FlagPushPromisePadded Flags = 0x8
101 )
102
103 var flagName = map[FrameType]map[Flags]string{
104 FrameData: {
105 FlagDataEndStream: "END_STREAM",
106 FlagDataPadded: "PADDED",
107 },
108 FrameHeaders: {
109 FlagHeadersEndStream: "END_STREAM",
110 FlagHeadersEndHeaders: "END_HEADERS",
111 FlagHeadersPadded: "PADDED",
112 FlagHeadersPriority: "PRIORITY",
113 },
114 FrameSettings: {
115 FlagSettingsAck: "ACK",
116 },
117 FramePing: {
118 FlagPingAck: "ACK",
119 },
120 FrameContinuation: {
121 FlagContinuationEndHeaders: "END_HEADERS",
122 },
123 FramePushPromise: {
124 FlagPushPromiseEndHeaders: "END_HEADERS",
125 FlagPushPromisePadded: "PADDED",
126 },
127 }
128
129
130
131
132 type frameParser func(fc *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error)
133
134 var frameParsers = [...]frameParser{
135 FrameData: parseDataFrame,
136 FrameHeaders: parseHeadersFrame,
137 FramePriority: parsePriorityFrame,
138 FrameRSTStream: parseRSTStreamFrame,
139 FrameSettings: parseSettingsFrame,
140 FramePushPromise: parsePushPromise,
141 FramePing: parsePingFrame,
142 FrameGoAway: parseGoAwayFrame,
143 FrameWindowUpdate: parseWindowUpdateFrame,
144 FrameContinuation: parseContinuationFrame,
145 FramePriorityUpdate: parsePriorityUpdateFrame,
146 }
147
148 func typeFrameParser(t FrameType) frameParser {
149 if int(t) < len(frameParsers) {
150 if f := frameParsers[t]; f != nil {
151 return f
152 }
153 }
154 return parseUnknownFrame
155 }
156
157
158
159
160 type FrameHeader struct {
161 valid bool
162
163
164
165
166 Type FrameType
167
168
169
170 Flags Flags
171
172
173
174
175 Length uint32
176
177
178
179 StreamID uint32
180 }
181
182
183
184 func (h FrameHeader) Header() FrameHeader { return h }
185
186 func (h FrameHeader) String() string {
187 var buf bytes.Buffer
188 buf.WriteString("[FrameHeader ")
189 h.writeDebug(&buf)
190 buf.WriteByte(']')
191 return buf.String()
192 }
193
194 func (h FrameHeader) writeDebug(buf *bytes.Buffer) {
195 buf.WriteString(h.Type.String())
196 if h.Flags != 0 {
197 buf.WriteString(" flags=")
198 set := 0
199 for i := range uint8(8) {
200 if h.Flags&(1<<i) == 0 {
201 continue
202 }
203 set++
204 if set > 1 {
205 buf.WriteByte('|')
206 }
207 name := flagName[h.Type][Flags(1<<i)]
208 if name != "" {
209 buf.WriteString(name)
210 } else {
211 fmt.Fprintf(buf, "0x%x", 1<<i)
212 }
213 }
214 }
215 if h.StreamID != 0 {
216 fmt.Fprintf(buf, " stream=%d", h.StreamID)
217 }
218 fmt.Fprintf(buf, " len=%d", h.Length)
219 }
220
221 func (h *FrameHeader) checkValid() {
222 if !h.valid {
223 panic("Frame accessor called on non-owned Frame")
224 }
225 }
226
227 func (h *FrameHeader) invalidate() { h.valid = false }
228
229
230
231 var fhBytes = sync.Pool{
232 New: func() any {
233 buf := make([]byte, frameHeaderLen)
234 return &buf
235 },
236 }
237
238 func invalidHTTP1LookingFrameHeader() FrameHeader {
239 fh, _ := readFrameHeader(make([]byte, frameHeaderLen), strings.NewReader("HTTP/1.1 "))
240 return fh
241 }
242
243
244
245 func ReadFrameHeader(r io.Reader) (FrameHeader, error) {
246 bufp := fhBytes.Get().(*[]byte)
247 defer fhBytes.Put(bufp)
248 return readFrameHeader(*bufp, r)
249 }
250
251 func readFrameHeader(buf []byte, r io.Reader) (FrameHeader, error) {
252 _, err := io.ReadFull(r, buf[:frameHeaderLen])
253 if err != nil {
254 return FrameHeader{}, err
255 }
256 return FrameHeader{
257 Length: (uint32(buf[0])<<16 | uint32(buf[1])<<8 | uint32(buf[2])),
258 Type: FrameType(buf[3]),
259 Flags: Flags(buf[4]),
260 StreamID: binary.BigEndian.Uint32(buf[5:]) & (1<<31 - 1),
261 valid: true,
262 }, nil
263 }
264
265
266
267
268
269
270 type Frame interface {
271 Header() FrameHeader
272
273
274
275
276 invalidate()
277 }
278
279
280 type Framer struct {
281 r io.Reader
282 lastFrame Frame
283 errDetail error
284
285
286
287
288 countError func(errToken string)
289
290
291
292 lastHeaderStream uint32
293
294 lastFrameType FrameType
295
296 maxReadSize uint32
297 headerBuf [frameHeaderLen]byte
298
299
300
301
302 getReadBuf func(size uint32) []byte
303 readBuf []byte
304
305 maxWriteSize uint32
306
307 w io.Writer
308 wbuf []byte
309
310
311
312
313
314
315
316 AllowIllegalWrites bool
317
318
319
320
321
322
323 AllowIllegalReads bool
324
325
326
327
328 ReadMetaHeaders *hpack.Decoder
329
330
331
332
333
334 MaxHeaderListSize uint32
335
336
337
338
339
340 MaxHeaderValueCount int
341
342
343
344
345
346
347
348 logReads, logWrites bool
349
350 debugFramer *Framer
351 debugFramerBuf *bytes.Buffer
352 debugReadLoggerf func(string, ...any)
353 debugWriteLoggerf func(string, ...any)
354
355 frameCache *frameCache
356 }
357
358 func (fr *Framer) maxHeaderListSize() uint32 {
359 if fr.MaxHeaderListSize == 0 {
360 return 16 << 20
361 }
362 return fr.MaxHeaderListSize
363 }
364
365 func (fr *Framer) maxHeaderValueCount() int {
366 return fr.MaxHeaderValueCount
367 }
368
369 func (f *Framer) startWrite(ftype FrameType, flags Flags, streamID uint32) {
370
371 f.wbuf = append(f.wbuf[:0],
372 0,
373 0,
374 0,
375 byte(ftype),
376 byte(flags),
377 byte(streamID>>24),
378 byte(streamID>>16),
379 byte(streamID>>8),
380 byte(streamID))
381 }
382
383 func (f *Framer) endWrite() error {
384
385
386 length := len(f.wbuf) - frameHeaderLen
387 if length >= (1 << 24) {
388 return ErrFrameTooLarge
389 }
390 _ = append(f.wbuf[:0],
391 byte(length>>16),
392 byte(length>>8),
393 byte(length))
394 if f.logWrites {
395 f.logWrite()
396 }
397
398 n, err := f.w.Write(f.wbuf)
399 if err == nil && n != len(f.wbuf) {
400 err = io.ErrShortWrite
401 }
402 return err
403 }
404
405 func (f *Framer) logWrite() {
406 if f.debugFramer == nil {
407 f.debugFramerBuf = new(bytes.Buffer)
408 f.debugFramer = NewFramer(nil, f.debugFramerBuf)
409 f.debugFramer.logReads = false
410
411
412 f.debugFramer.AllowIllegalReads = true
413 }
414 f.debugFramerBuf.Write(f.wbuf)
415 fr, err := f.debugFramer.ReadFrame()
416 if err != nil {
417 f.debugWriteLoggerf("http2: Framer %p: failed to decode just-written frame", f)
418 return
419 }
420 f.debugWriteLoggerf("http2: Framer %p: wrote %v", f, summarizeFrame(fr))
421 }
422
423 func (f *Framer) writeByte(v byte) { f.wbuf = append(f.wbuf, v) }
424 func (f *Framer) writeBytes(v []byte) { f.wbuf = append(f.wbuf, v...) }
425 func (f *Framer) writeUint16(v uint16) { f.wbuf = append(f.wbuf, byte(v>>8), byte(v)) }
426 func (f *Framer) writeUint32(v uint32) {
427 f.wbuf = append(f.wbuf, byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
428 }
429
430 const (
431 minMaxFrameSize = 1 << 14
432 maxFrameSize = 1<<24 - 1
433 )
434
435
436
437
438 func (fr *Framer) SetReuseFrames() {
439 if fr.frameCache != nil {
440 return
441 }
442 fr.frameCache = &frameCache{}
443 }
444
445 type frameCache struct {
446 dataFrame DataFrame
447 }
448
449 func (fc *frameCache) getDataFrame() *DataFrame {
450 if fc == nil {
451 return &DataFrame{}
452 }
453 return &fc.dataFrame
454 }
455
456
457 func NewFramer(w io.Writer, r io.Reader) *Framer {
458 fr := &Framer{
459 w: w,
460 r: r,
461 countError: func(string) {},
462 logReads: logFrameReads,
463 logWrites: logFrameWrites,
464 debugReadLoggerf: log.Printf,
465 debugWriteLoggerf: log.Printf,
466 }
467 fr.getReadBuf = func(size uint32) []byte {
468 if cap(fr.readBuf) >= int(size) {
469 return fr.readBuf[:size]
470 }
471 fr.readBuf = make([]byte, size)
472 return fr.readBuf
473 }
474 fr.SetMaxReadFrameSize(maxFrameSize)
475 return fr
476 }
477
478
479
480
481
482 func (fr *Framer) SetMaxReadFrameSize(v uint32) {
483 if v > maxFrameSize {
484 v = maxFrameSize
485 }
486 fr.maxReadSize = v
487 }
488
489
490
491
492
493
494
495
496 func (fr *Framer) ErrorDetail() error {
497 return fr.errDetail
498 }
499
500
501
502 var ErrFrameTooLarge = errors.New("http2: frame too large")
503
504
505
506 func terminalReadFrameError(err error) bool {
507 if _, ok := err.(StreamError); ok {
508 return false
509 }
510 return err != nil
511 }
512
513
514
515
516
517
518
519
520
521
522
523 func (fr *Framer) ReadFrameHeader() (FrameHeader, error) {
524 fr.errDetail = nil
525 fh, err := readFrameHeader(fr.headerBuf[:], fr.r)
526 if err != nil {
527 return fh, err
528 }
529 if fh.Length > fr.maxReadSize {
530 if fh == invalidHTTP1LookingFrameHeader() {
531 return fh, fmt.Errorf("http2: failed reading the frame payload: %w, note that the frame header looked like an HTTP/1.1 header", ErrFrameTooLarge)
532 }
533 return fh, ErrFrameTooLarge
534 }
535 if err := fr.checkFrameOrder(fh); err != nil {
536 return fh, err
537 }
538 return fh, nil
539 }
540
541
542
543
544
545 func (fr *Framer) ReadFrameForHeader(fh FrameHeader) (Frame, error) {
546 if fr.lastFrame != nil {
547 fr.lastFrame.invalidate()
548 }
549 payload := fr.getReadBuf(fh.Length)
550 if _, err := io.ReadFull(fr.r, payload); err != nil {
551 if fh == invalidHTTP1LookingFrameHeader() {
552 return nil, fmt.Errorf("http2: failed reading the frame payload: %w, note that the frame header looked like an HTTP/1.1 header", err)
553 }
554 return nil, err
555 }
556 f, err := typeFrameParser(fh.Type)(fr.frameCache, fh, fr.countError, payload)
557 if err != nil {
558 if ce, ok := err.(connError); ok {
559 return nil, fr.connError(ce.Code, ce.Reason)
560 }
561 return nil, err
562 }
563 fr.lastFrame = f
564 if fr.logReads {
565 fr.debugReadLoggerf("http2: Framer %p: read %v", fr, summarizeFrame(f))
566 }
567 if fh.Type == FrameHeaders && fr.ReadMetaHeaders != nil {
568 return fr.readMetaFrame(f.(*HeadersFrame))
569 }
570 return f, nil
571 }
572
573
574
575
576
577
578
579
580
581
582
583 func (fr *Framer) ReadFrame() (Frame, error) {
584 fh, err := fr.ReadFrameHeader()
585 if err != nil {
586 return nil, err
587 }
588 return fr.ReadFrameForHeader(fh)
589 }
590
591
592
593
594
595 func (fr *Framer) connError(code ErrCode, reason string) error {
596 fr.errDetail = errors.New(reason)
597 return ConnectionError(code)
598 }
599
600
601
602
603 func (fr *Framer) checkFrameOrder(fh FrameHeader) error {
604 lastType := fr.lastFrameType
605 fr.lastFrameType = fh.Type
606 if fr.AllowIllegalReads {
607 return nil
608 }
609
610 if fr.lastHeaderStream != 0 {
611 if fh.Type != FrameContinuation {
612 return fr.connError(ErrCodeProtocol,
613 fmt.Sprintf("got %s for stream %d; expected CONTINUATION following %s for stream %d",
614 fh.Type, fh.StreamID,
615 lastType, fr.lastHeaderStream))
616 }
617 if fh.StreamID != fr.lastHeaderStream {
618 return fr.connError(ErrCodeProtocol,
619 fmt.Sprintf("got CONTINUATION for stream %d; expected stream %d",
620 fh.StreamID, fr.lastHeaderStream))
621 }
622 } else if fh.Type == FrameContinuation {
623 return fr.connError(ErrCodeProtocol, fmt.Sprintf("unexpected CONTINUATION for stream %d", fh.StreamID))
624 }
625
626 switch fh.Type {
627 case FrameHeaders, FrameContinuation:
628 if fh.Flags.Has(FlagHeadersEndHeaders) {
629 fr.lastHeaderStream = 0
630 } else {
631 fr.lastHeaderStream = fh.StreamID
632 }
633 }
634
635 return nil
636 }
637
638
639
640
641 type DataFrame struct {
642 FrameHeader
643 data []byte
644 }
645
646 func (f *DataFrame) StreamEnded() bool {
647 return f.FrameHeader.Flags.Has(FlagDataEndStream)
648 }
649
650
651
652
653
654 func (f *DataFrame) Data() []byte {
655 f.checkValid()
656 return f.data
657 }
658
659 func parseDataFrame(fc *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error) {
660 if fh.StreamID == 0 {
661
662
663
664
665
666 countError("frame_data_stream_0")
667 return nil, connError{ErrCodeProtocol, "DATA frame with stream ID 0"}
668 }
669 f := fc.getDataFrame()
670 f.FrameHeader = fh
671
672 var padSize byte
673 if fh.Flags.Has(FlagDataPadded) {
674 var err error
675 payload, padSize, err = readByte(payload)
676 if err != nil {
677 countError("frame_data_pad_byte_short")
678 return nil, err
679 }
680 }
681 if int(padSize) > len(payload) {
682
683
684
685
686 countError("frame_data_pad_too_big")
687 return nil, connError{ErrCodeProtocol, "pad size larger than data payload"}
688 }
689 f.data = payload[:len(payload)-int(padSize)]
690 return f, nil
691 }
692
693 var (
694 errStreamID = errors.New("invalid stream ID")
695 errDepStreamID = errors.New("invalid dependent stream ID")
696 errPadLength = errors.New("pad length too large")
697 errPadBytes = errors.New("padding bytes must all be zeros unless AllowIllegalWrites is enabled")
698 )
699
700 func validStreamIDOrZero(streamID uint32) bool {
701 return streamID&(1<<31) == 0
702 }
703
704 func validStreamID(streamID uint32) bool {
705 return streamID != 0 && streamID&(1<<31) == 0
706 }
707
708
709
710
711
712
713 func (f *Framer) WriteData(streamID uint32, endStream bool, data []byte) error {
714 return f.WriteDataPadded(streamID, endStream, data, nil)
715 }
716
717
718
719
720
721
722
723
724
725
726 func (f *Framer) WriteDataPadded(streamID uint32, endStream bool, data, pad []byte) error {
727 if err := f.startWriteDataPadded(streamID, endStream, data, pad); err != nil {
728 return err
729 }
730 return f.endWrite()
731 }
732
733
734
735 func (f *Framer) startWriteDataPadded(streamID uint32, endStream bool, data, pad []byte) error {
736 if !validStreamID(streamID) && !f.AllowIllegalWrites {
737 return errStreamID
738 }
739 if len(pad) > 0 {
740 if len(pad) > 255 {
741 return errPadLength
742 }
743 if !f.AllowIllegalWrites {
744 for _, b := range pad {
745 if b != 0 {
746
747 return errPadBytes
748 }
749 }
750 }
751 }
752 var flags Flags
753 if endStream {
754 flags |= FlagDataEndStream
755 }
756 if pad != nil {
757 flags |= FlagDataPadded
758 }
759 f.startWrite(FrameData, flags, streamID)
760 if pad != nil {
761 f.wbuf = append(f.wbuf, byte(len(pad)))
762 }
763 f.wbuf = append(f.wbuf, data...)
764 f.wbuf = append(f.wbuf, pad...)
765 return nil
766 }
767
768
769
770
771
772
773 type SettingsFrame struct {
774 FrameHeader
775 p []byte
776 }
777
778 func parseSettingsFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {
779 if fh.Flags.Has(FlagSettingsAck) && fh.Length > 0 {
780
781
782
783
784
785
786 countError("frame_settings_ack_with_length")
787 return nil, ConnectionError(ErrCodeFrameSize)
788 }
789 if fh.StreamID != 0 {
790
791
792
793
794
795
796
797 countError("frame_settings_has_stream")
798 return nil, ConnectionError(ErrCodeProtocol)
799 }
800 if len(p)%6 != 0 {
801 countError("frame_settings_mod_6")
802
803 return nil, ConnectionError(ErrCodeFrameSize)
804 }
805 f := &SettingsFrame{FrameHeader: fh, p: p}
806 if v, ok := f.Value(SettingInitialWindowSize); ok && v > (1<<31)-1 {
807 countError("frame_settings_window_size_too_big")
808
809
810
811 return nil, ConnectionError(ErrCodeFlowControl)
812 }
813 return f, nil
814 }
815
816 func (f *SettingsFrame) IsAck() bool {
817 return f.FrameHeader.Flags.Has(FlagSettingsAck)
818 }
819
820 func (f *SettingsFrame) Value(id SettingID) (v uint32, ok bool) {
821 f.checkValid()
822 for i := 0; i < f.NumSettings(); i++ {
823 if s := f.Setting(i); s.ID == id {
824 return s.Val, true
825 }
826 }
827 return 0, false
828 }
829
830
831
832 func (f *SettingsFrame) Setting(i int) Setting {
833 buf := f.p
834 return Setting{
835 ID: SettingID(binary.BigEndian.Uint16(buf[i*6 : i*6+2])),
836 Val: binary.BigEndian.Uint32(buf[i*6+2 : i*6+6]),
837 }
838 }
839
840 func (f *SettingsFrame) NumSettings() int { return len(f.p) / 6 }
841
842
843 func (f *SettingsFrame) HasDuplicates() bool {
844 num := f.NumSettings()
845 if num == 0 {
846 return false
847 }
848
849
850 if num < 10 {
851 for i := range num {
852 idi := f.Setting(i).ID
853 for j := i + 1; j < num; j++ {
854 idj := f.Setting(j).ID
855 if idi == idj {
856 return true
857 }
858 }
859 }
860 return false
861 }
862 seen := map[SettingID]bool{}
863 for i := range num {
864 id := f.Setting(i).ID
865 if seen[id] {
866 return true
867 }
868 seen[id] = true
869 }
870 return false
871 }
872
873
874
875 func (f *SettingsFrame) ForeachSetting(fn func(Setting) error) error {
876 f.checkValid()
877 for i := 0; i < f.NumSettings(); i++ {
878 if err := fn(f.Setting(i)); err != nil {
879 return err
880 }
881 }
882 return nil
883 }
884
885
886
887
888
889
890 func (f *Framer) WriteSettings(settings ...Setting) error {
891 f.startWrite(FrameSettings, 0, 0)
892 for _, s := range settings {
893 f.writeUint16(uint16(s.ID))
894 f.writeUint32(s.Val)
895 }
896 return f.endWrite()
897 }
898
899
900
901
902
903 func (f *Framer) WriteSettingsAck() error {
904 f.startWrite(FrameSettings, FlagSettingsAck, 0)
905 return f.endWrite()
906 }
907
908
909
910
911
912 type PingFrame struct {
913 FrameHeader
914 Data [8]byte
915 }
916
917 func (f *PingFrame) IsAck() bool { return f.Flags.Has(FlagPingAck) }
918
919 func parsePingFrame(_ *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error) {
920 if len(payload) != 8 {
921 countError("frame_ping_length")
922 return nil, ConnectionError(ErrCodeFrameSize)
923 }
924 if fh.StreamID != 0 {
925 countError("frame_ping_has_stream")
926 return nil, ConnectionError(ErrCodeProtocol)
927 }
928 f := &PingFrame{FrameHeader: fh}
929 copy(f.Data[:], payload)
930 return f, nil
931 }
932
933 func (f *Framer) WritePing(ack bool, data [8]byte) error {
934 var flags Flags
935 if ack {
936 flags = FlagPingAck
937 }
938 f.startWrite(FramePing, flags, 0)
939 f.writeBytes(data[:])
940 return f.endWrite()
941 }
942
943
944
945 type GoAwayFrame struct {
946 FrameHeader
947 LastStreamID uint32
948 ErrCode ErrCode
949 debugData []byte
950 }
951
952
953
954
955
956 func (f *GoAwayFrame) DebugData() []byte {
957 f.checkValid()
958 return f.debugData
959 }
960
961 func parseGoAwayFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {
962 if fh.StreamID != 0 {
963 countError("frame_goaway_has_stream")
964 return nil, ConnectionError(ErrCodeProtocol)
965 }
966 if len(p) < 8 {
967 countError("frame_goaway_short")
968 return nil, ConnectionError(ErrCodeFrameSize)
969 }
970 return &GoAwayFrame{
971 FrameHeader: fh,
972 LastStreamID: binary.BigEndian.Uint32(p[:4]) & (1<<31 - 1),
973 ErrCode: ErrCode(binary.BigEndian.Uint32(p[4:8])),
974 debugData: p[8:],
975 }, nil
976 }
977
978 func (f *Framer) WriteGoAway(maxStreamID uint32, code ErrCode, debugData []byte) error {
979 f.startWrite(FrameGoAway, 0, 0)
980 f.writeUint32(maxStreamID & (1<<31 - 1))
981 f.writeUint32(uint32(code))
982 f.writeBytes(debugData)
983 return f.endWrite()
984 }
985
986
987
988 type UnknownFrame struct {
989 FrameHeader
990 p []byte
991 }
992
993
994
995
996
997
998 func (f *UnknownFrame) Payload() []byte {
999 f.checkValid()
1000 return f.p
1001 }
1002
1003 func parseUnknownFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {
1004 return &UnknownFrame{fh, p}, nil
1005 }
1006
1007
1008
1009 type WindowUpdateFrame struct {
1010 FrameHeader
1011 Increment uint32
1012 }
1013
1014 func parseWindowUpdateFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {
1015 if len(p) != 4 {
1016 countError("frame_windowupdate_bad_len")
1017 return nil, ConnectionError(ErrCodeFrameSize)
1018 }
1019 inc := binary.BigEndian.Uint32(p[:4]) & 0x7fffffff
1020 if inc == 0 {
1021
1022
1023
1024
1025
1026
1027 if fh.StreamID == 0 {
1028 countError("frame_windowupdate_zero_inc_conn")
1029 return nil, ConnectionError(ErrCodeProtocol)
1030 }
1031 countError("frame_windowupdate_zero_inc_stream")
1032 return nil, streamError(fh.StreamID, ErrCodeProtocol)
1033 }
1034 return &WindowUpdateFrame{
1035 FrameHeader: fh,
1036 Increment: inc,
1037 }, nil
1038 }
1039
1040
1041
1042
1043
1044 func (f *Framer) WriteWindowUpdate(streamID, incr uint32) error {
1045
1046 if (incr < 1 || incr > 2147483647) && !f.AllowIllegalWrites {
1047 return errors.New("illegal window increment value")
1048 }
1049 f.startWrite(FrameWindowUpdate, 0, streamID)
1050 f.writeUint32(incr)
1051 return f.endWrite()
1052 }
1053
1054
1055
1056 type HeadersFrame struct {
1057 FrameHeader
1058
1059
1060 Priority PriorityParam
1061
1062 headerFragBuf []byte
1063 }
1064
1065 func (f *HeadersFrame) HeaderBlockFragment() []byte {
1066 f.checkValid()
1067 return f.headerFragBuf
1068 }
1069
1070 func (f *HeadersFrame) HeadersEnded() bool {
1071 return f.FrameHeader.Flags.Has(FlagHeadersEndHeaders)
1072 }
1073
1074 func (f *HeadersFrame) StreamEnded() bool {
1075 return f.FrameHeader.Flags.Has(FlagHeadersEndStream)
1076 }
1077
1078 func (f *HeadersFrame) HasPriority() bool {
1079 return f.FrameHeader.Flags.Has(FlagHeadersPriority)
1080 }
1081
1082 func parseHeadersFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (_ Frame, err error) {
1083 hf := &HeadersFrame{
1084 FrameHeader: fh,
1085 }
1086 if fh.StreamID == 0 {
1087
1088
1089
1090
1091 countError("frame_headers_zero_stream")
1092 return nil, connError{ErrCodeProtocol, "HEADERS frame with stream ID 0"}
1093 }
1094 var padLength uint8
1095 if fh.Flags.Has(FlagHeadersPadded) {
1096 if p, padLength, err = readByte(p); err != nil {
1097 countError("frame_headers_pad_short")
1098 return
1099 }
1100 }
1101 if fh.Flags.Has(FlagHeadersPriority) {
1102 var v uint32
1103 p, v, err = readUint32(p)
1104 if err != nil {
1105 countError("frame_headers_prio_short")
1106 return nil, err
1107 }
1108 hf.Priority.StreamDep = v & 0x7fffffff
1109 hf.Priority.Exclusive = (v != hf.Priority.StreamDep)
1110 p, hf.Priority.Weight, err = readByte(p)
1111 if err != nil {
1112 countError("frame_headers_prio_weight_short")
1113 return nil, err
1114 }
1115 }
1116 if len(p)-int(padLength) < 0 {
1117 countError("frame_headers_pad_too_big")
1118 return nil, streamError(fh.StreamID, ErrCodeProtocol)
1119 }
1120 hf.headerFragBuf = p[:len(p)-int(padLength)]
1121 return hf, nil
1122 }
1123
1124
1125 type HeadersFrameParam struct {
1126
1127 StreamID uint32
1128
1129 BlockFragment []byte
1130
1131
1132
1133
1134
1135 EndStream bool
1136
1137
1138
1139
1140 EndHeaders bool
1141
1142
1143
1144 PadLength uint8
1145
1146
1147
1148 Priority PriorityParam
1149 }
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159 func (f *Framer) WriteHeaders(p HeadersFrameParam) error {
1160 if !validStreamID(p.StreamID) && !f.AllowIllegalWrites {
1161 return errStreamID
1162 }
1163 var flags Flags
1164 if p.PadLength != 0 {
1165 flags |= FlagHeadersPadded
1166 }
1167 if p.EndStream {
1168 flags |= FlagHeadersEndStream
1169 }
1170 if p.EndHeaders {
1171 flags |= FlagHeadersEndHeaders
1172 }
1173 if !p.Priority.IsZero() {
1174 flags |= FlagHeadersPriority
1175 }
1176 f.startWrite(FrameHeaders, flags, p.StreamID)
1177 if p.PadLength != 0 {
1178 f.writeByte(p.PadLength)
1179 }
1180 if !p.Priority.IsZero() {
1181 v := p.Priority.StreamDep
1182 if !validStreamIDOrZero(v) && !f.AllowIllegalWrites {
1183 return errDepStreamID
1184 }
1185 if p.Priority.Exclusive {
1186 v |= 1 << 31
1187 }
1188 f.writeUint32(v)
1189 f.writeByte(p.Priority.Weight)
1190 }
1191 f.wbuf = append(f.wbuf, p.BlockFragment...)
1192 f.wbuf = append(f.wbuf, padZeros[:p.PadLength]...)
1193 return f.endWrite()
1194 }
1195
1196
1197
1198 type PriorityFrame struct {
1199 FrameHeader
1200 PriorityParam
1201 }
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220 func defaultRFC9218Priority(canUseDefault bool) PriorityParam {
1221 if canUseDefault {
1222 return PriorityParam{
1223 urgency: 3,
1224 incremental: 0,
1225 }
1226 }
1227 return PriorityParam{
1228 urgency: 3,
1229 incremental: 1,
1230 }
1231 }
1232
1233
1234
1235
1236
1237
1238 type PriorityParam struct {
1239
1240
1241
1242 StreamDep uint32
1243
1244
1245 Exclusive bool
1246
1247
1248
1249
1250
1251 Weight uint8
1252
1253
1254
1255
1256 urgency uint8
1257
1258
1259
1260
1261
1262
1263
1264
1265 incremental uint8
1266 }
1267
1268 func (p PriorityParam) IsZero() bool {
1269 return p == PriorityParam{}
1270 }
1271
1272 func parsePriorityFrame(_ *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error) {
1273 if fh.StreamID == 0 {
1274 countError("frame_priority_zero_stream")
1275 return nil, connError{ErrCodeProtocol, "PRIORITY frame with stream ID 0"}
1276 }
1277 if len(payload) != 5 {
1278 countError("frame_priority_bad_length")
1279 return nil, connError{ErrCodeFrameSize, fmt.Sprintf("PRIORITY frame payload size was %d; want 5", len(payload))}
1280 }
1281 v := binary.BigEndian.Uint32(payload[:4])
1282 streamID := v & 0x7fffffff
1283 return &PriorityFrame{
1284 FrameHeader: fh,
1285 PriorityParam: PriorityParam{
1286 Weight: payload[4],
1287 StreamDep: streamID,
1288 Exclusive: streamID != v,
1289 },
1290 }, nil
1291 }
1292
1293
1294
1295
1296
1297 func (f *Framer) WritePriority(streamID uint32, p PriorityParam) error {
1298 if !validStreamID(streamID) && !f.AllowIllegalWrites {
1299 return errStreamID
1300 }
1301 if !validStreamIDOrZero(p.StreamDep) {
1302 return errDepStreamID
1303 }
1304 f.startWrite(FramePriority, 0, streamID)
1305 v := p.StreamDep
1306 if p.Exclusive {
1307 v |= 1 << 31
1308 }
1309 f.writeUint32(v)
1310 f.writeByte(p.Weight)
1311 return f.endWrite()
1312 }
1313
1314
1315
1316 type PriorityUpdateFrame struct {
1317 FrameHeader
1318 Priority string
1319 PrioritizedStreamID uint32
1320 }
1321
1322 func parseRFC9218Priority(s string, canUseDefault bool) (p PriorityParam, ok bool) {
1323 p = defaultRFC9218Priority(canUseDefault)
1324 ok = httpsfv.ParseDictionary(s, func(key, val, _ string) {
1325 switch key {
1326 case "u":
1327 if u, ok := httpsfv.ParseInteger(val); ok && u >= 0 && u <= 7 {
1328 p.urgency = uint8(u)
1329 }
1330 case "i":
1331 if i, ok := httpsfv.ParseBoolean(val); ok {
1332 if i {
1333 p.incremental = 1
1334 } else {
1335 p.incremental = 0
1336 }
1337 }
1338 }
1339 })
1340 if !ok {
1341 return defaultRFC9218Priority(canUseDefault), ok
1342 }
1343 return p, true
1344 }
1345
1346 func parsePriorityUpdateFrame(_ *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error) {
1347 if fh.StreamID != 0 {
1348 countError("frame_priority_update_non_zero_stream")
1349 return nil, connError{ErrCodeProtocol, "PRIORITY_UPDATE frame with non-zero stream ID"}
1350 }
1351 if len(payload) < 4 {
1352 countError("frame_priority_update_bad_length")
1353 return nil, connError{ErrCodeFrameSize, fmt.Sprintf("PRIORITY_UPDATE frame payload size was %d; want at least 4", len(payload))}
1354 }
1355 v := binary.BigEndian.Uint32(payload[:4])
1356 streamID := v & 0x7fffffff
1357 if streamID == 0 {
1358 countError("frame_priority_update_prioritizing_zero_stream")
1359 return nil, connError{ErrCodeProtocol, "PRIORITY_UPDATE frame with prioritized stream ID of zero"}
1360 }
1361 return &PriorityUpdateFrame{
1362 FrameHeader: fh,
1363 PrioritizedStreamID: streamID,
1364 Priority: string(payload[4:]),
1365 }, nil
1366 }
1367
1368
1369
1370
1371
1372 func (f *Framer) WritePriorityUpdate(streamID uint32, priority string) error {
1373 if !validStreamID(streamID) && !f.AllowIllegalWrites {
1374 return errStreamID
1375 }
1376 f.startWrite(FramePriorityUpdate, 0, 0)
1377 f.writeUint32(streamID)
1378 f.writeBytes([]byte(priority))
1379 return f.endWrite()
1380 }
1381
1382
1383
1384 type RSTStreamFrame struct {
1385 FrameHeader
1386 ErrCode ErrCode
1387 }
1388
1389 func parseRSTStreamFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {
1390 if len(p) != 4 {
1391 countError("frame_rststream_bad_len")
1392 return nil, ConnectionError(ErrCodeFrameSize)
1393 }
1394 if fh.StreamID == 0 {
1395 countError("frame_rststream_zero_stream")
1396 return nil, ConnectionError(ErrCodeProtocol)
1397 }
1398 return &RSTStreamFrame{fh, ErrCode(binary.BigEndian.Uint32(p[:4]))}, nil
1399 }
1400
1401
1402
1403
1404
1405 func (f *Framer) WriteRSTStream(streamID uint32, code ErrCode) error {
1406 if !validStreamID(streamID) && !f.AllowIllegalWrites {
1407 return errStreamID
1408 }
1409 f.startWrite(FrameRSTStream, 0, streamID)
1410 f.writeUint32(uint32(code))
1411 return f.endWrite()
1412 }
1413
1414
1415
1416 type ContinuationFrame struct {
1417 FrameHeader
1418 headerFragBuf []byte
1419 }
1420
1421 func parseContinuationFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {
1422 if fh.StreamID == 0 {
1423 countError("frame_continuation_zero_stream")
1424 return nil, connError{ErrCodeProtocol, "CONTINUATION frame with stream ID 0"}
1425 }
1426 return &ContinuationFrame{fh, p}, nil
1427 }
1428
1429 func (f *ContinuationFrame) HeaderBlockFragment() []byte {
1430 f.checkValid()
1431 return f.headerFragBuf
1432 }
1433
1434 func (f *ContinuationFrame) HeadersEnded() bool {
1435 return f.FrameHeader.Flags.Has(FlagContinuationEndHeaders)
1436 }
1437
1438
1439
1440
1441
1442 func (f *Framer) WriteContinuation(streamID uint32, endHeaders bool, headerBlockFragment []byte) error {
1443 if !validStreamID(streamID) && !f.AllowIllegalWrites {
1444 return errStreamID
1445 }
1446 var flags Flags
1447 if endHeaders {
1448 flags |= FlagContinuationEndHeaders
1449 }
1450 f.startWrite(FrameContinuation, flags, streamID)
1451 f.wbuf = append(f.wbuf, headerBlockFragment...)
1452 return f.endWrite()
1453 }
1454
1455
1456
1457 type PushPromiseFrame struct {
1458 FrameHeader
1459 PromiseID uint32
1460 headerFragBuf []byte
1461 }
1462
1463 func (f *PushPromiseFrame) HeaderBlockFragment() []byte {
1464 f.checkValid()
1465 return f.headerFragBuf
1466 }
1467
1468 func (f *PushPromiseFrame) HeadersEnded() bool {
1469 return f.FrameHeader.Flags.Has(FlagPushPromiseEndHeaders)
1470 }
1471
1472 func parsePushPromise(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (_ Frame, err error) {
1473 pp := &PushPromiseFrame{
1474 FrameHeader: fh,
1475 }
1476 if pp.StreamID == 0 {
1477
1478
1479
1480
1481
1482
1483 countError("frame_pushpromise_zero_stream")
1484 return nil, ConnectionError(ErrCodeProtocol)
1485 }
1486
1487
1488 var padLength uint8
1489 if fh.Flags.Has(FlagPushPromisePadded) {
1490 if p, padLength, err = readByte(p); err != nil {
1491 countError("frame_pushpromise_pad_short")
1492 return
1493 }
1494 }
1495
1496 p, pp.PromiseID, err = readUint32(p)
1497 if err != nil {
1498 countError("frame_pushpromise_promiseid_short")
1499 return
1500 }
1501 pp.PromiseID = pp.PromiseID & (1<<31 - 1)
1502
1503 if int(padLength) > len(p) {
1504
1505 countError("frame_pushpromise_pad_too_big")
1506 return nil, ConnectionError(ErrCodeProtocol)
1507 }
1508 pp.headerFragBuf = p[:len(p)-int(padLength)]
1509 return pp, nil
1510 }
1511
1512
1513 type PushPromiseParam struct {
1514
1515 StreamID uint32
1516
1517
1518
1519 PromiseID uint32
1520
1521
1522 BlockFragment []byte
1523
1524
1525
1526
1527 EndHeaders bool
1528
1529
1530
1531 PadLength uint8
1532 }
1533
1534
1535
1536
1537
1538
1539
1540
1541 func (f *Framer) WritePushPromise(p PushPromiseParam) error {
1542 if !validStreamID(p.StreamID) && !f.AllowIllegalWrites {
1543 return errStreamID
1544 }
1545 var flags Flags
1546 if p.PadLength != 0 {
1547 flags |= FlagPushPromisePadded
1548 }
1549 if p.EndHeaders {
1550 flags |= FlagPushPromiseEndHeaders
1551 }
1552 f.startWrite(FramePushPromise, flags, p.StreamID)
1553 if p.PadLength != 0 {
1554 f.writeByte(p.PadLength)
1555 }
1556 if !validStreamID(p.PromiseID) && !f.AllowIllegalWrites {
1557 return errStreamID
1558 }
1559 f.writeUint32(p.PromiseID)
1560 f.wbuf = append(f.wbuf, p.BlockFragment...)
1561 f.wbuf = append(f.wbuf, padZeros[:p.PadLength]...)
1562 return f.endWrite()
1563 }
1564
1565
1566
1567 func (f *Framer) WriteRawFrame(t FrameType, flags Flags, streamID uint32, payload []byte) error {
1568 f.startWrite(t, flags, streamID)
1569 f.writeBytes(payload)
1570 return f.endWrite()
1571 }
1572
1573 func readByte(p []byte) (remain []byte, b byte, err error) {
1574 if len(p) == 0 {
1575 return nil, 0, io.ErrUnexpectedEOF
1576 }
1577 return p[1:], p[0], nil
1578 }
1579
1580 func readUint32(p []byte) (remain []byte, v uint32, err error) {
1581 if len(p) < 4 {
1582 return nil, 0, io.ErrUnexpectedEOF
1583 }
1584 return p[4:], binary.BigEndian.Uint32(p[:4]), nil
1585 }
1586
1587 type streamEnder interface {
1588 StreamEnded() bool
1589 }
1590
1591 type headersEnder interface {
1592 HeadersEnded() bool
1593 }
1594
1595 type headersOrContinuation interface {
1596 headersEnder
1597 HeaderBlockFragment() []byte
1598 }
1599
1600
1601
1602
1603
1604
1605
1606 type MetaHeadersFrame struct {
1607 *HeadersFrame
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619 Fields []hpack.HeaderField
1620
1621
1622
1623
1624 Truncated bool
1625 }
1626
1627
1628
1629 func (mh *MetaHeadersFrame) PseudoValue(pseudo string) string {
1630 for _, hf := range mh.Fields {
1631 if !hf.IsPseudo() {
1632 return ""
1633 }
1634 if hf.Name[1:] == pseudo {
1635 return hf.Value
1636 }
1637 }
1638 return ""
1639 }
1640
1641
1642
1643 func (mh *MetaHeadersFrame) RegularFields() []hpack.HeaderField {
1644 for i, hf := range mh.Fields {
1645 if !hf.IsPseudo() {
1646 return mh.Fields[i:]
1647 }
1648 }
1649 return nil
1650 }
1651
1652
1653
1654 func (mh *MetaHeadersFrame) PseudoFields() []hpack.HeaderField {
1655 for i, hf := range mh.Fields {
1656 if !hf.IsPseudo() {
1657 return mh.Fields[:i]
1658 }
1659 }
1660 return mh.Fields
1661 }
1662
1663 func (mh *MetaHeadersFrame) rfc9218Priority(priorityAware bool) (p PriorityParam, priorityAwareAfter, hasIntermediary bool) {
1664 var s string
1665 for _, field := range mh.Fields {
1666 if field.Name == "priority" {
1667 s = field.Value
1668 priorityAware = true
1669 }
1670 if slices.Contains([]string{"via", "forwarded", "x-forwarded-for"}, field.Name) {
1671 hasIntermediary = true
1672 }
1673 }
1674
1675
1676 p, _ = parseRFC9218Priority(s, priorityAware && !hasIntermediary)
1677 return p, priorityAware, hasIntermediary
1678 }
1679
1680 func (mh *MetaHeadersFrame) checkPseudos() error {
1681 var isRequest, isResponse bool
1682 pf := mh.PseudoFields()
1683 for i, hf := range pf {
1684 switch hf.Name {
1685 case ":method", ":path", ":scheme", ":authority", ":protocol":
1686 isRequest = true
1687 case ":status":
1688 isResponse = true
1689 default:
1690 return pseudoHeaderError(hf.Name)
1691 }
1692
1693
1694
1695 for _, hf2 := range pf[:i] {
1696 if hf.Name == hf2.Name {
1697 return duplicatePseudoHeaderError(hf.Name)
1698 }
1699 }
1700 }
1701 if isRequest && isResponse {
1702 return errMixPseudoHeaderTypes
1703 }
1704 return nil
1705 }
1706
1707 func (fr *Framer) maxHeaderStringLen() int {
1708 v := int(fr.maxHeaderListSize())
1709 if v < 0 {
1710
1711 return 0
1712 }
1713 return v
1714 }
1715
1716
1717
1718
1719 func (fr *Framer) readMetaFrame(hf *HeadersFrame) (Frame, error) {
1720 if fr.AllowIllegalReads {
1721 return nil, errors.New("illegal use of AllowIllegalReads with ReadMetaHeaders")
1722 }
1723 mh := &MetaHeadersFrame{
1724 HeadersFrame: hf,
1725 }
1726 var remainSize = fr.maxHeaderListSize()
1727 var sawRegular bool
1728 var headerCount int
1729
1730 var invalid error
1731 hdec := fr.ReadMetaHeaders
1732 hdec.SetEmitEnabled(true)
1733 hdec.SetMaxStringLength(fr.maxHeaderStringLen())
1734 hdec.SetEmitFunc(func(hf hpack.HeaderField) {
1735 if VerboseLogs && fr.logReads {
1736 fr.debugReadLoggerf("http2: decoded hpack field %+v", hf)
1737 }
1738 headerCount++
1739 if limit := fr.maxHeaderValueCount(); limit > 0 && headerCount > limit {
1740 hdec.SetEmitEnabled(false)
1741 mh.Truncated = true
1742 remainSize = 0
1743 return
1744 }
1745 if !httpguts.ValidHeaderFieldValue(hf.Value) {
1746
1747 invalid = headerFieldValueError(hf.Name)
1748 }
1749 isPseudo := strings.HasPrefix(hf.Name, ":")
1750 if isPseudo {
1751 if sawRegular {
1752 invalid = errPseudoAfterRegular
1753 }
1754 } else {
1755 sawRegular = true
1756 if !validWireHeaderFieldName(hf.Name) {
1757 invalid = headerFieldNameError(hf.Name)
1758 }
1759 }
1760
1761 if invalid != nil {
1762 hdec.SetEmitEnabled(false)
1763 return
1764 }
1765
1766 size := hf.Size()
1767 if size > remainSize {
1768 hdec.SetEmitEnabled(false)
1769 mh.Truncated = true
1770 remainSize = 0
1771 return
1772 }
1773 remainSize -= size
1774
1775 mh.Fields = append(mh.Fields, hf)
1776 })
1777
1778 defer hdec.SetEmitFunc(func(hf hpack.HeaderField) {})
1779
1780 var hc headersOrContinuation = hf
1781 for {
1782 frag := hc.HeaderBlockFragment()
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792 if int64(len(frag)) > int64(2*remainSize) {
1793 if VerboseLogs {
1794 log.Printf("http2: header list too large")
1795 }
1796
1797
1798 return mh, ConnectionError(ErrCodeProtocol)
1799 }
1800
1801
1802
1803
1804 if invalid != nil {
1805 if VerboseLogs {
1806 log.Printf("http2: invalid header: %v", invalid)
1807 }
1808
1809
1810 return mh, ConnectionError(ErrCodeProtocol)
1811 }
1812
1813 if _, err := hdec.Write(frag); err != nil {
1814 return mh, ConnectionError(ErrCodeCompression)
1815 }
1816
1817 if hc.HeadersEnded() {
1818 break
1819 }
1820 if f, err := fr.ReadFrame(); err != nil {
1821 return nil, err
1822 } else {
1823 hc = f.(*ContinuationFrame)
1824 }
1825 }
1826
1827 mh.HeadersFrame.headerFragBuf = nil
1828 mh.HeadersFrame.invalidate()
1829
1830 if err := hdec.Close(); err != nil {
1831 return mh, ConnectionError(ErrCodeCompression)
1832 }
1833 if invalid != nil {
1834 fr.errDetail = invalid
1835 if VerboseLogs {
1836 log.Printf("http2: invalid header: %v", invalid)
1837 }
1838 return nil, StreamError{mh.StreamID, ErrCodeProtocol, invalid}
1839 }
1840 if err := mh.checkPseudos(); err != nil {
1841 fr.errDetail = err
1842 if VerboseLogs {
1843 log.Printf("http2: invalid pseudo headers: %v", err)
1844 }
1845 return nil, StreamError{mh.StreamID, ErrCodeProtocol, err}
1846 }
1847 return mh, nil
1848 }
1849
1850 func summarizeFrame(f Frame) string {
1851 var buf bytes.Buffer
1852 f.Header().writeDebug(&buf)
1853 switch f := f.(type) {
1854 case *SettingsFrame:
1855 n := 0
1856 f.ForeachSetting(func(s Setting) error {
1857 n++
1858 if n == 1 {
1859 buf.WriteString(", settings:")
1860 }
1861 fmt.Fprintf(&buf, " %v=%v,", s.ID, s.Val)
1862 return nil
1863 })
1864 if n > 0 {
1865 buf.Truncate(buf.Len() - 1)
1866 }
1867 case *DataFrame:
1868 data := f.Data()
1869 const max = 256
1870 if len(data) > max {
1871 data = data[:max]
1872 }
1873 fmt.Fprintf(&buf, " data=%q", data)
1874 if len(f.Data()) > max {
1875 fmt.Fprintf(&buf, " (%d bytes omitted)", len(f.Data())-max)
1876 }
1877 case *WindowUpdateFrame:
1878 if f.StreamID == 0 {
1879 buf.WriteString(" (conn)")
1880 }
1881 fmt.Fprintf(&buf, " incr=%v", f.Increment)
1882 case *PingFrame:
1883 fmt.Fprintf(&buf, " ping=%q", f.Data[:])
1884 case *GoAwayFrame:
1885 fmt.Fprintf(&buf, " LastStreamID=%v ErrCode=%v Debug=%q",
1886 f.LastStreamID, f.ErrCode, f.debugData)
1887 case *RSTStreamFrame:
1888 fmt.Fprintf(&buf, " ErrCode=%v", f.ErrCode)
1889 }
1890 return buf.String()
1891 }
1892
View as plain text