diff options
Diffstat (limited to 'vendor/golang.org/x/net/http2/frame.go')
-rw-r--r-- | vendor/golang.org/x/net/http2/frame.go | 1579 |
1 files changed, 1579 insertions, 0 deletions
diff --git a/vendor/golang.org/x/net/http2/frame.go b/vendor/golang.org/x/net/http2/frame.go new file mode 100644 index 0000000..3b14890 --- /dev/null +++ b/vendor/golang.org/x/net/http2/frame.go | |||
@@ -0,0 +1,1579 @@ | |||
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/http2/hpack" | ||
18 | "golang.org/x/net/lex/httplex" | ||
19 | ) | ||
20 | |||
21 | const frameHeaderLen = 9 | ||
22 | |||
23 | var padZeros = make([]byte, 255) // zeros for padding | ||
24 | |||
25 | // A FrameType is a registered frame type as defined in | ||
26 | // http://http2.github.io/http2-spec/#rfc.section.11.2 | ||
27 | type FrameType uint8 | ||
28 | |||
29 | const ( | ||
30 | FrameData FrameType = 0x0 | ||
31 | FrameHeaders FrameType = 0x1 | ||
32 | FramePriority FrameType = 0x2 | ||
33 | FrameRSTStream FrameType = 0x3 | ||
34 | FrameSettings FrameType = 0x4 | ||
35 | FramePushPromise FrameType = 0x5 | ||
36 | FramePing FrameType = 0x6 | ||
37 | FrameGoAway FrameType = 0x7 | ||
38 | FrameWindowUpdate FrameType = 0x8 | ||
39 | FrameContinuation FrameType = 0x9 | ||
40 | ) | ||
41 | |||
42 | var frameName = map[FrameType]string{ | ||
43 | FrameData: "DATA", | ||
44 | FrameHeaders: "HEADERS", | ||
45 | FramePriority: "PRIORITY", | ||
46 | FrameRSTStream: "RST_STREAM", | ||
47 | FrameSettings: "SETTINGS", | ||
48 | FramePushPromise: "PUSH_PROMISE", | ||
49 | FramePing: "PING", | ||
50 | FrameGoAway: "GOAWAY", | ||
51 | FrameWindowUpdate: "WINDOW_UPDATE", | ||
52 | FrameContinuation: "CONTINUATION", | ||
53 | } | ||
54 | |||
55 | func (t FrameType) String() string { | ||
56 | if s, ok := frameName[t]; ok { | ||
57 | return s | ||
58 | } | ||
59 | return fmt.Sprintf("UNKNOWN_FRAME_TYPE_%d", uint8(t)) | ||
60 | } | ||
61 | |||
62 | // Flags is a bitmask of HTTP/2 flags. | ||
63 | // The meaning of flags varies depending on the frame type. | ||
64 | type Flags uint8 | ||
65 | |||
66 | // Has reports whether f contains all (0 or more) flags in v. | ||
67 | func (f Flags) Has(v Flags) bool { | ||
68 | return (f & v) == v | ||
69 | } | ||
70 | |||
71 | // Frame-specific FrameHeader flag bits. | ||
72 | const ( | ||
73 | // Data Frame | ||
74 | FlagDataEndStream Flags = 0x1 | ||
75 | FlagDataPadded Flags = 0x8 | ||
76 | |||
77 | // Headers Frame | ||
78 | FlagHeadersEndStream Flags = 0x1 | ||
79 | FlagHeadersEndHeaders Flags = 0x4 | ||
80 | FlagHeadersPadded Flags = 0x8 | ||
81 | FlagHeadersPriority Flags = 0x20 | ||
82 | |||
83 | // Settings Frame | ||
84 | FlagSettingsAck Flags = 0x1 | ||
85 | |||
86 | // Ping Frame | ||
87 | FlagPingAck Flags = 0x1 | ||
88 | |||
89 | // Continuation Frame | ||
90 | FlagContinuationEndHeaders Flags = 0x4 | ||
91 | |||
92 | FlagPushPromiseEndHeaders Flags = 0x4 | ||
93 | FlagPushPromisePadded Flags = 0x8 | ||
94 | ) | ||
95 | |||
96 | var flagName = map[FrameType]map[Flags]string{ | ||
97 | FrameData: { | ||
98 | FlagDataEndStream: "END_STREAM", | ||
99 | FlagDataPadded: "PADDED", | ||
100 | }, | ||
101 | FrameHeaders: { | ||
102 | FlagHeadersEndStream: "END_STREAM", | ||
103 | FlagHeadersEndHeaders: "END_HEADERS", | ||
104 | FlagHeadersPadded: "PADDED", | ||
105 | FlagHeadersPriority: "PRIORITY", | ||
106 | }, | ||
107 | FrameSettings: { | ||
108 | FlagSettingsAck: "ACK", | ||
109 | }, | ||
110 | FramePing: { | ||
111 | FlagPingAck: "ACK", | ||
112 | }, | ||
113 | FrameContinuation: { | ||
114 | FlagContinuationEndHeaders: "END_HEADERS", | ||
115 | }, | ||
116 | FramePushPromise: { | ||
117 | FlagPushPromiseEndHeaders: "END_HEADERS", | ||
118 | FlagPushPromisePadded: "PADDED", | ||
119 | }, | ||
120 | } | ||
121 | |||
122 | // a frameParser parses a frame given its FrameHeader and payload | ||
123 | // bytes. The length of payload will always equal fh.Length (which | ||
124 | // might be 0). | ||
125 | type frameParser func(fc *frameCache, fh FrameHeader, payload []byte) (Frame, error) | ||
126 | |||
127 | var frameParsers = map[FrameType]frameParser{ | ||
128 | FrameData: parseDataFrame, | ||
129 | FrameHeaders: parseHeadersFrame, | ||
130 | FramePriority: parsePriorityFrame, | ||
131 | FrameRSTStream: parseRSTStreamFrame, | ||
132 | FrameSettings: parseSettingsFrame, | ||
133 | FramePushPromise: parsePushPromise, | ||
134 | FramePing: parsePingFrame, | ||
135 | FrameGoAway: parseGoAwayFrame, | ||
136 | FrameWindowUpdate: parseWindowUpdateFrame, | ||
137 | FrameContinuation: parseContinuationFrame, | ||
138 | } | ||
139 | |||
140 | func typeFrameParser(t FrameType) frameParser { | ||
141 | if f := frameParsers[t]; f != nil { | ||
142 | return f | ||
143 | } | ||
144 | return parseUnknownFrame | ||
145 | } | ||
146 | |||
147 | // A FrameHeader is the 9 byte header of all HTTP/2 frames. | ||
148 | // | ||
149 | // See http://http2.github.io/http2-spec/#FrameHeader | ||
150 | type FrameHeader struct { | ||
151 | valid bool // caller can access []byte fields in the Frame | ||
152 | |||
153 | // Type is the 1 byte frame type. There are ten standard frame | ||
154 | // types, but extension frame types may be written by WriteRawFrame | ||
155 | // and will be returned by ReadFrame (as UnknownFrame). | ||
156 | Type FrameType | ||
157 | |||
158 | // Flags are the 1 byte of 8 potential bit flags per frame. | ||
159 | // They are specific to the frame type. | ||
160 | Flags Flags | ||
161 | |||
162 | // Length is the length of the frame, not including the 9 byte header. | ||
163 | // The maximum size is one byte less than 16MB (uint24), but only | ||
164 | // frames up to 16KB are allowed without peer agreement. | ||
165 | Length uint32 | ||
166 | |||
167 | // StreamID is which stream this frame is for. Certain frames | ||
168 | // are not stream-specific, in which case this field is 0. | ||
169 | StreamID uint32 | ||
170 | } | ||
171 | |||
172 | // Header returns h. It exists so FrameHeaders can be embedded in other | ||
173 | // specific frame types and implement the Frame interface. | ||
174 | func (h FrameHeader) Header() FrameHeader { return h } | ||
175 | |||
176 | func (h FrameHeader) String() string { | ||
177 | var buf bytes.Buffer | ||
178 | buf.WriteString("[FrameHeader ") | ||
179 | h.writeDebug(&buf) | ||
180 | buf.WriteByte(']') | ||
181 | return buf.String() | ||
182 | } | ||
183 | |||
184 | func (h FrameHeader) writeDebug(buf *bytes.Buffer) { | ||
185 | buf.WriteString(h.Type.String()) | ||
186 | if h.Flags != 0 { | ||
187 | buf.WriteString(" flags=") | ||
188 | set := 0 | ||
189 | for i := uint8(0); i < 8; i++ { | ||
190 | if h.Flags&(1<<i) == 0 { | ||
191 | continue | ||
192 | } | ||
193 | set++ | ||
194 | if set > 1 { | ||
195 | buf.WriteByte('|') | ||
196 | } | ||
197 | name := flagName[h.Type][Flags(1<<i)] | ||
198 | if name != "" { | ||
199 | buf.WriteString(name) | ||
200 | } else { | ||
201 | fmt.Fprintf(buf, "0x%x", 1<<i) | ||
202 | } | ||
203 | } | ||
204 | } | ||
205 | if h.StreamID != 0 { | ||
206 | fmt.Fprintf(buf, " stream=%d", h.StreamID) | ||
207 | } | ||
208 | fmt.Fprintf(buf, " len=%d", h.Length) | ||
209 | } | ||
210 | |||
211 | func (h *FrameHeader) checkValid() { | ||
212 | if !h.valid { | ||
213 | panic("Frame accessor called on non-owned Frame") | ||
214 | } | ||
215 | } | ||
216 | |||
217 | func (h *FrameHeader) invalidate() { h.valid = false } | ||
218 | |||
219 | // frame header bytes. | ||
220 | // Used only by ReadFrameHeader. | ||
221 | var fhBytes = sync.Pool{ | ||
222 | New: func() interface{} { | ||
223 | buf := make([]byte, frameHeaderLen) | ||
224 | return &buf | ||
225 | }, | ||
226 | } | ||
227 | |||
228 | // ReadFrameHeader reads 9 bytes from r and returns a FrameHeader. | ||
229 | // Most users should use Framer.ReadFrame instead. | ||
230 | func ReadFrameHeader(r io.Reader) (FrameHeader, error) { | ||
231 | bufp := fhBytes.Get().(*[]byte) | ||
232 | defer fhBytes.Put(bufp) | ||
233 | return readFrameHeader(*bufp, r) | ||
234 | } | ||
235 | |||
236 | func readFrameHeader(buf []byte, r io.Reader) (FrameHeader, error) { | ||
237 | _, err := io.ReadFull(r, buf[:frameHeaderLen]) | ||
238 | if err != nil { | ||
239 | return FrameHeader{}, err | ||
240 | } | ||
241 | return FrameHeader{ | ||
242 | Length: (uint32(buf[0])<<16 | uint32(buf[1])<<8 | uint32(buf[2])), | ||
243 | Type: FrameType(buf[3]), | ||
244 | Flags: Flags(buf[4]), | ||
245 | StreamID: binary.BigEndian.Uint32(buf[5:]) & (1<<31 - 1), | ||
246 | valid: true, | ||
247 | }, nil | ||
248 | } | ||
249 | |||
250 | // A Frame is the base interface implemented by all frame types. | ||
251 | // Callers will generally type-assert the specific frame type: | ||
252 | // *HeadersFrame, *SettingsFrame, *WindowUpdateFrame, etc. | ||
253 | // | ||
254 | // Frames are only valid until the next call to Framer.ReadFrame. | ||
255 | type Frame interface { | ||
256 | Header() FrameHeader | ||
257 | |||
258 | // invalidate is called by Framer.ReadFrame to make this | ||
259 | // frame's buffers as being invalid, since the subsequent | ||
260 | // frame will reuse them. | ||
261 | invalidate() | ||
262 | } | ||
263 | |||
264 | // A Framer reads and writes Frames. | ||
265 | type Framer struct { | ||
266 | r io.Reader | ||
267 | lastFrame Frame | ||
268 | errDetail error | ||
269 | |||
270 | // lastHeaderStream is non-zero if the last frame was an | ||
271 | // unfinished HEADERS/CONTINUATION. | ||
272 | lastHeaderStream uint32 | ||
273 | |||
274 | maxReadSize uint32 | ||
275 | headerBuf [frameHeaderLen]byte | ||
276 | |||
277 | // TODO: let getReadBuf be configurable, and use a less memory-pinning | ||
278 | // allocator in server.go to minimize memory pinned for many idle conns. | ||
279 | // Will probably also need to make frame invalidation have a hook too. | ||
280 | getReadBuf func(size uint32) []byte | ||
281 | readBuf []byte // cache for default getReadBuf | ||
282 | |||
283 | maxWriteSize uint32 // zero means unlimited; TODO: implement | ||
284 | |||
285 | w io.Writer | ||
286 | wbuf []byte | ||
287 | |||
288 | // AllowIllegalWrites permits the Framer's Write methods to | ||
289 | // write frames that do not conform to the HTTP/2 spec. This | ||
290 | // permits using the Framer to test other HTTP/2 | ||
291 | // implementations' conformance to the spec. | ||
292 | // If false, the Write methods will prefer to return an error | ||
293 | // rather than comply. | ||
294 | AllowIllegalWrites bool | ||
295 | |||
296 | // AllowIllegalReads permits the Framer's ReadFrame method | ||
297 | // to return non-compliant frames or frame orders. | ||
298 | // This is for testing and permits using the Framer to test | ||
299 | // other HTTP/2 implementations' conformance to the spec. | ||
300 | // It is not compatible with ReadMetaHeaders. | ||
301 | AllowIllegalReads bool | ||
302 | |||
303 | // ReadMetaHeaders if non-nil causes ReadFrame to merge | ||
304 | // HEADERS and CONTINUATION frames together and return | ||
305 | // MetaHeadersFrame instead. | ||
306 | ReadMetaHeaders *hpack.Decoder | ||
307 | |||
308 | // MaxHeaderListSize is the http2 MAX_HEADER_LIST_SIZE. | ||
309 | // It's used only if ReadMetaHeaders is set; 0 means a sane default | ||
310 | // (currently 16MB) | ||
311 | // If the limit is hit, MetaHeadersFrame.Truncated is set true. | ||
312 | MaxHeaderListSize uint32 | ||
313 | |||
314 | // TODO: track which type of frame & with which flags was sent | ||
315 | // last. Then return an error (unless AllowIllegalWrites) if | ||
316 | // we're in the middle of a header block and a | ||
317 | // non-Continuation or Continuation on a different stream is | ||
318 | // attempted to be written. | ||
319 | |||
320 | logReads, logWrites bool | ||
321 | |||
322 | debugFramer *Framer // only use for logging written writes | ||
323 | debugFramerBuf *bytes.Buffer | ||
324 | debugReadLoggerf func(string, ...interface{}) | ||
325 | debugWriteLoggerf func(string, ...interface{}) | ||
326 | |||
327 | frameCache *frameCache // nil if frames aren't reused (default) | ||
328 | } | ||
329 | |||
330 | func (fr *Framer) maxHeaderListSize() uint32 { | ||
331 | if fr.MaxHeaderListSize == 0 { | ||
332 | return 16 << 20 // sane default, per docs | ||
333 | } | ||
334 | return fr.MaxHeaderListSize | ||
335 | } | ||
336 | |||
337 | func (f *Framer) startWrite(ftype FrameType, flags Flags, streamID uint32) { | ||
338 | // Write the FrameHeader. | ||
339 | f.wbuf = append(f.wbuf[:0], | ||
340 | 0, // 3 bytes of length, filled in in endWrite | ||
341 | 0, | ||
342 | 0, | ||
343 | byte(ftype), | ||
344 | byte(flags), | ||
345 | byte(streamID>>24), | ||
346 | byte(streamID>>16), | ||
347 | byte(streamID>>8), | ||
348 | byte(streamID)) | ||
349 | } | ||
350 | |||
351 | func (f *Framer) endWrite() error { | ||
352 | // Now that we know the final size, fill in the FrameHeader in | ||
353 | // the space previously reserved for it. Abuse append. | ||
354 | length := len(f.wbuf) - frameHeaderLen | ||
355 | if length >= (1 << 24) { | ||
356 | return ErrFrameTooLarge | ||
357 | } | ||
358 | _ = append(f.wbuf[:0], | ||
359 | byte(length>>16), | ||
360 | byte(length>>8), | ||
361 | byte(length)) | ||
362 | if f.logWrites { | ||
363 | f.logWrite() | ||
364 | } | ||
365 | |||
366 | n, err := f.w.Write(f.wbuf) | ||
367 | if err == nil && n != len(f.wbuf) { | ||
368 | err = io.ErrShortWrite | ||
369 | } | ||
370 | return err | ||
371 | } | ||
372 | |||
373 | func (f *Framer) logWrite() { | ||
374 | if f.debugFramer == nil { | ||
375 | f.debugFramerBuf = new(bytes.Buffer) | ||
376 | f.debugFramer = NewFramer(nil, f.debugFramerBuf) | ||
377 | f.debugFramer.logReads = false // we log it ourselves, saying "wrote" below | ||
378 | // Let us read anything, even if we accidentally wrote it | ||
379 | // in the wrong order: | ||
380 | f.debugFramer.AllowIllegalReads = true | ||
381 | } | ||
382 | f.debugFramerBuf.Write(f.wbuf) | ||
383 | fr, err := f.debugFramer.ReadFrame() | ||
384 | if err != nil { | ||
385 | f.debugWriteLoggerf("http2: Framer %p: failed to decode just-written frame", f) | ||
386 | return | ||
387 | } | ||
388 | f.debugWriteLoggerf("http2: Framer %p: wrote %v", f, summarizeFrame(fr)) | ||
389 | } | ||
390 | |||
391 | func (f *Framer) writeByte(v byte) { f.wbuf = append(f.wbuf, v) } | ||
392 | func (f *Framer) writeBytes(v []byte) { f.wbuf = append(f.wbuf, v...) } | ||
393 | func (f *Framer) writeUint16(v uint16) { f.wbuf = append(f.wbuf, byte(v>>8), byte(v)) } | ||
394 | func (f *Framer) writeUint32(v uint32) { | ||
395 | f.wbuf = append(f.wbuf, byte(v>>24), byte(v>>16), byte(v>>8), byte(v)) | ||
396 | } | ||
397 | |||
398 | const ( | ||
399 | minMaxFrameSize = 1 << 14 | ||
400 | maxFrameSize = 1<<24 - 1 | ||
401 | ) | ||
402 | |||
403 | // SetReuseFrames allows the Framer to reuse Frames. | ||
404 | // If called on a Framer, Frames returned by calls to ReadFrame are only | ||
405 | // valid until the next call to ReadFrame. | ||
406 | func (fr *Framer) SetReuseFrames() { | ||
407 | if fr.frameCache != nil { | ||
408 | return | ||
409 | } | ||
410 | fr.frameCache = &frameCache{} | ||
411 | } | ||
412 | |||
413 | type frameCache struct { | ||
414 | dataFrame DataFrame | ||
415 | } | ||
416 | |||
417 | func (fc *frameCache) getDataFrame() *DataFrame { | ||
418 | if fc == nil { | ||
419 | return &DataFrame{} | ||
420 | } | ||
421 | return &fc.dataFrame | ||
422 | } | ||
423 | |||
424 | // NewFramer returns a Framer that writes frames to w and reads them from r. | ||
425 | func NewFramer(w io.Writer, r io.Reader) *Framer { | ||
426 | fr := &Framer{ | ||
427 | w: w, | ||
428 | r: r, | ||
429 | logReads: logFrameReads, | ||
430 | logWrites: logFrameWrites, | ||
431 | debugReadLoggerf: log.Printf, | ||
432 | debugWriteLoggerf: log.Printf, | ||
433 | } | ||
434 | fr.getReadBuf = func(size uint32) []byte { | ||
435 | if cap(fr.readBuf) >= int(size) { | ||
436 | return fr.readBuf[:size] | ||
437 | } | ||
438 | fr.readBuf = make([]byte, size) | ||
439 | return fr.readBuf | ||
440 | } | ||
441 | fr.SetMaxReadFrameSize(maxFrameSize) | ||
442 | return fr | ||
443 | } | ||
444 | |||
445 | // SetMaxReadFrameSize sets the maximum size of a frame | ||
446 | // that will be read by a subsequent call to ReadFrame. | ||
447 | // It is the caller's responsibility to advertise this | ||
448 | // limit with a SETTINGS frame. | ||
449 | func (fr *Framer) SetMaxReadFrameSize(v uint32) { | ||
450 | if v > maxFrameSize { | ||
451 | v = maxFrameSize | ||
452 | } | ||
453 | fr.maxReadSize = v | ||
454 | } | ||
455 | |||
456 | // ErrorDetail returns a more detailed error of the last error | ||
457 | // returned by Framer.ReadFrame. For instance, if ReadFrame | ||
458 | // returns a StreamError with code PROTOCOL_ERROR, ErrorDetail | ||
459 | // will say exactly what was invalid. ErrorDetail is not guaranteed | ||
460 | // to return a non-nil value and like the rest of the http2 package, | ||
461 | // its return value is not protected by an API compatibility promise. | ||
462 | // ErrorDetail is reset after the next call to ReadFrame. | ||
463 | func (fr *Framer) ErrorDetail() error { | ||
464 | return fr.errDetail | ||
465 | } | ||
466 | |||
467 | // ErrFrameTooLarge is returned from Framer.ReadFrame when the peer | ||
468 | // sends a frame that is larger than declared with SetMaxReadFrameSize. | ||
469 | var ErrFrameTooLarge = errors.New("http2: frame too large") | ||
470 | |||
471 | // terminalReadFrameError reports whether err is an unrecoverable | ||
472 | // error from ReadFrame and no other frames should be read. | ||
473 | func terminalReadFrameError(err error) bool { | ||
474 | if _, ok := err.(StreamError); ok { | ||
475 | return false | ||
476 | } | ||
477 | return err != nil | ||
478 | } | ||
479 | |||
480 | // ReadFrame reads a single frame. The returned Frame is only valid | ||
481 | // until the next call to ReadFrame. | ||
482 | // | ||
483 | // If the frame is larger than previously set with SetMaxReadFrameSize, the | ||
484 | // returned error is ErrFrameTooLarge. Other errors may be of type | ||
485 | // ConnectionError, StreamError, or anything else from the underlying | ||
486 | // reader. | ||
487 | func (fr *Framer) ReadFrame() (Frame, error) { | ||
488 | fr.errDetail = nil | ||
489 | if fr.lastFrame != nil { | ||
490 | fr.lastFrame.invalidate() | ||
491 | } | ||
492 | fh, err := readFrameHeader(fr.headerBuf[:], fr.r) | ||
493 | if err != nil { | ||
494 | return nil, err | ||
495 | } | ||
496 | if fh.Length > fr.maxReadSize { | ||
497 | return nil, ErrFrameTooLarge | ||
498 | } | ||
499 | payload := fr.getReadBuf(fh.Length) | ||
500 | if _, err := io.ReadFull(fr.r, payload); err != nil { | ||
501 | return nil, err | ||
502 | } | ||
503 | f, err := typeFrameParser(fh.Type)(fr.frameCache, fh, payload) | ||
504 | if err != nil { | ||
505 | if ce, ok := err.(connError); ok { | ||
506 | return nil, fr.connError(ce.Code, ce.Reason) | ||
507 | } | ||
508 | return nil, err | ||
509 | } | ||
510 | if err := fr.checkFrameOrder(f); err != nil { | ||
511 | return nil, err | ||
512 | } | ||
513 | if fr.logReads { | ||
514 | fr.debugReadLoggerf("http2: Framer %p: read %v", fr, summarizeFrame(f)) | ||
515 | } | ||
516 | if fh.Type == FrameHeaders && fr.ReadMetaHeaders != nil { | ||
517 | return fr.readMetaFrame(f.(*HeadersFrame)) | ||
518 | } | ||
519 | return f, nil | ||
520 | } | ||
521 | |||
522 | // connError returns ConnectionError(code) but first | ||
523 | // stashes away a public reason to the caller can optionally relay it | ||
524 | // to the peer before hanging up on them. This might help others debug | ||
525 | // their implementations. | ||
526 | func (fr *Framer) connError(code ErrCode, reason string) error { | ||
527 | fr.errDetail = errors.New(reason) | ||
528 | return ConnectionError(code) | ||
529 | } | ||
530 | |||
531 | // checkFrameOrder reports an error if f is an invalid frame to return | ||
532 | // next from ReadFrame. Mostly it checks whether HEADERS and | ||
533 | // CONTINUATION frames are contiguous. | ||
534 | func (fr *Framer) checkFrameOrder(f Frame) error { | ||
535 | last := fr.lastFrame | ||
536 | fr.lastFrame = f | ||
537 | if fr.AllowIllegalReads { | ||
538 | return nil | ||
539 | } | ||
540 | |||
541 | fh := f.Header() | ||
542 | if fr.lastHeaderStream != 0 { | ||
543 | if fh.Type != FrameContinuation { | ||
544 | return fr.connError(ErrCodeProtocol, | ||
545 | fmt.Sprintf("got %s for stream %d; expected CONTINUATION following %s for stream %d", | ||
546 | fh.Type, fh.StreamID, | ||
547 | last.Header().Type, fr.lastHeaderStream)) | ||
548 | } | ||
549 | if fh.StreamID != fr.lastHeaderStream { | ||
550 | return fr.connError(ErrCodeProtocol, | ||
551 | fmt.Sprintf("got CONTINUATION for stream %d; expected stream %d", | ||
552 | fh.StreamID, fr.lastHeaderStream)) | ||
553 | } | ||
554 | } else if fh.Type == FrameContinuation { | ||
555 | return fr.connError(ErrCodeProtocol, fmt.Sprintf("unexpected CONTINUATION for stream %d", fh.StreamID)) | ||
556 | } | ||
557 | |||
558 | switch fh.Type { | ||
559 | case FrameHeaders, FrameContinuation: | ||
560 | if fh.Flags.Has(FlagHeadersEndHeaders) { | ||
561 | fr.lastHeaderStream = 0 | ||
562 | } else { | ||
563 | fr.lastHeaderStream = fh.StreamID | ||
564 | } | ||
565 | } | ||
566 | |||
567 | return nil | ||
568 | } | ||
569 | |||
570 | // A DataFrame conveys arbitrary, variable-length sequences of octets | ||
571 | // associated with a stream. | ||
572 | // See http://http2.github.io/http2-spec/#rfc.section.6.1 | ||
573 | type DataFrame struct { | ||
574 | FrameHeader | ||
575 | data []byte | ||
576 | } | ||
577 | |||
578 | func (f *DataFrame) StreamEnded() bool { | ||
579 | return f.FrameHeader.Flags.Has(FlagDataEndStream) | ||
580 | } | ||
581 | |||
582 | // Data returns the frame's data octets, not including any padding | ||
583 | // size byte or padding suffix bytes. | ||
584 | // The caller must not retain the returned memory past the next | ||
585 | // call to ReadFrame. | ||
586 | func (f *DataFrame) Data() []byte { | ||
587 | f.checkValid() | ||
588 | return f.data | ||
589 | } | ||
590 | |||
591 | func parseDataFrame(fc *frameCache, fh FrameHeader, payload []byte) (Frame, error) { | ||
592 | if fh.StreamID == 0 { | ||
593 | // DATA frames MUST be associated with a stream. If a | ||
594 | // DATA frame is received whose stream identifier | ||
595 | // field is 0x0, the recipient MUST respond with a | ||
596 | // connection error (Section 5.4.1) of type | ||
597 | // PROTOCOL_ERROR. | ||
598 | return nil, connError{ErrCodeProtocol, "DATA frame with stream ID 0"} | ||
599 | } | ||
600 | f := fc.getDataFrame() | ||
601 | f.FrameHeader = fh | ||
602 | |||
603 | var padSize byte | ||
604 | if fh.Flags.Has(FlagDataPadded) { | ||
605 | var err error | ||
606 | payload, padSize, err = readByte(payload) | ||
607 | if err != nil { | ||
608 | return nil, err | ||
609 | } | ||
610 | } | ||
611 | if int(padSize) > len(payload) { | ||
612 | // If the length of the padding is greater than the | ||
613 | // length of the frame payload, the recipient MUST | ||
614 | // treat this as a connection error. | ||
615 | // Filed: https://github.com/http2/http2-spec/issues/610 | ||
616 | return nil, connError{ErrCodeProtocol, "pad size larger than data payload"} | ||
617 | } | ||
618 | f.data = payload[:len(payload)-int(padSize)] | ||
619 | return f, nil | ||
620 | } | ||
621 | |||
622 | var ( | ||
623 | errStreamID = errors.New("invalid stream ID") | ||
624 | errDepStreamID = errors.New("invalid dependent stream ID") | ||
625 | errPadLength = errors.New("pad length too large") | ||
626 | errPadBytes = errors.New("padding bytes must all be zeros unless AllowIllegalWrites is enabled") | ||
627 | ) | ||
628 | |||
629 | func validStreamIDOrZero(streamID uint32) bool { | ||
630 | return streamID&(1<<31) == 0 | ||
631 | } | ||
632 | |||
633 | func validStreamID(streamID uint32) bool { | ||
634 | return streamID != 0 && streamID&(1<<31) == 0 | ||
635 | } | ||
636 | |||
637 | // WriteData writes a DATA frame. | ||
638 | // | ||
639 | // It will perform exactly one Write to the underlying Writer. | ||
640 | // It is the caller's responsibility not to violate the maximum frame size | ||
641 | // and to not call other Write methods concurrently. | ||
642 | func (f *Framer) WriteData(streamID uint32, endStream bool, data []byte) error { | ||
643 | return f.WriteDataPadded(streamID, endStream, data, nil) | ||
644 | } | ||
645 | |||
646 | // WriteData writes a DATA frame with optional padding. | ||
647 | // | ||
648 | // If pad is nil, the padding bit is not sent. | ||
649 | // The length of pad must not exceed 255 bytes. | ||
650 | // The bytes of pad must all be zero, unless f.AllowIllegalWrites is set. | ||
651 | // | ||
652 | // It will perform exactly one Write to the underlying Writer. | ||
653 | // It is the caller's responsibility not to violate the maximum frame size | ||
654 | // and to not call other Write methods concurrently. | ||
655 | func (f *Framer) WriteDataPadded(streamID uint32, endStream bool, data, pad []byte) error { | ||
656 | if !validStreamID(streamID) && !f.AllowIllegalWrites { | ||
657 | return errStreamID | ||
658 | } | ||
659 | if len(pad) > 0 { | ||
660 | if len(pad) > 255 { | ||
661 | return errPadLength | ||
662 | } | ||
663 | if !f.AllowIllegalWrites { | ||
664 | for _, b := range pad { | ||
665 | if b != 0 { | ||
666 | // "Padding octets MUST be set to zero when sending." | ||
667 | return errPadBytes | ||
668 | } | ||
669 | } | ||
670 | } | ||
671 | } | ||
672 | var flags Flags | ||
673 | if endStream { | ||
674 | flags |= FlagDataEndStream | ||
675 | } | ||
676 | if pad != nil { | ||
677 | flags |= FlagDataPadded | ||
678 | } | ||
679 | f.startWrite(FrameData, flags, streamID) | ||
680 | if pad != nil { | ||
681 | f.wbuf = append(f.wbuf, byte(len(pad))) | ||
682 | } | ||
683 | f.wbuf = append(f.wbuf, data...) | ||
684 | f.wbuf = append(f.wbuf, pad...) | ||
685 | return f.endWrite() | ||
686 | } | ||
687 | |||
688 | // A SettingsFrame conveys configuration parameters that affect how | ||
689 | // endpoints communicate, such as preferences and constraints on peer | ||
690 | // behavior. | ||
691 | // | ||
692 | // See http://http2.github.io/http2-spec/#SETTINGS | ||
693 | type SettingsFrame struct { | ||
694 | FrameHeader | ||
695 | p []byte | ||
696 | } | ||
697 | |||
698 | func parseSettingsFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) { | ||
699 | if fh.Flags.Has(FlagSettingsAck) && fh.Length > 0 { | ||
700 | // When this (ACK 0x1) bit is set, the payload of the | ||
701 | // SETTINGS frame MUST be empty. Receipt of a | ||
702 | // SETTINGS frame with the ACK flag set and a length | ||
703 | // field value other than 0 MUST be treated as a | ||
704 | // connection error (Section 5.4.1) of type | ||
705 | // FRAME_SIZE_ERROR. | ||
706 | return nil, ConnectionError(ErrCodeFrameSize) | ||
707 | } | ||
708 | if fh.StreamID != 0 { | ||
709 | // SETTINGS frames always apply to a connection, | ||
710 | // never a single stream. The stream identifier for a | ||
711 | // SETTINGS frame MUST be zero (0x0). If an endpoint | ||
712 | // receives a SETTINGS frame whose stream identifier | ||
713 | // field is anything other than 0x0, the endpoint MUST | ||
714 | // respond with a connection error (Section 5.4.1) of | ||
715 | // type PROTOCOL_ERROR. | ||
716 | return nil, ConnectionError(ErrCodeProtocol) | ||
717 | } | ||
718 | if len(p)%6 != 0 { | ||
719 | // Expecting even number of 6 byte settings. | ||
720 | return nil, ConnectionError(ErrCodeFrameSize) | ||
721 | } | ||
722 | f := &SettingsFrame{FrameHeader: fh, p: p} | ||
723 | if v, ok := f.Value(SettingInitialWindowSize); ok && v > (1<<31)-1 { | ||
724 | // Values above the maximum flow control window size of 2^31 - 1 MUST | ||
725 | // be treated as a connection error (Section 5.4.1) of type | ||
726 | // FLOW_CONTROL_ERROR. | ||
727 | return nil, ConnectionError(ErrCodeFlowControl) | ||
728 | } | ||
729 | return f, nil | ||
730 | } | ||
731 | |||
732 | func (f *SettingsFrame) IsAck() bool { | ||
733 | return f.FrameHeader.Flags.Has(FlagSettingsAck) | ||
734 | } | ||
735 | |||
736 | func (f *SettingsFrame) Value(s SettingID) (v uint32, ok bool) { | ||
737 | f.checkValid() | ||
738 | buf := f.p | ||
739 | for len(buf) > 0 { | ||
740 | settingID := SettingID(binary.BigEndian.Uint16(buf[:2])) | ||
741 | if settingID == s { | ||
742 | return binary.BigEndian.Uint32(buf[2:6]), true | ||
743 | } | ||
744 | buf = buf[6:] | ||
745 | } | ||
746 | return 0, false | ||
747 | } | ||
748 | |||
749 | // ForeachSetting runs fn for each setting. | ||
750 | // It stops and returns the first error. | ||
751 | func (f *SettingsFrame) ForeachSetting(fn func(Setting) error) error { | ||
752 | f.checkValid() | ||
753 | buf := f.p | ||
754 | for len(buf) > 0 { | ||
755 | if err := fn(Setting{ | ||
756 | SettingID(binary.BigEndian.Uint16(buf[:2])), | ||
757 | binary.BigEndian.Uint32(buf[2:6]), | ||
758 | }); err != nil { | ||
759 | return err | ||
760 | } | ||
761 | buf = buf[6:] | ||
762 | } | ||
763 | return nil | ||
764 | } | ||
765 | |||
766 | // WriteSettings writes a SETTINGS frame with zero or more settings | ||
767 | // specified and the ACK bit not set. | ||
768 | // | ||
769 | // It will perform exactly one Write to the underlying Writer. | ||
770 | // It is the caller's responsibility to not call other Write methods concurrently. | ||
771 | func (f *Framer) WriteSettings(settings ...Setting) error { | ||
772 | f.startWrite(FrameSettings, 0, 0) | ||
773 | for _, s := range settings { | ||
774 | f.writeUint16(uint16(s.ID)) | ||
775 | f.writeUint32(s.Val) | ||
776 | } | ||
777 | return f.endWrite() | ||
778 | } | ||
779 | |||
780 | // WriteSettingsAck writes an empty SETTINGS frame with the ACK bit set. | ||
781 | // | ||
782 | // It will perform exactly one Write to the underlying Writer. | ||
783 | // It is the caller's responsibility to not call other Write methods concurrently. | ||
784 | func (f *Framer) WriteSettingsAck() error { | ||
785 | f.startWrite(FrameSettings, FlagSettingsAck, 0) | ||
786 | return f.endWrite() | ||
787 | } | ||
788 | |||
789 | // A PingFrame is a mechanism for measuring a minimal round trip time | ||
790 | // from the sender, as well as determining whether an idle connection | ||
791 | // is still functional. | ||
792 | // See http://http2.github.io/http2-spec/#rfc.section.6.7 | ||
793 | type PingFrame struct { | ||
794 | FrameHeader | ||
795 | Data [8]byte | ||
796 | } | ||
797 | |||
798 | func (f *PingFrame) IsAck() bool { return f.Flags.Has(FlagPingAck) } | ||
799 | |||
800 | func parsePingFrame(_ *frameCache, fh FrameHeader, payload []byte) (Frame, error) { | ||
801 | if len(payload) != 8 { | ||
802 | return nil, ConnectionError(ErrCodeFrameSize) | ||
803 | } | ||
804 | if fh.StreamID != 0 { | ||
805 | return nil, ConnectionError(ErrCodeProtocol) | ||
806 | } | ||
807 | f := &PingFrame{FrameHeader: fh} | ||
808 | copy(f.Data[:], payload) | ||
809 | return f, nil | ||
810 | } | ||
811 | |||
812 | func (f *Framer) WritePing(ack bool, data [8]byte) error { | ||
813 | var flags Flags | ||
814 | if ack { | ||
815 | flags = FlagPingAck | ||
816 | } | ||
817 | f.startWrite(FramePing, flags, 0) | ||
818 | f.writeBytes(data[:]) | ||
819 | return f.endWrite() | ||
820 | } | ||
821 | |||
822 | // A GoAwayFrame informs the remote peer to stop creating streams on this connection. | ||
823 | // See http://http2.github.io/http2-spec/#rfc.section.6.8 | ||
824 | type GoAwayFrame struct { | ||
825 | FrameHeader | ||
826 | LastStreamID uint32 | ||
827 | ErrCode ErrCode | ||
828 | debugData []byte | ||
829 | } | ||
830 | |||
831 | // DebugData returns any debug data in the GOAWAY frame. Its contents | ||
832 | // are not defined. | ||
833 | // The caller must not retain the returned memory past the next | ||
834 | // call to ReadFrame. | ||
835 | func (f *GoAwayFrame) DebugData() []byte { | ||
836 | f.checkValid() | ||
837 | return f.debugData | ||
838 | } | ||
839 | |||
840 | func parseGoAwayFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) { | ||
841 | if fh.StreamID != 0 { | ||
842 | return nil, ConnectionError(ErrCodeProtocol) | ||
843 | } | ||
844 | if len(p) < 8 { | ||
845 | return nil, ConnectionError(ErrCodeFrameSize) | ||
846 | } | ||
847 | return &GoAwayFrame{ | ||
848 | FrameHeader: fh, | ||
849 | LastStreamID: binary.BigEndian.Uint32(p[:4]) & (1<<31 - 1), | ||
850 | ErrCode: ErrCode(binary.BigEndian.Uint32(p[4:8])), | ||
851 | debugData: p[8:], | ||
852 | }, nil | ||
853 | } | ||
854 | |||
855 | func (f *Framer) WriteGoAway(maxStreamID uint32, code ErrCode, debugData []byte) error { | ||
856 | f.startWrite(FrameGoAway, 0, 0) | ||
857 | f.writeUint32(maxStreamID & (1<<31 - 1)) | ||
858 | f.writeUint32(uint32(code)) | ||
859 | f.writeBytes(debugData) | ||
860 | return f.endWrite() | ||
861 | } | ||
862 | |||
863 | // An UnknownFrame is the frame type returned when the frame type is unknown | ||
864 | // or no specific frame type parser exists. | ||
865 | type UnknownFrame struct { | ||
866 | FrameHeader | ||
867 | p []byte | ||
868 | } | ||
869 | |||
870 | // Payload returns the frame's payload (after the header). It is not | ||
871 | // valid to call this method after a subsequent call to | ||
872 | // Framer.ReadFrame, nor is it valid to retain the returned slice. | ||
873 | // The memory is owned by the Framer and is invalidated when the next | ||
874 | // frame is read. | ||
875 | func (f *UnknownFrame) Payload() []byte { | ||
876 | f.checkValid() | ||
877 | return f.p | ||
878 | } | ||
879 | |||
880 | func parseUnknownFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) { | ||
881 | return &UnknownFrame{fh, p}, nil | ||
882 | } | ||
883 | |||
884 | // A WindowUpdateFrame is used to implement flow control. | ||
885 | // See http://http2.github.io/http2-spec/#rfc.section.6.9 | ||
886 | type WindowUpdateFrame struct { | ||
887 | FrameHeader | ||
888 | Increment uint32 // never read with high bit set | ||
889 | } | ||
890 | |||
891 | func parseWindowUpdateFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) { | ||
892 | if len(p) != 4 { | ||
893 | return nil, ConnectionError(ErrCodeFrameSize) | ||
894 | } | ||
895 | inc := binary.BigEndian.Uint32(p[:4]) & 0x7fffffff // mask off high reserved bit | ||
896 | if inc == 0 { | ||
897 | // A receiver MUST treat the receipt of a | ||
898 | // WINDOW_UPDATE frame with an flow control window | ||
899 | // increment of 0 as a stream error (Section 5.4.2) of | ||
900 | // type PROTOCOL_ERROR; errors on the connection flow | ||
901 | // control window MUST be treated as a connection | ||
902 | // error (Section 5.4.1). | ||
903 | if fh.StreamID == 0 { | ||
904 | return nil, ConnectionError(ErrCodeProtocol) | ||
905 | } | ||
906 | return nil, streamError(fh.StreamID, ErrCodeProtocol) | ||
907 | } | ||
908 | return &WindowUpdateFrame{ | ||
909 | FrameHeader: fh, | ||
910 | Increment: inc, | ||
911 | }, nil | ||
912 | } | ||
913 | |||
914 | // WriteWindowUpdate writes a WINDOW_UPDATE frame. | ||
915 | // The increment value must be between 1 and 2,147,483,647, inclusive. | ||
916 | // If the Stream ID is zero, the window update applies to the | ||
917 | // connection as a whole. | ||
918 | func (f *Framer) WriteWindowUpdate(streamID, incr uint32) error { | ||
919 | // "The legal range for the increment to the flow control window is 1 to 2^31-1 (2,147,483,647) octets." | ||
920 | if (incr < 1 || incr > 2147483647) && !f.AllowIllegalWrites { | ||
921 | return errors.New("illegal window increment value") | ||
922 | } | ||
923 | f.startWrite(FrameWindowUpdate, 0, streamID) | ||
924 | f.writeUint32(incr) | ||
925 | return f.endWrite() | ||
926 | } | ||
927 | |||
928 | // A HeadersFrame is used to open a stream and additionally carries a | ||
929 | // header block fragment. | ||
930 | type HeadersFrame struct { | ||
931 | FrameHeader | ||
932 | |||
933 | // Priority is set if FlagHeadersPriority is set in the FrameHeader. | ||
934 | Priority PriorityParam | ||
935 | |||
936 | headerFragBuf []byte // not owned | ||
937 | } | ||
938 | |||
939 | func (f *HeadersFrame) HeaderBlockFragment() []byte { | ||
940 | f.checkValid() | ||
941 | return f.headerFragBuf | ||
942 | } | ||
943 | |||
944 | func (f *HeadersFrame) HeadersEnded() bool { | ||
945 | return f.FrameHeader.Flags.Has(FlagHeadersEndHeaders) | ||
946 | } | ||
947 | |||
948 | func (f *HeadersFrame) StreamEnded() bool { | ||
949 | return f.FrameHeader.Flags.Has(FlagHeadersEndStream) | ||
950 | } | ||
951 | |||
952 | func (f *HeadersFrame) HasPriority() bool { | ||
953 | return f.FrameHeader.Flags.Has(FlagHeadersPriority) | ||
954 | } | ||
955 | |||
956 | func parseHeadersFrame(_ *frameCache, fh FrameHeader, p []byte) (_ Frame, err error) { | ||
957 | hf := &HeadersFrame{ | ||
958 | FrameHeader: fh, | ||
959 | } | ||
960 | if fh.StreamID == 0 { | ||
961 | // HEADERS frames MUST be associated with a stream. If a HEADERS frame | ||
962 | // is received whose stream identifier field is 0x0, the recipient MUST | ||
963 | // respond with a connection error (Section 5.4.1) of type | ||
964 | // PROTOCOL_ERROR. | ||
965 | return nil, connError{ErrCodeProtocol, "HEADERS frame with stream ID 0"} | ||
966 | } | ||
967 | var padLength uint8 | ||
968 | if fh.Flags.Has(FlagHeadersPadded) { | ||
969 | if p, padLength, err = readByte(p); err != nil { | ||
970 | return | ||
971 | } | ||
972 | } | ||
973 | if fh.Flags.Has(FlagHeadersPriority) { | ||
974 | var v uint32 | ||
975 | p, v, err = readUint32(p) | ||
976 | if err != nil { | ||
977 | return nil, err | ||
978 | } | ||
979 | hf.Priority.StreamDep = v & 0x7fffffff | ||
980 | hf.Priority.Exclusive = (v != hf.Priority.StreamDep) // high bit was set | ||
981 | p, hf.Priority.Weight, err = readByte(p) | ||
982 | if err != nil { | ||
983 | return nil, err | ||
984 | } | ||
985 | } | ||
986 | if len(p)-int(padLength) <= 0 { | ||
987 | return nil, streamError(fh.StreamID, ErrCodeProtocol) | ||
988 | } | ||
989 | hf.headerFragBuf = p[:len(p)-int(padLength)] | ||
990 | return hf, nil | ||
991 | } | ||
992 | |||
993 | // HeadersFrameParam are the parameters for writing a HEADERS frame. | ||
994 | type HeadersFrameParam struct { | ||
995 | // StreamID is the required Stream ID to initiate. | ||
996 | StreamID uint32 | ||
997 | // BlockFragment is part (or all) of a Header Block. | ||
998 | BlockFragment []byte | ||
999 | |||
1000 | // EndStream indicates that the header block is the last that | ||
1001 | // the endpoint will send for the identified stream. Setting | ||
1002 | // this flag causes the stream to enter one of "half closed" | ||
1003 | // states. | ||
1004 | EndStream bool | ||
1005 | |||
1006 | // EndHeaders indicates that this frame contains an entire | ||
1007 | // header block and is not followed by any | ||
1008 | // CONTINUATION frames. | ||
1009 | EndHeaders bool | ||
1010 | |||
1011 | // PadLength is the optional number of bytes of zeros to add | ||
1012 | // to this frame. | ||
1013 | PadLength uint8 | ||
1014 | |||
1015 | // Priority, if non-zero, includes stream priority information | ||
1016 | // in the HEADER frame. | ||
1017 | Priority PriorityParam | ||
1018 | } | ||
1019 | |||
1020 | // WriteHeaders writes a single HEADERS frame. | ||
1021 | // | ||
1022 | // This is a low-level header writing method. Encoding headers and | ||
1023 | // splitting them into any necessary CONTINUATION frames is handled | ||
1024 | // elsewhere. | ||
1025 | // | ||
1026 | // It will perform exactly one Write to the underlying Writer. | ||
1027 | // It is the caller's responsibility to not call other Write methods concurrently. | ||
1028 | func (f *Framer) WriteHeaders(p HeadersFrameParam) error { | ||
1029 | if !validStreamID(p.StreamID) && !f.AllowIllegalWrites { | ||
1030 | return errStreamID | ||
1031 | } | ||
1032 | var flags Flags | ||
1033 | if p.PadLength != 0 { | ||
1034 | flags |= FlagHeadersPadded | ||
1035 | } | ||
1036 | if p.EndStream { | ||
1037 | flags |= FlagHeadersEndStream | ||
1038 | } | ||
1039 | if p.EndHeaders { | ||
1040 | flags |= FlagHeadersEndHeaders | ||
1041 | } | ||
1042 | if !p.Priority.IsZero() { | ||
1043 | flags |= FlagHeadersPriority | ||
1044 | } | ||
1045 | f.startWrite(FrameHeaders, flags, p.StreamID) | ||
1046 | if p.PadLength != 0 { | ||
1047 | f.writeByte(p.PadLength) | ||
1048 | } | ||
1049 | if !p.Priority.IsZero() { | ||
1050 | v := p.Priority.StreamDep | ||
1051 | if !validStreamIDOrZero(v) && !f.AllowIllegalWrites { | ||
1052 | return errDepStreamID | ||
1053 | } | ||
1054 | if p.Priority.Exclusive { | ||
1055 | v |= 1 << 31 | ||
1056 | } | ||
1057 | f.writeUint32(v) | ||
1058 | f.writeByte(p.Priority.Weight) | ||
1059 | } | ||
1060 | f.wbuf = append(f.wbuf, p.BlockFragment...) | ||
1061 | f.wbuf = append(f.wbuf, padZeros[:p.PadLength]...) | ||
1062 | return f.endWrite() | ||
1063 | } | ||
1064 | |||
1065 | // A PriorityFrame specifies the sender-advised priority of a stream. | ||
1066 | // See http://http2.github.io/http2-spec/#rfc.section.6.3 | ||
1067 | type PriorityFrame struct { | ||
1068 | FrameHeader | ||
1069 | PriorityParam | ||
1070 | } | ||
1071 | |||
1072 | // PriorityParam are the stream prioritzation parameters. | ||
1073 | type PriorityParam struct { | ||
1074 | // StreamDep is a 31-bit stream identifier for the | ||
1075 | // stream that this stream depends on. Zero means no | ||
1076 | // dependency. | ||
1077 | StreamDep uint32 | ||
1078 | |||
1079 | // Exclusive is whether the dependency is exclusive. | ||
1080 | Exclusive bool | ||
1081 | |||
1082 | // Weight is the stream's zero-indexed weight. It should be | ||
1083 | // set together with StreamDep, or neither should be set. Per | ||
1084 | // the spec, "Add one to the value to obtain a weight between | ||
1085 | // 1 and 256." | ||
1086 | Weight uint8 | ||
1087 | } | ||
1088 | |||
1089 | func (p PriorityParam) IsZero() bool { | ||
1090 | return p == PriorityParam{} | ||
1091 | } | ||
1092 | |||
1093 | func parsePriorityFrame(_ *frameCache, fh FrameHeader, payload []byte) (Frame, error) { | ||
1094 | if fh.StreamID == 0 { | ||
1095 | return nil, connError{ErrCodeProtocol, "PRIORITY frame with stream ID 0"} | ||
1096 | } | ||
1097 | if len(payload) != 5 { | ||
1098 | return nil, connError{ErrCodeFrameSize, fmt.Sprintf("PRIORITY frame payload size was %d; want 5", len(payload))} | ||
1099 | } | ||
1100 | v := binary.BigEndian.Uint32(payload[:4]) | ||
1101 | streamID := v & 0x7fffffff // mask off high bit | ||
1102 | return &PriorityFrame{ | ||
1103 | FrameHeader: fh, | ||
1104 | PriorityParam: PriorityParam{ | ||
1105 | Weight: payload[4], | ||
1106 | StreamDep: streamID, | ||
1107 | Exclusive: streamID != v, // was high bit set? | ||
1108 | }, | ||
1109 | }, nil | ||
1110 | } | ||
1111 | |||
1112 | // WritePriority writes a PRIORITY frame. | ||
1113 | // | ||
1114 | // It will perform exactly one Write to the underlying Writer. | ||
1115 | // It is the caller's responsibility to not call other Write methods concurrently. | ||
1116 | func (f *Framer) WritePriority(streamID uint32, p PriorityParam) error { | ||
1117 | if !validStreamID(streamID) && !f.AllowIllegalWrites { | ||
1118 | return errStreamID | ||
1119 | } | ||
1120 | if !validStreamIDOrZero(p.StreamDep) { | ||
1121 | return errDepStreamID | ||
1122 | } | ||
1123 | f.startWrite(FramePriority, 0, streamID) | ||
1124 | v := p.StreamDep | ||
1125 | if p.Exclusive { | ||
1126 | v |= 1 << 31 | ||
1127 | } | ||
1128 | f.writeUint32(v) | ||
1129 | f.writeByte(p.Weight) | ||
1130 | return f.endWrite() | ||
1131 | } | ||
1132 | |||
1133 | // A RSTStreamFrame allows for abnormal termination of a stream. | ||
1134 | // See http://http2.github.io/http2-spec/#rfc.section.6.4 | ||
1135 | type RSTStreamFrame struct { | ||
1136 | FrameHeader | ||
1137 | ErrCode ErrCode | ||
1138 | } | ||
1139 | |||
1140 | func parseRSTStreamFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) { | ||
1141 | if len(p) != 4 { | ||
1142 | return nil, ConnectionError(ErrCodeFrameSize) | ||
1143 | } | ||
1144 | if fh.StreamID == 0 { | ||
1145 | return nil, ConnectionError(ErrCodeProtocol) | ||
1146 | } | ||
1147 | return &RSTStreamFrame{fh, ErrCode(binary.BigEndian.Uint32(p[:4]))}, nil | ||
1148 | } | ||
1149 | |||
1150 | // WriteRSTStream writes a RST_STREAM frame. | ||
1151 | // | ||
1152 | // It will perform exactly one Write to the underlying Writer. | ||
1153 | // It is the caller's responsibility to not call other Write methods concurrently. | ||
1154 | func (f *Framer) WriteRSTStream(streamID uint32, code ErrCode) error { | ||
1155 | if !validStreamID(streamID) && !f.AllowIllegalWrites { | ||
1156 | return errStreamID | ||
1157 | } | ||
1158 | f.startWrite(FrameRSTStream, 0, streamID) | ||
1159 | f.writeUint32(uint32(code)) | ||
1160 | return f.endWrite() | ||
1161 | } | ||
1162 | |||
1163 | // A ContinuationFrame is used to continue a sequence of header block fragments. | ||
1164 | // See http://http2.github.io/http2-spec/#rfc.section.6.10 | ||
1165 | type ContinuationFrame struct { | ||
1166 | FrameHeader | ||
1167 | headerFragBuf []byte | ||
1168 | } | ||
1169 | |||
1170 | func parseContinuationFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) { | ||
1171 | if fh.StreamID == 0 { | ||
1172 | return nil, connError{ErrCodeProtocol, "CONTINUATION frame with stream ID 0"} | ||
1173 | } | ||
1174 | return &ContinuationFrame{fh, p}, nil | ||
1175 | } | ||
1176 | |||
1177 | func (f *ContinuationFrame) HeaderBlockFragment() []byte { | ||
1178 | f.checkValid() | ||
1179 | return f.headerFragBuf | ||
1180 | } | ||
1181 | |||
1182 | func (f *ContinuationFrame) HeadersEnded() bool { | ||
1183 | return f.FrameHeader.Flags.Has(FlagContinuationEndHeaders) | ||
1184 | } | ||
1185 | |||
1186 | // WriteContinuation writes a CONTINUATION frame. | ||
1187 | // | ||
1188 | // It will perform exactly one Write to the underlying Writer. | ||
1189 | // It is the caller's responsibility to not call other Write methods concurrently. | ||
1190 | func (f *Framer) WriteContinuation(streamID uint32, endHeaders bool, headerBlockFragment []byte) error { | ||
1191 | if !validStreamID(streamID) && !f.AllowIllegalWrites { | ||
1192 | return errStreamID | ||
1193 | } | ||
1194 | var flags Flags | ||
1195 | if endHeaders { | ||
1196 | flags |= FlagContinuationEndHeaders | ||
1197 | } | ||
1198 | f.startWrite(FrameContinuation, flags, streamID) | ||
1199 | f.wbuf = append(f.wbuf, headerBlockFragment...) | ||
1200 | return f.endWrite() | ||
1201 | } | ||
1202 | |||
1203 | // A PushPromiseFrame is used to initiate a server stream. | ||
1204 | // See http://http2.github.io/http2-spec/#rfc.section.6.6 | ||
1205 | type PushPromiseFrame struct { | ||
1206 | FrameHeader | ||
1207 | PromiseID uint32 | ||
1208 | headerFragBuf []byte // not owned | ||
1209 | } | ||
1210 | |||
1211 | func (f *PushPromiseFrame) HeaderBlockFragment() []byte { | ||
1212 | f.checkValid() | ||
1213 | return f.headerFragBuf | ||
1214 | } | ||
1215 | |||
1216 | func (f *PushPromiseFrame) HeadersEnded() bool { | ||
1217 | return f.FrameHeader.Flags.Has(FlagPushPromiseEndHeaders) | ||
1218 | } | ||
1219 | |||
1220 | func parsePushPromise(_ *frameCache, fh FrameHeader, p []byte) (_ Frame, err error) { | ||
1221 | pp := &PushPromiseFrame{ | ||
1222 | FrameHeader: fh, | ||
1223 | } | ||
1224 | if pp.StreamID == 0 { | ||
1225 | // PUSH_PROMISE frames MUST be associated with an existing, | ||
1226 | // peer-initiated stream. The stream identifier of a | ||
1227 | // PUSH_PROMISE frame indicates the stream it is associated | ||
1228 | // with. If the stream identifier field specifies the value | ||
1229 | // 0x0, a recipient MUST respond with a connection error | ||
1230 | // (Section 5.4.1) of type PROTOCOL_ERROR. | ||
1231 | return nil, ConnectionError(ErrCodeProtocol) | ||
1232 | } | ||
1233 | // The PUSH_PROMISE frame includes optional padding. | ||
1234 | // Padding fields and flags are identical to those defined for DATA frames | ||
1235 | var padLength uint8 | ||
1236 | if fh.Flags.Has(FlagPushPromisePadded) { | ||
1237 | if p, padLength, err = readByte(p); err != nil { | ||
1238 | return | ||
1239 | } | ||
1240 | } | ||
1241 | |||
1242 | p, pp.PromiseID, err = readUint32(p) | ||
1243 | if err != nil { | ||
1244 | return | ||
1245 | } | ||
1246 | pp.PromiseID = pp.PromiseID & (1<<31 - 1) | ||
1247 | |||
1248 | if int(padLength) > len(p) { | ||
1249 | // like the DATA frame, error out if padding is longer than the body. | ||
1250 | return nil, ConnectionError(ErrCodeProtocol) | ||
1251 | } | ||
1252 | pp.headerFragBuf = p[:len(p)-int(padLength)] | ||
1253 | return pp, nil | ||
1254 | } | ||
1255 | |||
1256 | // PushPromiseParam are the parameters for writing a PUSH_PROMISE frame. | ||
1257 | type PushPromiseParam struct { | ||
1258 | // StreamID is the required Stream ID to initiate. | ||
1259 | StreamID uint32 | ||
1260 | |||
1261 | // PromiseID is the required Stream ID which this | ||
1262 | // Push Promises | ||
1263 | PromiseID uint32 | ||
1264 | |||
1265 | // BlockFragment is part (or all) of a Header Block. | ||
1266 | BlockFragment []byte | ||
1267 | |||
1268 | // EndHeaders indicates that this frame contains an entire | ||
1269 | // header block and is not followed by any | ||
1270 | // CONTINUATION frames. | ||
1271 | EndHeaders bool | ||
1272 | |||
1273 | // PadLength is the optional number of bytes of zeros to add | ||
1274 | // to this frame. | ||
1275 | PadLength uint8 | ||
1276 | } | ||
1277 | |||
1278 | // WritePushPromise writes a single PushPromise Frame. | ||
1279 | // | ||
1280 | // As with Header Frames, This is the low level call for writing | ||
1281 | // individual frames. Continuation frames are handled elsewhere. | ||
1282 | // | ||
1283 | // It will perform exactly one Write to the underlying Writer. | ||
1284 | // It is the caller's responsibility to not call other Write methods concurrently. | ||
1285 | func (f *Framer) WritePushPromise(p PushPromiseParam) error { | ||
1286 | if !validStreamID(p.StreamID) && !f.AllowIllegalWrites { | ||
1287 | return errStreamID | ||
1288 | } | ||
1289 | var flags Flags | ||
1290 | if p.PadLength != 0 { | ||
1291 | flags |= FlagPushPromisePadded | ||
1292 | } | ||
1293 | if p.EndHeaders { | ||
1294 | flags |= FlagPushPromiseEndHeaders | ||
1295 | } | ||
1296 | f.startWrite(FramePushPromise, flags, p.StreamID) | ||
1297 | if p.PadLength != 0 { | ||
1298 | f.writeByte(p.PadLength) | ||
1299 | } | ||
1300 | if !validStreamID(p.PromiseID) && !f.AllowIllegalWrites { | ||
1301 | return errStreamID | ||
1302 | } | ||
1303 | f.writeUint32(p.PromiseID) | ||
1304 | f.wbuf = append(f.wbuf, p.BlockFragment...) | ||
1305 | f.wbuf = append(f.wbuf, padZeros[:p.PadLength]...) | ||
1306 | return f.endWrite() | ||
1307 | } | ||
1308 | |||
1309 | // WriteRawFrame writes a raw frame. This can be used to write | ||
1310 | // extension frames unknown to this package. | ||
1311 | func (f *Framer) WriteRawFrame(t FrameType, flags Flags, streamID uint32, payload []byte) error { | ||
1312 | f.startWrite(t, flags, streamID) | ||
1313 | f.writeBytes(payload) | ||
1314 | return f.endWrite() | ||
1315 | } | ||
1316 | |||
1317 | func readByte(p []byte) (remain []byte, b byte, err error) { | ||
1318 | if len(p) == 0 { | ||
1319 | return nil, 0, io.ErrUnexpectedEOF | ||
1320 | } | ||
1321 | return p[1:], p[0], nil | ||
1322 | } | ||
1323 | |||
1324 | func readUint32(p []byte) (remain []byte, v uint32, err error) { | ||
1325 | if len(p) < 4 { | ||
1326 | return nil, 0, io.ErrUnexpectedEOF | ||
1327 | } | ||
1328 | return p[4:], binary.BigEndian.Uint32(p[:4]), nil | ||
1329 | } | ||
1330 | |||
1331 | type streamEnder interface { | ||
1332 | StreamEnded() bool | ||
1333 | } | ||
1334 | |||
1335 | type headersEnder interface { | ||
1336 | HeadersEnded() bool | ||
1337 | } | ||
1338 | |||
1339 | type headersOrContinuation interface { | ||
1340 | headersEnder | ||
1341 | HeaderBlockFragment() []byte | ||
1342 | } | ||
1343 | |||
1344 | // A MetaHeadersFrame is the representation of one HEADERS frame and | ||
1345 | // zero or more contiguous CONTINUATION frames and the decoding of | ||
1346 | // their HPACK-encoded contents. | ||
1347 | // | ||
1348 | // This type of frame does not appear on the wire and is only returned | ||
1349 | // by the Framer when Framer.ReadMetaHeaders is set. | ||
1350 | type MetaHeadersFrame struct { | ||
1351 | *HeadersFrame | ||
1352 | |||
1353 | // Fields are the fields contained in the HEADERS and | ||
1354 | // CONTINUATION frames. The underlying slice is owned by the | ||
1355 | // Framer and must not be retained after the next call to | ||
1356 | // ReadFrame. | ||
1357 | // | ||
1358 | // Fields are guaranteed to be in the correct http2 order and | ||
1359 | // not have unknown pseudo header fields or invalid header | ||
1360 | // field names or values. Required pseudo header fields may be | ||
1361 | // missing, however. Use the MetaHeadersFrame.Pseudo accessor | ||
1362 | // method access pseudo headers. | ||
1363 | Fields []hpack.HeaderField | ||
1364 | |||
1365 | // Truncated is whether the max header list size limit was hit | ||
1366 | // and Fields is incomplete. The hpack decoder state is still | ||
1367 | // valid, however. | ||
1368 | Truncated bool | ||
1369 | } | ||
1370 | |||
1371 | // PseudoValue returns the given pseudo header field's value. | ||
1372 | // The provided pseudo field should not contain the leading colon. | ||
1373 | func (mh *MetaHeadersFrame) PseudoValue(pseudo string) string { | ||
1374 | for _, hf := range mh.Fields { | ||
1375 | if !hf.IsPseudo() { | ||
1376 | return "" | ||
1377 | } | ||
1378 | if hf.Name[1:] == pseudo { | ||
1379 | return hf.Value | ||
1380 | } | ||
1381 | } | ||
1382 | return "" | ||
1383 | } | ||
1384 | |||
1385 | // RegularFields returns the regular (non-pseudo) header fields of mh. | ||
1386 | // The caller does not own the returned slice. | ||
1387 | func (mh *MetaHeadersFrame) RegularFields() []hpack.HeaderField { | ||
1388 | for i, hf := range mh.Fields { | ||
1389 | if !hf.IsPseudo() { | ||
1390 | return mh.Fields[i:] | ||
1391 | } | ||
1392 | } | ||
1393 | return nil | ||
1394 | } | ||
1395 | |||
1396 | // PseudoFields returns the pseudo header fields of mh. | ||
1397 | // The caller does not own the returned slice. | ||
1398 | func (mh *MetaHeadersFrame) PseudoFields() []hpack.HeaderField { | ||
1399 | for i, hf := range mh.Fields { | ||
1400 | if !hf.IsPseudo() { | ||
1401 | return mh.Fields[:i] | ||
1402 | } | ||
1403 | } | ||
1404 | return mh.Fields | ||
1405 | } | ||
1406 | |||
1407 | func (mh *MetaHeadersFrame) checkPseudos() error { | ||
1408 | var isRequest, isResponse bool | ||
1409 | pf := mh.PseudoFields() | ||
1410 | for i, hf := range pf { | ||
1411 | switch hf.Name { | ||
1412 | case ":method", ":path", ":scheme", ":authority": | ||
1413 | isRequest = true | ||
1414 | case ":status": | ||
1415 | isResponse = true | ||
1416 | default: | ||
1417 | return pseudoHeaderError(hf.Name) | ||
1418 | } | ||
1419 | // Check for duplicates. | ||
1420 | // This would be a bad algorithm, but N is 4. | ||
1421 | // And this doesn't allocate. | ||
1422 | for _, hf2 := range pf[:i] { | ||
1423 | if hf.Name == hf2.Name { | ||
1424 | return duplicatePseudoHeaderError(hf.Name) | ||
1425 | } | ||
1426 | } | ||
1427 | } | ||
1428 | if isRequest && isResponse { | ||
1429 | return errMixPseudoHeaderTypes | ||
1430 | } | ||
1431 | return nil | ||
1432 | } | ||
1433 | |||
1434 | func (fr *Framer) maxHeaderStringLen() int { | ||
1435 | v := fr.maxHeaderListSize() | ||
1436 | if uint32(int(v)) == v { | ||
1437 | return int(v) | ||
1438 | } | ||
1439 | // They had a crazy big number for MaxHeaderBytes anyway, | ||
1440 | // so give them unlimited header lengths: | ||
1441 | return 0 | ||
1442 | } | ||
1443 | |||
1444 | // readMetaFrame returns 0 or more CONTINUATION frames from fr and | ||
1445 | // merge them into into the provided hf and returns a MetaHeadersFrame | ||
1446 | // with the decoded hpack values. | ||
1447 | func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) { | ||
1448 | if fr.AllowIllegalReads { | ||
1449 | return nil, errors.New("illegal use of AllowIllegalReads with ReadMetaHeaders") | ||
1450 | } | ||
1451 | mh := &MetaHeadersFrame{ | ||
1452 | HeadersFrame: hf, | ||
1453 | } | ||
1454 | var remainSize = fr.maxHeaderListSize() | ||
1455 | var sawRegular bool | ||
1456 | |||
1457 | var invalid error // pseudo header field errors | ||
1458 | hdec := fr.ReadMetaHeaders | ||
1459 | hdec.SetEmitEnabled(true) | ||
1460 | hdec.SetMaxStringLength(fr.maxHeaderStringLen()) | ||
1461 | hdec.SetEmitFunc(func(hf hpack.HeaderField) { | ||
1462 | if VerboseLogs && fr.logReads { | ||
1463 | fr.debugReadLoggerf("http2: decoded hpack field %+v", hf) | ||
1464 | } | ||
1465 | if !httplex.ValidHeaderFieldValue(hf.Value) { | ||
1466 | invalid = headerFieldValueError(hf.Value) | ||
1467 | } | ||
1468 | isPseudo := strings.HasPrefix(hf.Name, ":") | ||
1469 | if isPseudo { | ||
1470 | if sawRegular { | ||
1471 | invalid = errPseudoAfterRegular | ||
1472 | } | ||
1473 | } else { | ||
1474 | sawRegular = true | ||
1475 | if !validWireHeaderFieldName(hf.Name) { | ||
1476 | invalid = headerFieldNameError(hf.Name) | ||
1477 | } | ||
1478 | } | ||
1479 | |||
1480 | if invalid != nil { | ||
1481 | hdec.SetEmitEnabled(false) | ||
1482 | return | ||
1483 | } | ||
1484 | |||
1485 | size := hf.Size() | ||
1486 | if size > remainSize { | ||
1487 | hdec.SetEmitEnabled(false) | ||
1488 | mh.Truncated = true | ||
1489 | return | ||
1490 | } | ||
1491 | remainSize -= size | ||
1492 | |||
1493 | mh.Fields = append(mh.Fields, hf) | ||
1494 | }) | ||
1495 | // Lose reference to MetaHeadersFrame: | ||
1496 | defer hdec.SetEmitFunc(func(hf hpack.HeaderField) {}) | ||
1497 | |||
1498 | var hc headersOrContinuation = hf | ||
1499 | for { | ||
1500 | frag := hc.HeaderBlockFragment() | ||
1501 | if _, err := hdec.Write(frag); err != nil { | ||
1502 | return nil, ConnectionError(ErrCodeCompression) | ||
1503 | } | ||
1504 | |||
1505 | if hc.HeadersEnded() { | ||
1506 | break | ||
1507 | } | ||
1508 | if f, err := fr.ReadFrame(); err != nil { | ||
1509 | return nil, err | ||
1510 | } else { | ||
1511 | hc = f.(*ContinuationFrame) // guaranteed by checkFrameOrder | ||
1512 | } | ||
1513 | } | ||
1514 | |||
1515 | mh.HeadersFrame.headerFragBuf = nil | ||
1516 | mh.HeadersFrame.invalidate() | ||
1517 | |||
1518 | if err := hdec.Close(); err != nil { | ||
1519 | return nil, ConnectionError(ErrCodeCompression) | ||
1520 | } | ||
1521 | if invalid != nil { | ||
1522 | fr.errDetail = invalid | ||
1523 | if VerboseLogs { | ||
1524 | log.Printf("http2: invalid header: %v", invalid) | ||
1525 | } | ||
1526 | return nil, StreamError{mh.StreamID, ErrCodeProtocol, invalid} | ||
1527 | } | ||
1528 | if err := mh.checkPseudos(); err != nil { | ||
1529 | fr.errDetail = err | ||
1530 | if VerboseLogs { | ||
1531 | log.Printf("http2: invalid pseudo headers: %v", err) | ||
1532 | } | ||
1533 | return nil, StreamError{mh.StreamID, ErrCodeProtocol, err} | ||
1534 | } | ||
1535 | return mh, nil | ||
1536 | } | ||
1537 | |||
1538 | func summarizeFrame(f Frame) string { | ||
1539 | var buf bytes.Buffer | ||
1540 | f.Header().writeDebug(&buf) | ||
1541 | switch f := f.(type) { | ||
1542 | case *SettingsFrame: | ||
1543 | n := 0 | ||
1544 | f.ForeachSetting(func(s Setting) error { | ||
1545 | n++ | ||
1546 | if n == 1 { | ||
1547 | buf.WriteString(", settings:") | ||
1548 | } | ||
1549 | fmt.Fprintf(&buf, " %v=%v,", s.ID, s.Val) | ||
1550 | return nil | ||
1551 | }) | ||
1552 | if n > 0 { | ||
1553 | buf.Truncate(buf.Len() - 1) // remove trailing comma | ||
1554 | } | ||
1555 | case *DataFrame: | ||
1556 | data := f.Data() | ||
1557 | const max = 256 | ||
1558 | if len(data) > max { | ||
1559 | data = data[:max] | ||
1560 | } | ||
1561 | fmt.Fprintf(&buf, " data=%q", data) | ||
1562 | if len(f.Data()) > max { | ||
1563 | fmt.Fprintf(&buf, " (%d bytes omitted)", len(f.Data())-max) | ||
1564 | } | ||
1565 | case *WindowUpdateFrame: | ||
1566 | if f.StreamID == 0 { | ||
1567 | buf.WriteString(" (conn)") | ||
1568 | } | ||
1569 | fmt.Fprintf(&buf, " incr=%v", f.Increment) | ||
1570 | case *PingFrame: | ||
1571 | fmt.Fprintf(&buf, " ping=%q", f.Data[:]) | ||
1572 | case *GoAwayFrame: | ||
1573 | fmt.Fprintf(&buf, " LastStreamID=%v ErrCode=%v Debug=%q", | ||
1574 | f.LastStreamID, f.ErrCode, f.debugData) | ||
1575 | case *RSTStreamFrame: | ||
1576 | fmt.Fprintf(&buf, " ErrCode=%v", f.ErrCode) | ||
1577 | } | ||
1578 | return buf.String() | ||
1579 | } | ||