podman

Форк
0
1688 строк · 48.1 Кб
1
// Copyright 2014 The Go Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
4

5
package http2
6

7
import (
8
	"bytes"
9
	"encoding/binary"
10
	"errors"
11
	"fmt"
12
	"io"
13
	"log"
14
	"strings"
15
	"sync"
16

17
	"golang.org/x/net/http/httpguts"
18
	"golang.org/x/net/http2/hpack"
19
)
20

21
const frameHeaderLen = 9
22

23
var padZeros = make([]byte, 255) // zeros for padding
24

25
// A FrameType is a registered frame type as defined in
26
// https://httpwg.org/specs/rfc7540.html#rfc.section.11.2
27
type FrameType uint8
28

29
const (
30
	FrameData         FrameType = 0x0
31
	FrameHeaders      FrameType = 0x1
32
	FramePriority     FrameType = 0x2
33
	FrameRSTStream    FrameType = 0x3
34
	FrameSettings     FrameType = 0x4
35
	FramePushPromise  FrameType = 0x5
36
	FramePing         FrameType = 0x6
37
	FrameGoAway       FrameType = 0x7
38
	FrameWindowUpdate FrameType = 0x8
39
	FrameContinuation FrameType = 0x9
40
)
41

42
var frameName = map[FrameType]string{
43
	FrameData:         "DATA",
44
	FrameHeaders:      "HEADERS",
45
	FramePriority:     "PRIORITY",
46
	FrameRSTStream:    "RST_STREAM",
47
	FrameSettings:     "SETTINGS",
48
	FramePushPromise:  "PUSH_PROMISE",
49
	FramePing:         "PING",
50
	FrameGoAway:       "GOAWAY",
51
	FrameWindowUpdate: "WINDOW_UPDATE",
52
	FrameContinuation: "CONTINUATION",
53
}
54

55
func (t FrameType) String() string {
56
	if s, ok := frameName[t]; ok {
57
		return s
58
	}
59
	return fmt.Sprintf("UNKNOWN_FRAME_TYPE_%d", uint8(t))
60
}
61

62
// Flags is a bitmask of HTTP/2 flags.
63
// The meaning of flags varies depending on the frame type.
64
type Flags uint8
65

66
// Has reports whether f contains all (0 or more) flags in v.
67
func (f Flags) Has(v Flags) bool {
68
	return (f & v) == v
69
}
70

71
// Frame-specific FrameHeader flag bits.
72
const (
73
	// Data Frame
74
	FlagDataEndStream Flags = 0x1
75
	FlagDataPadded    Flags = 0x8
76

77
	// Headers Frame
78
	FlagHeadersEndStream  Flags = 0x1
79
	FlagHeadersEndHeaders Flags = 0x4
80
	FlagHeadersPadded     Flags = 0x8
81
	FlagHeadersPriority   Flags = 0x20
82

83
	// Settings Frame
84
	FlagSettingsAck Flags = 0x1
85

86
	// Ping Frame
87
	FlagPingAck Flags = 0x1
88

89
	// Continuation Frame
90
	FlagContinuationEndHeaders Flags = 0x4
91

92
	FlagPushPromiseEndHeaders Flags = 0x4
93
	FlagPushPromisePadded     Flags = 0x8
94
)
95

96
var flagName = map[FrameType]map[Flags]string{
97
	FrameData: {
98
		FlagDataEndStream: "END_STREAM",
99
		FlagDataPadded:    "PADDED",
100
	},
101
	FrameHeaders: {
102
		FlagHeadersEndStream:  "END_STREAM",
103
		FlagHeadersEndHeaders: "END_HEADERS",
104
		FlagHeadersPadded:     "PADDED",
105
		FlagHeadersPriority:   "PRIORITY",
106
	},
107
	FrameSettings: {
108
		FlagSettingsAck: "ACK",
109
	},
110
	FramePing: {
111
		FlagPingAck: "ACK",
112
	},
113
	FrameContinuation: {
114
		FlagContinuationEndHeaders: "END_HEADERS",
115
	},
116
	FramePushPromise: {
117
		FlagPushPromiseEndHeaders: "END_HEADERS",
118
		FlagPushPromisePadded:     "PADDED",
119
	},
120
}
121

122
// a frameParser parses a frame given its FrameHeader and payload
123
// bytes. The length of payload will always equal fh.Length (which
124
// might be 0).
125
type frameParser func(fc *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error)
126

127
var frameParsers = map[FrameType]frameParser{
128
	FrameData:         parseDataFrame,
129
	FrameHeaders:      parseHeadersFrame,
130
	FramePriority:     parsePriorityFrame,
131
	FrameRSTStream:    parseRSTStreamFrame,
132
	FrameSettings:     parseSettingsFrame,
133
	FramePushPromise:  parsePushPromise,
134
	FramePing:         parsePingFrame,
135
	FrameGoAway:       parseGoAwayFrame,
136
	FrameWindowUpdate: parseWindowUpdateFrame,
137
	FrameContinuation: parseContinuationFrame,
138
}
139

140
func typeFrameParser(t FrameType) frameParser {
141
	if f := frameParsers[t]; f != nil {
142
		return f
143
	}
144
	return parseUnknownFrame
145
}
146

147
// A FrameHeader is the 9 byte header of all HTTP/2 frames.
148
//
149
// See https://httpwg.org/specs/rfc7540.html#FrameHeader
150
type FrameHeader struct {
151
	valid bool // caller can access []byte fields in the Frame
152

153
	// Type is the 1 byte frame type. There are ten standard frame
154
	// types, but extension frame types may be written by WriteRawFrame
155
	// and will be returned by ReadFrame (as UnknownFrame).
156
	Type FrameType
157

158
	// Flags are the 1 byte of 8 potential bit flags per frame.
159
	// They are specific to the frame type.
160
	Flags Flags
161

162
	// Length is the length of the frame, not including the 9 byte header.
163
	// The maximum size is one byte less than 16MB (uint24), but only
164
	// frames up to 16KB are allowed without peer agreement.
165
	Length uint32
166

167
	// StreamID is which stream this frame is for. Certain frames
168
	// are not stream-specific, in which case this field is 0.
169
	StreamID uint32
170
}
171

172
// Header returns h. It exists so FrameHeaders can be embedded in other
173
// specific frame types and implement the Frame interface.
174
func (h FrameHeader) Header() FrameHeader { return h }
175

176
func (h FrameHeader) String() string {
177
	var buf bytes.Buffer
178
	buf.WriteString("[FrameHeader ")
179
	h.writeDebug(&buf)
180
	buf.WriteByte(']')
181
	return buf.String()
182
}
183

184
func (h FrameHeader) writeDebug(buf *bytes.Buffer) {
185
	buf.WriteString(h.Type.String())
186
	if h.Flags != 0 {
187
		buf.WriteString(" flags=")
188
		set := 0
189
		for i := uint8(0); i < 8; i++ {
190
			if h.Flags&(1<<i) == 0 {
191
				continue
192
			}
193
			set++
194
			if set > 1 {
195
				buf.WriteByte('|')
196
			}
197
			name := flagName[h.Type][Flags(1<<i)]
198
			if name != "" {
199
				buf.WriteString(name)
200
			} else {
201
				fmt.Fprintf(buf, "0x%x", 1<<i)
202
			}
203
		}
204
	}
205
	if h.StreamID != 0 {
206
		fmt.Fprintf(buf, " stream=%d", h.StreamID)
207
	}
208
	fmt.Fprintf(buf, " len=%d", h.Length)
209
}
210

211
func (h *FrameHeader) checkValid() {
212
	if !h.valid {
213
		panic("Frame accessor called on non-owned Frame")
214
	}
215
}
216

217
func (h *FrameHeader) invalidate() { h.valid = false }
218

219
// frame header bytes.
220
// Used only by ReadFrameHeader.
221
var fhBytes = sync.Pool{
222
	New: func() interface{} {
223
		buf := make([]byte, frameHeaderLen)
224
		return &buf
225
	},
226
}
227

228
// ReadFrameHeader reads 9 bytes from r and returns a FrameHeader.
229
// Most users should use Framer.ReadFrame instead.
230
func ReadFrameHeader(r io.Reader) (FrameHeader, error) {
231
	bufp := fhBytes.Get().(*[]byte)
232
	defer fhBytes.Put(bufp)
233
	return readFrameHeader(*bufp, r)
234
}
235

236
func readFrameHeader(buf []byte, r io.Reader) (FrameHeader, error) {
237
	_, err := io.ReadFull(r, buf[:frameHeaderLen])
238
	if err != nil {
239
		return FrameHeader{}, err
240
	}
241
	return FrameHeader{
242
		Length:   (uint32(buf[0])<<16 | uint32(buf[1])<<8 | uint32(buf[2])),
243
		Type:     FrameType(buf[3]),
244
		Flags:    Flags(buf[4]),
245
		StreamID: binary.BigEndian.Uint32(buf[5:]) & (1<<31 - 1),
246
		valid:    true,
247
	}, nil
248
}
249

250
// A Frame is the base interface implemented by all frame types.
251
// Callers will generally type-assert the specific frame type:
252
// *HeadersFrame, *SettingsFrame, *WindowUpdateFrame, etc.
253
//
254
// Frames are only valid until the next call to Framer.ReadFrame.
255
type Frame interface {
256
	Header() FrameHeader
257

258
	// invalidate is called by Framer.ReadFrame to make this
259
	// frame's buffers as being invalid, since the subsequent
260
	// frame will reuse them.
261
	invalidate()
262
}
263

264
// A Framer reads and writes Frames.
265
type Framer struct {
266
	r         io.Reader
267
	lastFrame Frame
268
	errDetail error
269

270
	// countError is a non-nil func that's called on a frame parse
271
	// error with some unique error path token. It's initialized
272
	// from Transport.CountError or Server.CountError.
273
	countError func(errToken string)
274

275
	// lastHeaderStream is non-zero if the last frame was an
276
	// unfinished HEADERS/CONTINUATION.
277
	lastHeaderStream uint32
278

279
	maxReadSize uint32
280
	headerBuf   [frameHeaderLen]byte
281

282
	// TODO: let getReadBuf be configurable, and use a less memory-pinning
283
	// allocator in server.go to minimize memory pinned for many idle conns.
284
	// Will probably also need to make frame invalidation have a hook too.
285
	getReadBuf func(size uint32) []byte
286
	readBuf    []byte // cache for default getReadBuf
287

288
	maxWriteSize uint32 // zero means unlimited; TODO: implement
289

290
	w    io.Writer
291
	wbuf []byte
292

293
	// AllowIllegalWrites permits the Framer's Write methods to
294
	// write frames that do not conform to the HTTP/2 spec. This
295
	// permits using the Framer to test other HTTP/2
296
	// implementations' conformance to the spec.
297
	// If false, the Write methods will prefer to return an error
298
	// rather than comply.
299
	AllowIllegalWrites bool
300

301
	// AllowIllegalReads permits the Framer's ReadFrame method
302
	// to return non-compliant frames or frame orders.
303
	// This is for testing and permits using the Framer to test
304
	// other HTTP/2 implementations' conformance to the spec.
305
	// It is not compatible with ReadMetaHeaders.
306
	AllowIllegalReads bool
307

308
	// ReadMetaHeaders if non-nil causes ReadFrame to merge
309
	// HEADERS and CONTINUATION frames together and return
310
	// MetaHeadersFrame instead.
311
	ReadMetaHeaders *hpack.Decoder
312

313
	// MaxHeaderListSize is the http2 MAX_HEADER_LIST_SIZE.
314
	// It's used only if ReadMetaHeaders is set; 0 means a sane default
315
	// (currently 16MB)
316
	// If the limit is hit, MetaHeadersFrame.Truncated is set true.
317
	MaxHeaderListSize uint32
318

319
	// TODO: track which type of frame & with which flags was sent
320
	// last. Then return an error (unless AllowIllegalWrites) if
321
	// we're in the middle of a header block and a
322
	// non-Continuation or Continuation on a different stream is
323
	// attempted to be written.
324

325
	logReads, logWrites bool
326

327
	debugFramer       *Framer // only use for logging written writes
328
	debugFramerBuf    *bytes.Buffer
329
	debugReadLoggerf  func(string, ...interface{})
330
	debugWriteLoggerf func(string, ...interface{})
331

332
	frameCache *frameCache // nil if frames aren't reused (default)
333
}
334

335
func (fr *Framer) maxHeaderListSize() uint32 {
336
	if fr.MaxHeaderListSize == 0 {
337
		return 16 << 20 // sane default, per docs
338
	}
339
	return fr.MaxHeaderListSize
340
}
341

342
func (f *Framer) startWrite(ftype FrameType, flags Flags, streamID uint32) {
343
	// Write the FrameHeader.
344
	f.wbuf = append(f.wbuf[:0],
345
		0, // 3 bytes of length, filled in in endWrite
346
		0,
347
		0,
348
		byte(ftype),
349
		byte(flags),
350
		byte(streamID>>24),
351
		byte(streamID>>16),
352
		byte(streamID>>8),
353
		byte(streamID))
354
}
355

356
func (f *Framer) endWrite() error {
357
	// Now that we know the final size, fill in the FrameHeader in
358
	// the space previously reserved for it. Abuse append.
359
	length := len(f.wbuf) - frameHeaderLen
360
	if length >= (1 << 24) {
361
		return ErrFrameTooLarge
362
	}
363
	_ = append(f.wbuf[:0],
364
		byte(length>>16),
365
		byte(length>>8),
366
		byte(length))
367
	if f.logWrites {
368
		f.logWrite()
369
	}
370

371
	n, err := f.w.Write(f.wbuf)
372
	if err == nil && n != len(f.wbuf) {
373
		err = io.ErrShortWrite
374
	}
375
	return err
376
}
377

378
func (f *Framer) logWrite() {
379
	if f.debugFramer == nil {
380
		f.debugFramerBuf = new(bytes.Buffer)
381
		f.debugFramer = NewFramer(nil, f.debugFramerBuf)
382
		f.debugFramer.logReads = false // we log it ourselves, saying "wrote" below
383
		// Let us read anything, even if we accidentally wrote it
384
		// in the wrong order:
385
		f.debugFramer.AllowIllegalReads = true
386
	}
387
	f.debugFramerBuf.Write(f.wbuf)
388
	fr, err := f.debugFramer.ReadFrame()
389
	if err != nil {
390
		f.debugWriteLoggerf("http2: Framer %p: failed to decode just-written frame", f)
391
		return
392
	}
393
	f.debugWriteLoggerf("http2: Framer %p: wrote %v", f, summarizeFrame(fr))
394
}
395

396
func (f *Framer) writeByte(v byte)     { f.wbuf = append(f.wbuf, v) }
397
func (f *Framer) writeBytes(v []byte)  { f.wbuf = append(f.wbuf, v...) }
398
func (f *Framer) writeUint16(v uint16) { f.wbuf = append(f.wbuf, byte(v>>8), byte(v)) }
399
func (f *Framer) writeUint32(v uint32) {
400
	f.wbuf = append(f.wbuf, byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
401
}
402

403
const (
404
	minMaxFrameSize = 1 << 14
405
	maxFrameSize    = 1<<24 - 1
406
)
407

408
// SetReuseFrames allows the Framer to reuse Frames.
409
// If called on a Framer, Frames returned by calls to ReadFrame are only
410
// valid until the next call to ReadFrame.
411
func (fr *Framer) SetReuseFrames() {
412
	if fr.frameCache != nil {
413
		return
414
	}
415
	fr.frameCache = &frameCache{}
416
}
417

418
type frameCache struct {
419
	dataFrame DataFrame
420
}
421

422
func (fc *frameCache) getDataFrame() *DataFrame {
423
	if fc == nil {
424
		return &DataFrame{}
425
	}
426
	return &fc.dataFrame
427
}
428

429
// NewFramer returns a Framer that writes frames to w and reads them from r.
430
func NewFramer(w io.Writer, r io.Reader) *Framer {
431
	fr := &Framer{
432
		w:                 w,
433
		r:                 r,
434
		countError:        func(string) {},
435
		logReads:          logFrameReads,
436
		logWrites:         logFrameWrites,
437
		debugReadLoggerf:  log.Printf,
438
		debugWriteLoggerf: log.Printf,
439
	}
440
	fr.getReadBuf = func(size uint32) []byte {
441
		if cap(fr.readBuf) >= int(size) {
442
			return fr.readBuf[:size]
443
		}
444
		fr.readBuf = make([]byte, size)
445
		return fr.readBuf
446
	}
447
	fr.SetMaxReadFrameSize(maxFrameSize)
448
	return fr
449
}
450

451
// SetMaxReadFrameSize sets the maximum size of a frame
452
// that will be read by a subsequent call to ReadFrame.
453
// It is the caller's responsibility to advertise this
454
// limit with a SETTINGS frame.
455
func (fr *Framer) SetMaxReadFrameSize(v uint32) {
456
	if v > maxFrameSize {
457
		v = maxFrameSize
458
	}
459
	fr.maxReadSize = v
460
}
461

462
// ErrorDetail returns a more detailed error of the last error
463
// returned by Framer.ReadFrame. For instance, if ReadFrame
464
// returns a StreamError with code PROTOCOL_ERROR, ErrorDetail
465
// will say exactly what was invalid. ErrorDetail is not guaranteed
466
// to return a non-nil value and like the rest of the http2 package,
467
// its return value is not protected by an API compatibility promise.
468
// ErrorDetail is reset after the next call to ReadFrame.
469
func (fr *Framer) ErrorDetail() error {
470
	return fr.errDetail
471
}
472

473
// ErrFrameTooLarge is returned from Framer.ReadFrame when the peer
474
// sends a frame that is larger than declared with SetMaxReadFrameSize.
475
var ErrFrameTooLarge = errors.New("http2: frame too large")
476

477
// terminalReadFrameError reports whether err is an unrecoverable
478
// error from ReadFrame and no other frames should be read.
479
func terminalReadFrameError(err error) bool {
480
	if _, ok := err.(StreamError); ok {
481
		return false
482
	}
483
	return err != nil
484
}
485

486
// ReadFrame reads a single frame. The returned Frame is only valid
487
// until the next call to ReadFrame.
488
//
489
// If the frame is larger than previously set with SetMaxReadFrameSize, the
490
// returned error is ErrFrameTooLarge. Other errors may be of type
491
// ConnectionError, StreamError, or anything else from the underlying
492
// reader.
493
func (fr *Framer) ReadFrame() (Frame, error) {
494
	fr.errDetail = nil
495
	if fr.lastFrame != nil {
496
		fr.lastFrame.invalidate()
497
	}
498
	fh, err := readFrameHeader(fr.headerBuf[:], fr.r)
499
	if err != nil {
500
		return nil, err
501
	}
502
	if fh.Length > fr.maxReadSize {
503
		return nil, ErrFrameTooLarge
504
	}
505
	payload := fr.getReadBuf(fh.Length)
506
	if _, err := io.ReadFull(fr.r, payload); err != nil {
507
		return nil, err
508
	}
509
	f, err := typeFrameParser(fh.Type)(fr.frameCache, fh, fr.countError, payload)
510
	if err != nil {
511
		if ce, ok := err.(connError); ok {
512
			return nil, fr.connError(ce.Code, ce.Reason)
513
		}
514
		return nil, err
515
	}
516
	if err := fr.checkFrameOrder(f); err != nil {
517
		return nil, err
518
	}
519
	if fr.logReads {
520
		fr.debugReadLoggerf("http2: Framer %p: read %v", fr, summarizeFrame(f))
521
	}
522
	if fh.Type == FrameHeaders && fr.ReadMetaHeaders != nil {
523
		return fr.readMetaFrame(f.(*HeadersFrame))
524
	}
525
	return f, nil
526
}
527

528
// connError returns ConnectionError(code) but first
529
// stashes away a public reason to the caller can optionally relay it
530
// to the peer before hanging up on them. This might help others debug
531
// their implementations.
532
func (fr *Framer) connError(code ErrCode, reason string) error {
533
	fr.errDetail = errors.New(reason)
534
	return ConnectionError(code)
535
}
536

537
// checkFrameOrder reports an error if f is an invalid frame to return
538
// next from ReadFrame. Mostly it checks whether HEADERS and
539
// CONTINUATION frames are contiguous.
540
func (fr *Framer) checkFrameOrder(f Frame) error {
541
	last := fr.lastFrame
542
	fr.lastFrame = f
543
	if fr.AllowIllegalReads {
544
		return nil
545
	}
546

547
	fh := f.Header()
548
	if fr.lastHeaderStream != 0 {
549
		if fh.Type != FrameContinuation {
550
			return fr.connError(ErrCodeProtocol,
551
				fmt.Sprintf("got %s for stream %d; expected CONTINUATION following %s for stream %d",
552
					fh.Type, fh.StreamID,
553
					last.Header().Type, fr.lastHeaderStream))
554
		}
555
		if fh.StreamID != fr.lastHeaderStream {
556
			return fr.connError(ErrCodeProtocol,
557
				fmt.Sprintf("got CONTINUATION for stream %d; expected stream %d",
558
					fh.StreamID, fr.lastHeaderStream))
559
		}
560
	} else if fh.Type == FrameContinuation {
561
		return fr.connError(ErrCodeProtocol, fmt.Sprintf("unexpected CONTINUATION for stream %d", fh.StreamID))
562
	}
563

564
	switch fh.Type {
565
	case FrameHeaders, FrameContinuation:
566
		if fh.Flags.Has(FlagHeadersEndHeaders) {
567
			fr.lastHeaderStream = 0
568
		} else {
569
			fr.lastHeaderStream = fh.StreamID
570
		}
571
	}
572

573
	return nil
574
}
575

576
// A DataFrame conveys arbitrary, variable-length sequences of octets
577
// associated with a stream.
578
// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.1
579
type DataFrame struct {
580
	FrameHeader
581
	data []byte
582
}
583

584
func (f *DataFrame) StreamEnded() bool {
585
	return f.FrameHeader.Flags.Has(FlagDataEndStream)
586
}
587

588
// Data returns the frame's data octets, not including any padding
589
// size byte or padding suffix bytes.
590
// The caller must not retain the returned memory past the next
591
// call to ReadFrame.
592
func (f *DataFrame) Data() []byte {
593
	f.checkValid()
594
	return f.data
595
}
596

597
func parseDataFrame(fc *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error) {
598
	if fh.StreamID == 0 {
599
		// DATA frames MUST be associated with a stream. If a
600
		// DATA frame is received whose stream identifier
601
		// field is 0x0, the recipient MUST respond with a
602
		// connection error (Section 5.4.1) of type
603
		// PROTOCOL_ERROR.
604
		countError("frame_data_stream_0")
605
		return nil, connError{ErrCodeProtocol, "DATA frame with stream ID 0"}
606
	}
607
	f := fc.getDataFrame()
608
	f.FrameHeader = fh
609

610
	var padSize byte
611
	if fh.Flags.Has(FlagDataPadded) {
612
		var err error
613
		payload, padSize, err = readByte(payload)
614
		if err != nil {
615
			countError("frame_data_pad_byte_short")
616
			return nil, err
617
		}
618
	}
619
	if int(padSize) > len(payload) {
620
		// If the length of the padding is greater than the
621
		// length of the frame payload, the recipient MUST
622
		// treat this as a connection error.
623
		// Filed: https://github.com/http2/http2-spec/issues/610
624
		countError("frame_data_pad_too_big")
625
		return nil, connError{ErrCodeProtocol, "pad size larger than data payload"}
626
	}
627
	f.data = payload[:len(payload)-int(padSize)]
628
	return f, nil
629
}
630

631
var (
632
	errStreamID    = errors.New("invalid stream ID")
633
	errDepStreamID = errors.New("invalid dependent stream ID")
634
	errPadLength   = errors.New("pad length too large")
635
	errPadBytes    = errors.New("padding bytes must all be zeros unless AllowIllegalWrites is enabled")
636
)
637

638
func validStreamIDOrZero(streamID uint32) bool {
639
	return streamID&(1<<31) == 0
640
}
641

642
func validStreamID(streamID uint32) bool {
643
	return streamID != 0 && streamID&(1<<31) == 0
644
}
645

646
// WriteData writes a DATA frame.
647
//
648
// It will perform exactly one Write to the underlying Writer.
649
// It is the caller's responsibility not to violate the maximum frame size
650
// and to not call other Write methods concurrently.
651
func (f *Framer) WriteData(streamID uint32, endStream bool, data []byte) error {
652
	return f.WriteDataPadded(streamID, endStream, data, nil)
653
}
654

655
// WriteDataPadded writes a DATA frame with optional padding.
656
//
657
// If pad is nil, the padding bit is not sent.
658
// The length of pad must not exceed 255 bytes.
659
// The bytes of pad must all be zero, unless f.AllowIllegalWrites is set.
660
//
661
// It will perform exactly one Write to the underlying Writer.
662
// It is the caller's responsibility not to violate the maximum frame size
663
// and to not call other Write methods concurrently.
664
func (f *Framer) WriteDataPadded(streamID uint32, endStream bool, data, pad []byte) error {
665
	if err := f.startWriteDataPadded(streamID, endStream, data, pad); err != nil {
666
		return err
667
	}
668
	return f.endWrite()
669
}
670

671
// startWriteDataPadded is WriteDataPadded, but only writes the frame to the Framer's internal buffer.
672
// The caller should call endWrite to flush the frame to the underlying writer.
673
func (f *Framer) startWriteDataPadded(streamID uint32, endStream bool, data, pad []byte) error {
674
	if !validStreamID(streamID) && !f.AllowIllegalWrites {
675
		return errStreamID
676
	}
677
	if len(pad) > 0 {
678
		if len(pad) > 255 {
679
			return errPadLength
680
		}
681
		if !f.AllowIllegalWrites {
682
			for _, b := range pad {
683
				if b != 0 {
684
					// "Padding octets MUST be set to zero when sending."
685
					return errPadBytes
686
				}
687
			}
688
		}
689
	}
690
	var flags Flags
691
	if endStream {
692
		flags |= FlagDataEndStream
693
	}
694
	if pad != nil {
695
		flags |= FlagDataPadded
696
	}
697
	f.startWrite(FrameData, flags, streamID)
698
	if pad != nil {
699
		f.wbuf = append(f.wbuf, byte(len(pad)))
700
	}
701
	f.wbuf = append(f.wbuf, data...)
702
	f.wbuf = append(f.wbuf, pad...)
703
	return nil
704
}
705

706
// A SettingsFrame conveys configuration parameters that affect how
707
// endpoints communicate, such as preferences and constraints on peer
708
// behavior.
709
//
710
// See https://httpwg.org/specs/rfc7540.html#SETTINGS
711
type SettingsFrame struct {
712
	FrameHeader
713
	p []byte
714
}
715

716
func parseSettingsFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {
717
	if fh.Flags.Has(FlagSettingsAck) && fh.Length > 0 {
718
		// When this (ACK 0x1) bit is set, the payload of the
719
		// SETTINGS frame MUST be empty. Receipt of a
720
		// SETTINGS frame with the ACK flag set and a length
721
		// field value other than 0 MUST be treated as a
722
		// connection error (Section 5.4.1) of type
723
		// FRAME_SIZE_ERROR.
724
		countError("frame_settings_ack_with_length")
725
		return nil, ConnectionError(ErrCodeFrameSize)
726
	}
727
	if fh.StreamID != 0 {
728
		// SETTINGS frames always apply to a connection,
729
		// never a single stream. The stream identifier for a
730
		// SETTINGS frame MUST be zero (0x0).  If an endpoint
731
		// receives a SETTINGS frame whose stream identifier
732
		// field is anything other than 0x0, the endpoint MUST
733
		// respond with a connection error (Section 5.4.1) of
734
		// type PROTOCOL_ERROR.
735
		countError("frame_settings_has_stream")
736
		return nil, ConnectionError(ErrCodeProtocol)
737
	}
738
	if len(p)%6 != 0 {
739
		countError("frame_settings_mod_6")
740
		// Expecting even number of 6 byte settings.
741
		return nil, ConnectionError(ErrCodeFrameSize)
742
	}
743
	f := &SettingsFrame{FrameHeader: fh, p: p}
744
	if v, ok := f.Value(SettingInitialWindowSize); ok && v > (1<<31)-1 {
745
		countError("frame_settings_window_size_too_big")
746
		// Values above the maximum flow control window size of 2^31 - 1 MUST
747
		// be treated as a connection error (Section 5.4.1) of type
748
		// FLOW_CONTROL_ERROR.
749
		return nil, ConnectionError(ErrCodeFlowControl)
750
	}
751
	return f, nil
752
}
753

754
func (f *SettingsFrame) IsAck() bool {
755
	return f.FrameHeader.Flags.Has(FlagSettingsAck)
756
}
757

758
func (f *SettingsFrame) Value(id SettingID) (v uint32, ok bool) {
759
	f.checkValid()
760
	for i := 0; i < f.NumSettings(); i++ {
761
		if s := f.Setting(i); s.ID == id {
762
			return s.Val, true
763
		}
764
	}
765
	return 0, false
766
}
767

768
// Setting returns the setting from the frame at the given 0-based index.
769
// The index must be >= 0 and less than f.NumSettings().
770
func (f *SettingsFrame) Setting(i int) Setting {
771
	buf := f.p
772
	return Setting{
773
		ID:  SettingID(binary.BigEndian.Uint16(buf[i*6 : i*6+2])),
774
		Val: binary.BigEndian.Uint32(buf[i*6+2 : i*6+6]),
775
	}
776
}
777

778
func (f *SettingsFrame) NumSettings() int { return len(f.p) / 6 }
779

780
// HasDuplicates reports whether f contains any duplicate setting IDs.
781
func (f *SettingsFrame) HasDuplicates() bool {
782
	num := f.NumSettings()
783
	if num == 0 {
784
		return false
785
	}
786
	// If it's small enough (the common case), just do the n^2
787
	// thing and avoid a map allocation.
788
	if num < 10 {
789
		for i := 0; i < num; i++ {
790
			idi := f.Setting(i).ID
791
			for j := i + 1; j < num; j++ {
792
				idj := f.Setting(j).ID
793
				if idi == idj {
794
					return true
795
				}
796
			}
797
		}
798
		return false
799
	}
800
	seen := map[SettingID]bool{}
801
	for i := 0; i < num; i++ {
802
		id := f.Setting(i).ID
803
		if seen[id] {
804
			return true
805
		}
806
		seen[id] = true
807
	}
808
	return false
809
}
810

811
// ForeachSetting runs fn for each setting.
812
// It stops and returns the first error.
813
func (f *SettingsFrame) ForeachSetting(fn func(Setting) error) error {
814
	f.checkValid()
815
	for i := 0; i < f.NumSettings(); i++ {
816
		if err := fn(f.Setting(i)); err != nil {
817
			return err
818
		}
819
	}
820
	return nil
821
}
822

823
// WriteSettings writes a SETTINGS frame with zero or more settings
824
// specified and the ACK bit not set.
825
//
826
// It will perform exactly one Write to the underlying Writer.
827
// It is the caller's responsibility to not call other Write methods concurrently.
828
func (f *Framer) WriteSettings(settings ...Setting) error {
829
	f.startWrite(FrameSettings, 0, 0)
830
	for _, s := range settings {
831
		f.writeUint16(uint16(s.ID))
832
		f.writeUint32(s.Val)
833
	}
834
	return f.endWrite()
835
}
836

837
// WriteSettingsAck writes an empty SETTINGS frame with the ACK bit set.
838
//
839
// It will perform exactly one Write to the underlying Writer.
840
// It is the caller's responsibility to not call other Write methods concurrently.
841
func (f *Framer) WriteSettingsAck() error {
842
	f.startWrite(FrameSettings, FlagSettingsAck, 0)
843
	return f.endWrite()
844
}
845

846
// A PingFrame is a mechanism for measuring a minimal round trip time
847
// from the sender, as well as determining whether an idle connection
848
// is still functional.
849
// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.7
850
type PingFrame struct {
851
	FrameHeader
852
	Data [8]byte
853
}
854

855
func (f *PingFrame) IsAck() bool { return f.Flags.Has(FlagPingAck) }
856

857
func parsePingFrame(_ *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error) {
858
	if len(payload) != 8 {
859
		countError("frame_ping_length")
860
		return nil, ConnectionError(ErrCodeFrameSize)
861
	}
862
	if fh.StreamID != 0 {
863
		countError("frame_ping_has_stream")
864
		return nil, ConnectionError(ErrCodeProtocol)
865
	}
866
	f := &PingFrame{FrameHeader: fh}
867
	copy(f.Data[:], payload)
868
	return f, nil
869
}
870

871
func (f *Framer) WritePing(ack bool, data [8]byte) error {
872
	var flags Flags
873
	if ack {
874
		flags = FlagPingAck
875
	}
876
	f.startWrite(FramePing, flags, 0)
877
	f.writeBytes(data[:])
878
	return f.endWrite()
879
}
880

881
// A GoAwayFrame informs the remote peer to stop creating streams on this connection.
882
// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.8
883
type GoAwayFrame struct {
884
	FrameHeader
885
	LastStreamID uint32
886
	ErrCode      ErrCode
887
	debugData    []byte
888
}
889

890
// DebugData returns any debug data in the GOAWAY frame. Its contents
891
// are not defined.
892
// The caller must not retain the returned memory past the next
893
// call to ReadFrame.
894
func (f *GoAwayFrame) DebugData() []byte {
895
	f.checkValid()
896
	return f.debugData
897
}
898

899
func parseGoAwayFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {
900
	if fh.StreamID != 0 {
901
		countError("frame_goaway_has_stream")
902
		return nil, ConnectionError(ErrCodeProtocol)
903
	}
904
	if len(p) < 8 {
905
		countError("frame_goaway_short")
906
		return nil, ConnectionError(ErrCodeFrameSize)
907
	}
908
	return &GoAwayFrame{
909
		FrameHeader:  fh,
910
		LastStreamID: binary.BigEndian.Uint32(p[:4]) & (1<<31 - 1),
911
		ErrCode:      ErrCode(binary.BigEndian.Uint32(p[4:8])),
912
		debugData:    p[8:],
913
	}, nil
914
}
915

916
func (f *Framer) WriteGoAway(maxStreamID uint32, code ErrCode, debugData []byte) error {
917
	f.startWrite(FrameGoAway, 0, 0)
918
	f.writeUint32(maxStreamID & (1<<31 - 1))
919
	f.writeUint32(uint32(code))
920
	f.writeBytes(debugData)
921
	return f.endWrite()
922
}
923

924
// An UnknownFrame is the frame type returned when the frame type is unknown
925
// or no specific frame type parser exists.
926
type UnknownFrame struct {
927
	FrameHeader
928
	p []byte
929
}
930

931
// Payload returns the frame's payload (after the header).  It is not
932
// valid to call this method after a subsequent call to
933
// Framer.ReadFrame, nor is it valid to retain the returned slice.
934
// The memory is owned by the Framer and is invalidated when the next
935
// frame is read.
936
func (f *UnknownFrame) Payload() []byte {
937
	f.checkValid()
938
	return f.p
939
}
940

941
func parseUnknownFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {
942
	return &UnknownFrame{fh, p}, nil
943
}
944

945
// A WindowUpdateFrame is used to implement flow control.
946
// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.9
947
type WindowUpdateFrame struct {
948
	FrameHeader
949
	Increment uint32 // never read with high bit set
950
}
951

952
func parseWindowUpdateFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {
953
	if len(p) != 4 {
954
		countError("frame_windowupdate_bad_len")
955
		return nil, ConnectionError(ErrCodeFrameSize)
956
	}
957
	inc := binary.BigEndian.Uint32(p[:4]) & 0x7fffffff // mask off high reserved bit
958
	if inc == 0 {
959
		// A receiver MUST treat the receipt of a
960
		// WINDOW_UPDATE frame with an flow control window
961
		// increment of 0 as a stream error (Section 5.4.2) of
962
		// type PROTOCOL_ERROR; errors on the connection flow
963
		// control window MUST be treated as a connection
964
		// error (Section 5.4.1).
965
		if fh.StreamID == 0 {
966
			countError("frame_windowupdate_zero_inc_conn")
967
			return nil, ConnectionError(ErrCodeProtocol)
968
		}
969
		countError("frame_windowupdate_zero_inc_stream")
970
		return nil, streamError(fh.StreamID, ErrCodeProtocol)
971
	}
972
	return &WindowUpdateFrame{
973
		FrameHeader: fh,
974
		Increment:   inc,
975
	}, nil
976
}
977

978
// WriteWindowUpdate writes a WINDOW_UPDATE frame.
979
// The increment value must be between 1 and 2,147,483,647, inclusive.
980
// If the Stream ID is zero, the window update applies to the
981
// connection as a whole.
982
func (f *Framer) WriteWindowUpdate(streamID, incr uint32) error {
983
	// "The legal range for the increment to the flow control window is 1 to 2^31-1 (2,147,483,647) octets."
984
	if (incr < 1 || incr > 2147483647) && !f.AllowIllegalWrites {
985
		return errors.New("illegal window increment value")
986
	}
987
	f.startWrite(FrameWindowUpdate, 0, streamID)
988
	f.writeUint32(incr)
989
	return f.endWrite()
990
}
991

992
// A HeadersFrame is used to open a stream and additionally carries a
993
// header block fragment.
994
type HeadersFrame struct {
995
	FrameHeader
996

997
	// Priority is set if FlagHeadersPriority is set in the FrameHeader.
998
	Priority PriorityParam
999

1000
	headerFragBuf []byte // not owned
1001
}
1002

1003
func (f *HeadersFrame) HeaderBlockFragment() []byte {
1004
	f.checkValid()
1005
	return f.headerFragBuf
1006
}
1007

1008
func (f *HeadersFrame) HeadersEnded() bool {
1009
	return f.FrameHeader.Flags.Has(FlagHeadersEndHeaders)
1010
}
1011

1012
func (f *HeadersFrame) StreamEnded() bool {
1013
	return f.FrameHeader.Flags.Has(FlagHeadersEndStream)
1014
}
1015

1016
func (f *HeadersFrame) HasPriority() bool {
1017
	return f.FrameHeader.Flags.Has(FlagHeadersPriority)
1018
}
1019

1020
func parseHeadersFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (_ Frame, err error) {
1021
	hf := &HeadersFrame{
1022
		FrameHeader: fh,
1023
	}
1024
	if fh.StreamID == 0 {
1025
		// HEADERS frames MUST be associated with a stream. If a HEADERS frame
1026
		// is received whose stream identifier field is 0x0, the recipient MUST
1027
		// respond with a connection error (Section 5.4.1) of type
1028
		// PROTOCOL_ERROR.
1029
		countError("frame_headers_zero_stream")
1030
		return nil, connError{ErrCodeProtocol, "HEADERS frame with stream ID 0"}
1031
	}
1032
	var padLength uint8
1033
	if fh.Flags.Has(FlagHeadersPadded) {
1034
		if p, padLength, err = readByte(p); err != nil {
1035
			countError("frame_headers_pad_short")
1036
			return
1037
		}
1038
	}
1039
	if fh.Flags.Has(FlagHeadersPriority) {
1040
		var v uint32
1041
		p, v, err = readUint32(p)
1042
		if err != nil {
1043
			countError("frame_headers_prio_short")
1044
			return nil, err
1045
		}
1046
		hf.Priority.StreamDep = v & 0x7fffffff
1047
		hf.Priority.Exclusive = (v != hf.Priority.StreamDep) // high bit was set
1048
		p, hf.Priority.Weight, err = readByte(p)
1049
		if err != nil {
1050
			countError("frame_headers_prio_weight_short")
1051
			return nil, err
1052
		}
1053
	}
1054
	if len(p)-int(padLength) < 0 {
1055
		countError("frame_headers_pad_too_big")
1056
		return nil, streamError(fh.StreamID, ErrCodeProtocol)
1057
	}
1058
	hf.headerFragBuf = p[:len(p)-int(padLength)]
1059
	return hf, nil
1060
}
1061

1062
// HeadersFrameParam are the parameters for writing a HEADERS frame.
1063
type HeadersFrameParam struct {
1064
	// StreamID is the required Stream ID to initiate.
1065
	StreamID uint32
1066
	// BlockFragment is part (or all) of a Header Block.
1067
	BlockFragment []byte
1068

1069
	// EndStream indicates that the header block is the last that
1070
	// the endpoint will send for the identified stream. Setting
1071
	// this flag causes the stream to enter one of "half closed"
1072
	// states.
1073
	EndStream bool
1074

1075
	// EndHeaders indicates that this frame contains an entire
1076
	// header block and is not followed by any
1077
	// CONTINUATION frames.
1078
	EndHeaders bool
1079

1080
	// PadLength is the optional number of bytes of zeros to add
1081
	// to this frame.
1082
	PadLength uint8
1083

1084
	// Priority, if non-zero, includes stream priority information
1085
	// in the HEADER frame.
1086
	Priority PriorityParam
1087
}
1088

1089
// WriteHeaders writes a single HEADERS frame.
1090
//
1091
// This is a low-level header writing method. Encoding headers and
1092
// splitting them into any necessary CONTINUATION frames is handled
1093
// elsewhere.
1094
//
1095
// It will perform exactly one Write to the underlying Writer.
1096
// It is the caller's responsibility to not call other Write methods concurrently.
1097
func (f *Framer) WriteHeaders(p HeadersFrameParam) error {
1098
	if !validStreamID(p.StreamID) && !f.AllowIllegalWrites {
1099
		return errStreamID
1100
	}
1101
	var flags Flags
1102
	if p.PadLength != 0 {
1103
		flags |= FlagHeadersPadded
1104
	}
1105
	if p.EndStream {
1106
		flags |= FlagHeadersEndStream
1107
	}
1108
	if p.EndHeaders {
1109
		flags |= FlagHeadersEndHeaders
1110
	}
1111
	if !p.Priority.IsZero() {
1112
		flags |= FlagHeadersPriority
1113
	}
1114
	f.startWrite(FrameHeaders, flags, p.StreamID)
1115
	if p.PadLength != 0 {
1116
		f.writeByte(p.PadLength)
1117
	}
1118
	if !p.Priority.IsZero() {
1119
		v := p.Priority.StreamDep
1120
		if !validStreamIDOrZero(v) && !f.AllowIllegalWrites {
1121
			return errDepStreamID
1122
		}
1123
		if p.Priority.Exclusive {
1124
			v |= 1 << 31
1125
		}
1126
		f.writeUint32(v)
1127
		f.writeByte(p.Priority.Weight)
1128
	}
1129
	f.wbuf = append(f.wbuf, p.BlockFragment...)
1130
	f.wbuf = append(f.wbuf, padZeros[:p.PadLength]...)
1131
	return f.endWrite()
1132
}
1133

1134
// A PriorityFrame specifies the sender-advised priority of a stream.
1135
// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.3
1136
type PriorityFrame struct {
1137
	FrameHeader
1138
	PriorityParam
1139
}
1140

1141
// PriorityParam are the stream prioritzation parameters.
1142
type PriorityParam struct {
1143
	// StreamDep is a 31-bit stream identifier for the
1144
	// stream that this stream depends on. Zero means no
1145
	// dependency.
1146
	StreamDep uint32
1147

1148
	// Exclusive is whether the dependency is exclusive.
1149
	Exclusive bool
1150

1151
	// Weight is the stream's zero-indexed weight. It should be
1152
	// set together with StreamDep, or neither should be set. Per
1153
	// the spec, "Add one to the value to obtain a weight between
1154
	// 1 and 256."
1155
	Weight uint8
1156
}
1157

1158
func (p PriorityParam) IsZero() bool {
1159
	return p == PriorityParam{}
1160
}
1161

1162
func parsePriorityFrame(_ *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error) {
1163
	if fh.StreamID == 0 {
1164
		countError("frame_priority_zero_stream")
1165
		return nil, connError{ErrCodeProtocol, "PRIORITY frame with stream ID 0"}
1166
	}
1167
	if len(payload) != 5 {
1168
		countError("frame_priority_bad_length")
1169
		return nil, connError{ErrCodeFrameSize, fmt.Sprintf("PRIORITY frame payload size was %d; want 5", len(payload))}
1170
	}
1171
	v := binary.BigEndian.Uint32(payload[:4])
1172
	streamID := v & 0x7fffffff // mask off high bit
1173
	return &PriorityFrame{
1174
		FrameHeader: fh,
1175
		PriorityParam: PriorityParam{
1176
			Weight:    payload[4],
1177
			StreamDep: streamID,
1178
			Exclusive: streamID != v, // was high bit set?
1179
		},
1180
	}, nil
1181
}
1182

1183
// WritePriority writes a PRIORITY frame.
1184
//
1185
// It will perform exactly one Write to the underlying Writer.
1186
// It is the caller's responsibility to not call other Write methods concurrently.
1187
func (f *Framer) WritePriority(streamID uint32, p PriorityParam) error {
1188
	if !validStreamID(streamID) && !f.AllowIllegalWrites {
1189
		return errStreamID
1190
	}
1191
	if !validStreamIDOrZero(p.StreamDep) {
1192
		return errDepStreamID
1193
	}
1194
	f.startWrite(FramePriority, 0, streamID)
1195
	v := p.StreamDep
1196
	if p.Exclusive {
1197
		v |= 1 << 31
1198
	}
1199
	f.writeUint32(v)
1200
	f.writeByte(p.Weight)
1201
	return f.endWrite()
1202
}
1203

1204
// A RSTStreamFrame allows for abnormal termination of a stream.
1205
// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.4
1206
type RSTStreamFrame struct {
1207
	FrameHeader
1208
	ErrCode ErrCode
1209
}
1210

1211
func parseRSTStreamFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {
1212
	if len(p) != 4 {
1213
		countError("frame_rststream_bad_len")
1214
		return nil, ConnectionError(ErrCodeFrameSize)
1215
	}
1216
	if fh.StreamID == 0 {
1217
		countError("frame_rststream_zero_stream")
1218
		return nil, ConnectionError(ErrCodeProtocol)
1219
	}
1220
	return &RSTStreamFrame{fh, ErrCode(binary.BigEndian.Uint32(p[:4]))}, nil
1221
}
1222

1223
// WriteRSTStream writes a RST_STREAM frame.
1224
//
1225
// It will perform exactly one Write to the underlying Writer.
1226
// It is the caller's responsibility to not call other Write methods concurrently.
1227
func (f *Framer) WriteRSTStream(streamID uint32, code ErrCode) error {
1228
	if !validStreamID(streamID) && !f.AllowIllegalWrites {
1229
		return errStreamID
1230
	}
1231
	f.startWrite(FrameRSTStream, 0, streamID)
1232
	f.writeUint32(uint32(code))
1233
	return f.endWrite()
1234
}
1235

1236
// A ContinuationFrame is used to continue a sequence of header block fragments.
1237
// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.10
1238
type ContinuationFrame struct {
1239
	FrameHeader
1240
	headerFragBuf []byte
1241
}
1242

1243
func parseContinuationFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {
1244
	if fh.StreamID == 0 {
1245
		countError("frame_continuation_zero_stream")
1246
		return nil, connError{ErrCodeProtocol, "CONTINUATION frame with stream ID 0"}
1247
	}
1248
	return &ContinuationFrame{fh, p}, nil
1249
}
1250

1251
func (f *ContinuationFrame) HeaderBlockFragment() []byte {
1252
	f.checkValid()
1253
	return f.headerFragBuf
1254
}
1255

1256
func (f *ContinuationFrame) HeadersEnded() bool {
1257
	return f.FrameHeader.Flags.Has(FlagContinuationEndHeaders)
1258
}
1259

1260
// WriteContinuation writes a CONTINUATION frame.
1261
//
1262
// It will perform exactly one Write to the underlying Writer.
1263
// It is the caller's responsibility to not call other Write methods concurrently.
1264
func (f *Framer) WriteContinuation(streamID uint32, endHeaders bool, headerBlockFragment []byte) error {
1265
	if !validStreamID(streamID) && !f.AllowIllegalWrites {
1266
		return errStreamID
1267
	}
1268
	var flags Flags
1269
	if endHeaders {
1270
		flags |= FlagContinuationEndHeaders
1271
	}
1272
	f.startWrite(FrameContinuation, flags, streamID)
1273
	f.wbuf = append(f.wbuf, headerBlockFragment...)
1274
	return f.endWrite()
1275
}
1276

1277
// A PushPromiseFrame is used to initiate a server stream.
1278
// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.6
1279
type PushPromiseFrame struct {
1280
	FrameHeader
1281
	PromiseID     uint32
1282
	headerFragBuf []byte // not owned
1283
}
1284

1285
func (f *PushPromiseFrame) HeaderBlockFragment() []byte {
1286
	f.checkValid()
1287
	return f.headerFragBuf
1288
}
1289

1290
func (f *PushPromiseFrame) HeadersEnded() bool {
1291
	return f.FrameHeader.Flags.Has(FlagPushPromiseEndHeaders)
1292
}
1293

1294
func parsePushPromise(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (_ Frame, err error) {
1295
	pp := &PushPromiseFrame{
1296
		FrameHeader: fh,
1297
	}
1298
	if pp.StreamID == 0 {
1299
		// PUSH_PROMISE frames MUST be associated with an existing,
1300
		// peer-initiated stream. The stream identifier of a
1301
		// PUSH_PROMISE frame indicates the stream it is associated
1302
		// with. If the stream identifier field specifies the value
1303
		// 0x0, a recipient MUST respond with a connection error
1304
		// (Section 5.4.1) of type PROTOCOL_ERROR.
1305
		countError("frame_pushpromise_zero_stream")
1306
		return nil, ConnectionError(ErrCodeProtocol)
1307
	}
1308
	// The PUSH_PROMISE frame includes optional padding.
1309
	// Padding fields and flags are identical to those defined for DATA frames
1310
	var padLength uint8
1311
	if fh.Flags.Has(FlagPushPromisePadded) {
1312
		if p, padLength, err = readByte(p); err != nil {
1313
			countError("frame_pushpromise_pad_short")
1314
			return
1315
		}
1316
	}
1317

1318
	p, pp.PromiseID, err = readUint32(p)
1319
	if err != nil {
1320
		countError("frame_pushpromise_promiseid_short")
1321
		return
1322
	}
1323
	pp.PromiseID = pp.PromiseID & (1<<31 - 1)
1324

1325
	if int(padLength) > len(p) {
1326
		// like the DATA frame, error out if padding is longer than the body.
1327
		countError("frame_pushpromise_pad_too_big")
1328
		return nil, ConnectionError(ErrCodeProtocol)
1329
	}
1330
	pp.headerFragBuf = p[:len(p)-int(padLength)]
1331
	return pp, nil
1332
}
1333

1334
// PushPromiseParam are the parameters for writing a PUSH_PROMISE frame.
1335
type PushPromiseParam struct {
1336
	// StreamID is the required Stream ID to initiate.
1337
	StreamID uint32
1338

1339
	// PromiseID is the required Stream ID which this
1340
	// Push Promises
1341
	PromiseID uint32
1342

1343
	// BlockFragment is part (or all) of a Header Block.
1344
	BlockFragment []byte
1345

1346
	// EndHeaders indicates that this frame contains an entire
1347
	// header block and is not followed by any
1348
	// CONTINUATION frames.
1349
	EndHeaders bool
1350

1351
	// PadLength is the optional number of bytes of zeros to add
1352
	// to this frame.
1353
	PadLength uint8
1354
}
1355

1356
// WritePushPromise writes a single PushPromise Frame.
1357
//
1358
// As with Header Frames, This is the low level call for writing
1359
// individual frames. Continuation frames are handled elsewhere.
1360
//
1361
// It will perform exactly one Write to the underlying Writer.
1362
// It is the caller's responsibility to not call other Write methods concurrently.
1363
func (f *Framer) WritePushPromise(p PushPromiseParam) error {
1364
	if !validStreamID(p.StreamID) && !f.AllowIllegalWrites {
1365
		return errStreamID
1366
	}
1367
	var flags Flags
1368
	if p.PadLength != 0 {
1369
		flags |= FlagPushPromisePadded
1370
	}
1371
	if p.EndHeaders {
1372
		flags |= FlagPushPromiseEndHeaders
1373
	}
1374
	f.startWrite(FramePushPromise, flags, p.StreamID)
1375
	if p.PadLength != 0 {
1376
		f.writeByte(p.PadLength)
1377
	}
1378
	if !validStreamID(p.PromiseID) && !f.AllowIllegalWrites {
1379
		return errStreamID
1380
	}
1381
	f.writeUint32(p.PromiseID)
1382
	f.wbuf = append(f.wbuf, p.BlockFragment...)
1383
	f.wbuf = append(f.wbuf, padZeros[:p.PadLength]...)
1384
	return f.endWrite()
1385
}
1386

1387
// WriteRawFrame writes a raw frame. This can be used to write
1388
// extension frames unknown to this package.
1389
func (f *Framer) WriteRawFrame(t FrameType, flags Flags, streamID uint32, payload []byte) error {
1390
	f.startWrite(t, flags, streamID)
1391
	f.writeBytes(payload)
1392
	return f.endWrite()
1393
}
1394

1395
func readByte(p []byte) (remain []byte, b byte, err error) {
1396
	if len(p) == 0 {
1397
		return nil, 0, io.ErrUnexpectedEOF
1398
	}
1399
	return p[1:], p[0], nil
1400
}
1401

1402
func readUint32(p []byte) (remain []byte, v uint32, err error) {
1403
	if len(p) < 4 {
1404
		return nil, 0, io.ErrUnexpectedEOF
1405
	}
1406
	return p[4:], binary.BigEndian.Uint32(p[:4]), nil
1407
}
1408

1409
type streamEnder interface {
1410
	StreamEnded() bool
1411
}
1412

1413
type headersEnder interface {
1414
	HeadersEnded() bool
1415
}
1416

1417
type headersOrContinuation interface {
1418
	headersEnder
1419
	HeaderBlockFragment() []byte
1420
}
1421

1422
// A MetaHeadersFrame is the representation of one HEADERS frame and
1423
// zero or more contiguous CONTINUATION frames and the decoding of
1424
// their HPACK-encoded contents.
1425
//
1426
// This type of frame does not appear on the wire and is only returned
1427
// by the Framer when Framer.ReadMetaHeaders is set.
1428
type MetaHeadersFrame struct {
1429
	*HeadersFrame
1430

1431
	// Fields are the fields contained in the HEADERS and
1432
	// CONTINUATION frames. The underlying slice is owned by the
1433
	// Framer and must not be retained after the next call to
1434
	// ReadFrame.
1435
	//
1436
	// Fields are guaranteed to be in the correct http2 order and
1437
	// not have unknown pseudo header fields or invalid header
1438
	// field names or values. Required pseudo header fields may be
1439
	// missing, however. Use the MetaHeadersFrame.Pseudo accessor
1440
	// method access pseudo headers.
1441
	Fields []hpack.HeaderField
1442

1443
	// Truncated is whether the max header list size limit was hit
1444
	// and Fields is incomplete. The hpack decoder state is still
1445
	// valid, however.
1446
	Truncated bool
1447
}
1448

1449
// PseudoValue returns the given pseudo header field's value.
1450
// The provided pseudo field should not contain the leading colon.
1451
func (mh *MetaHeadersFrame) PseudoValue(pseudo string) string {
1452
	for _, hf := range mh.Fields {
1453
		if !hf.IsPseudo() {
1454
			return ""
1455
		}
1456
		if hf.Name[1:] == pseudo {
1457
			return hf.Value
1458
		}
1459
	}
1460
	return ""
1461
}
1462

1463
// RegularFields returns the regular (non-pseudo) header fields of mh.
1464
// The caller does not own the returned slice.
1465
func (mh *MetaHeadersFrame) RegularFields() []hpack.HeaderField {
1466
	for i, hf := range mh.Fields {
1467
		if !hf.IsPseudo() {
1468
			return mh.Fields[i:]
1469
		}
1470
	}
1471
	return nil
1472
}
1473

1474
// PseudoFields returns the pseudo header fields of mh.
1475
// The caller does not own the returned slice.
1476
func (mh *MetaHeadersFrame) PseudoFields() []hpack.HeaderField {
1477
	for i, hf := range mh.Fields {
1478
		if !hf.IsPseudo() {
1479
			return mh.Fields[:i]
1480
		}
1481
	}
1482
	return mh.Fields
1483
}
1484

1485
func (mh *MetaHeadersFrame) checkPseudos() error {
1486
	var isRequest, isResponse bool
1487
	pf := mh.PseudoFields()
1488
	for i, hf := range pf {
1489
		switch hf.Name {
1490
		case ":method", ":path", ":scheme", ":authority":
1491
			isRequest = true
1492
		case ":status":
1493
			isResponse = true
1494
		default:
1495
			return pseudoHeaderError(hf.Name)
1496
		}
1497
		// Check for duplicates.
1498
		// This would be a bad algorithm, but N is 4.
1499
		// And this doesn't allocate.
1500
		for _, hf2 := range pf[:i] {
1501
			if hf.Name == hf2.Name {
1502
				return duplicatePseudoHeaderError(hf.Name)
1503
			}
1504
		}
1505
	}
1506
	if isRequest && isResponse {
1507
		return errMixPseudoHeaderTypes
1508
	}
1509
	return nil
1510
}
1511

1512
func (fr *Framer) maxHeaderStringLen() int {
1513
	v := int(fr.maxHeaderListSize())
1514
	if v < 0 {
1515
		// If maxHeaderListSize overflows an int, use no limit (0).
1516
		return 0
1517
	}
1518
	return v
1519
}
1520

1521
// readMetaFrame returns 0 or more CONTINUATION frames from fr and
1522
// merge them into the provided hf and returns a MetaHeadersFrame
1523
// with the decoded hpack values.
1524
func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) {
1525
	if fr.AllowIllegalReads {
1526
		return nil, errors.New("illegal use of AllowIllegalReads with ReadMetaHeaders")
1527
	}
1528
	mh := &MetaHeadersFrame{
1529
		HeadersFrame: hf,
1530
	}
1531
	var remainSize = fr.maxHeaderListSize()
1532
	var sawRegular bool
1533

1534
	var invalid error // pseudo header field errors
1535
	hdec := fr.ReadMetaHeaders
1536
	hdec.SetEmitEnabled(true)
1537
	hdec.SetMaxStringLength(fr.maxHeaderStringLen())
1538
	hdec.SetEmitFunc(func(hf hpack.HeaderField) {
1539
		if VerboseLogs && fr.logReads {
1540
			fr.debugReadLoggerf("http2: decoded hpack field %+v", hf)
1541
		}
1542
		if !httpguts.ValidHeaderFieldValue(hf.Value) {
1543
			// Don't include the value in the error, because it may be sensitive.
1544
			invalid = headerFieldValueError(hf.Name)
1545
		}
1546
		isPseudo := strings.HasPrefix(hf.Name, ":")
1547
		if isPseudo {
1548
			if sawRegular {
1549
				invalid = errPseudoAfterRegular
1550
			}
1551
		} else {
1552
			sawRegular = true
1553
			if !validWireHeaderFieldName(hf.Name) {
1554
				invalid = headerFieldNameError(hf.Name)
1555
			}
1556
		}
1557

1558
		if invalid != nil {
1559
			hdec.SetEmitEnabled(false)
1560
			return
1561
		}
1562

1563
		size := hf.Size()
1564
		if size > remainSize {
1565
			hdec.SetEmitEnabled(false)
1566
			mh.Truncated = true
1567
			remainSize = 0
1568
			return
1569
		}
1570
		remainSize -= size
1571

1572
		mh.Fields = append(mh.Fields, hf)
1573
	})
1574
	// Lose reference to MetaHeadersFrame:
1575
	defer hdec.SetEmitFunc(func(hf hpack.HeaderField) {})
1576

1577
	var hc headersOrContinuation = hf
1578
	for {
1579
		frag := hc.HeaderBlockFragment()
1580

1581
		// Avoid parsing large amounts of headers that we will then discard.
1582
		// If the sender exceeds the max header list size by too much,
1583
		// skip parsing the fragment and close the connection.
1584
		//
1585
		// "Too much" is either any CONTINUATION frame after we've already
1586
		// exceeded the max header list size (in which case remainSize is 0),
1587
		// or a frame whose encoded size is more than twice the remaining
1588
		// header list bytes we're willing to accept.
1589
		if int64(len(frag)) > int64(2*remainSize) {
1590
			if VerboseLogs {
1591
				log.Printf("http2: header list too large")
1592
			}
1593
			// It would be nice to send a RST_STREAM before sending the GOAWAY,
1594
			// but the structure of the server's frame writer makes this difficult.
1595
			return nil, ConnectionError(ErrCodeProtocol)
1596
		}
1597

1598
		// Also close the connection after any CONTINUATION frame following an
1599
		// invalid header, since we stop tracking the size of the headers after
1600
		// an invalid one.
1601
		if invalid != nil {
1602
			if VerboseLogs {
1603
				log.Printf("http2: invalid header: %v", invalid)
1604
			}
1605
			// It would be nice to send a RST_STREAM before sending the GOAWAY,
1606
			// but the structure of the server's frame writer makes this difficult.
1607
			return nil, ConnectionError(ErrCodeProtocol)
1608
		}
1609

1610
		if _, err := hdec.Write(frag); err != nil {
1611
			return nil, ConnectionError(ErrCodeCompression)
1612
		}
1613

1614
		if hc.HeadersEnded() {
1615
			break
1616
		}
1617
		if f, err := fr.ReadFrame(); err != nil {
1618
			return nil, err
1619
		} else {
1620
			hc = f.(*ContinuationFrame) // guaranteed by checkFrameOrder
1621
		}
1622
	}
1623

1624
	mh.HeadersFrame.headerFragBuf = nil
1625
	mh.HeadersFrame.invalidate()
1626

1627
	if err := hdec.Close(); err != nil {
1628
		return nil, ConnectionError(ErrCodeCompression)
1629
	}
1630
	if invalid != nil {
1631
		fr.errDetail = invalid
1632
		if VerboseLogs {
1633
			log.Printf("http2: invalid header: %v", invalid)
1634
		}
1635
		return nil, StreamError{mh.StreamID, ErrCodeProtocol, invalid}
1636
	}
1637
	if err := mh.checkPseudos(); err != nil {
1638
		fr.errDetail = err
1639
		if VerboseLogs {
1640
			log.Printf("http2: invalid pseudo headers: %v", err)
1641
		}
1642
		return nil, StreamError{mh.StreamID, ErrCodeProtocol, err}
1643
	}
1644
	return mh, nil
1645
}
1646

1647
func summarizeFrame(f Frame) string {
1648
	var buf bytes.Buffer
1649
	f.Header().writeDebug(&buf)
1650
	switch f := f.(type) {
1651
	case *SettingsFrame:
1652
		n := 0
1653
		f.ForeachSetting(func(s Setting) error {
1654
			n++
1655
			if n == 1 {
1656
				buf.WriteString(", settings:")
1657
			}
1658
			fmt.Fprintf(&buf, " %v=%v,", s.ID, s.Val)
1659
			return nil
1660
		})
1661
		if n > 0 {
1662
			buf.Truncate(buf.Len() - 1) // remove trailing comma
1663
		}
1664
	case *DataFrame:
1665
		data := f.Data()
1666
		const max = 256
1667
		if len(data) > max {
1668
			data = data[:max]
1669
		}
1670
		fmt.Fprintf(&buf, " data=%q", data)
1671
		if len(f.Data()) > max {
1672
			fmt.Fprintf(&buf, " (%d bytes omitted)", len(f.Data())-max)
1673
		}
1674
	case *WindowUpdateFrame:
1675
		if f.StreamID == 0 {
1676
			buf.WriteString(" (conn)")
1677
		}
1678
		fmt.Fprintf(&buf, " incr=%v", f.Increment)
1679
	case *PingFrame:
1680
		fmt.Fprintf(&buf, " ping=%q", f.Data[:])
1681
	case *GoAwayFrame:
1682
		fmt.Fprintf(&buf, " LastStreamID=%v ErrCode=%v Debug=%q",
1683
			f.LastStreamID, f.ErrCode, f.debugData)
1684
	case *RSTStreamFrame:
1685
		fmt.Fprintf(&buf, " ErrCode=%v", f.ErrCode)
1686
	}
1687
	return buf.String()
1688
}
1689

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.