github.com/q45/go@v0.0.0-20151101211701-a4fb8c13db3f/src/net/http/h2_bundle.go (about) 1 // Code generated by golang.org/x/tools/cmd/bundle command: 2 // $ bundle golang.org/x/net/http2 net/http http2 3 4 // Package http2 implements the HTTP/2 protocol. 5 // 6 // This is a work in progress. This package is low-level and intended 7 // to be used directly by very few people. Most users will use it 8 // indirectly through integration with the net/http package. See 9 // ConfigureServer. That ConfigureServer call will likely be automatic 10 // or available via an empty import in the future. 11 // 12 // See http://http2.github.io/ 13 // 14 package http 15 16 import ( 17 "bufio" 18 "bytes" 19 "crypto/tls" 20 "encoding/binary" 21 "errors" 22 "fmt" 23 "golang.org/x/net/http2/hpack" 24 "io" 25 "io/ioutil" 26 "log" 27 "net" 28 "net/url" 29 "os" 30 "runtime" 31 "strconv" 32 "strings" 33 "sync" 34 "time" 35 ) 36 37 // An ErrCode is an unsigned 32-bit error code as defined in the HTTP/2 spec. 38 type http2ErrCode uint32 39 40 const ( 41 http2ErrCodeNo http2ErrCode = 0x0 42 http2ErrCodeProtocol http2ErrCode = 0x1 43 http2ErrCodeInternal http2ErrCode = 0x2 44 http2ErrCodeFlowControl http2ErrCode = 0x3 45 http2ErrCodeSettingsTimeout http2ErrCode = 0x4 46 http2ErrCodeStreamClosed http2ErrCode = 0x5 47 http2ErrCodeFrameSize http2ErrCode = 0x6 48 http2ErrCodeRefusedStream http2ErrCode = 0x7 49 http2ErrCodeCancel http2ErrCode = 0x8 50 http2ErrCodeCompression http2ErrCode = 0x9 51 http2ErrCodeConnect http2ErrCode = 0xa 52 http2ErrCodeEnhanceYourCalm http2ErrCode = 0xb 53 http2ErrCodeInadequateSecurity http2ErrCode = 0xc 54 http2ErrCodeHTTP11Required http2ErrCode = 0xd 55 ) 56 57 var http2errCodeName = map[http2ErrCode]string{ 58 http2ErrCodeNo: "NO_ERROR", 59 http2ErrCodeProtocol: "PROTOCOL_ERROR", 60 http2ErrCodeInternal: "INTERNAL_ERROR", 61 http2ErrCodeFlowControl: "FLOW_CONTROL_ERROR", 62 http2ErrCodeSettingsTimeout: "SETTINGS_TIMEOUT", 63 http2ErrCodeStreamClosed: "STREAM_CLOSED", 64 http2ErrCodeFrameSize: "FRAME_SIZE_ERROR", 65 http2ErrCodeRefusedStream: "REFUSED_STREAM", 66 http2ErrCodeCancel: "CANCEL", 67 http2ErrCodeCompression: "COMPRESSION_ERROR", 68 http2ErrCodeConnect: "CONNECT_ERROR", 69 http2ErrCodeEnhanceYourCalm: "ENHANCE_YOUR_CALM", 70 http2ErrCodeInadequateSecurity: "INADEQUATE_SECURITY", 71 http2ErrCodeHTTP11Required: "HTTP_1_1_REQUIRED", 72 } 73 74 func (e http2ErrCode) String() string { 75 if s, ok := http2errCodeName[e]; ok { 76 return s 77 } 78 return fmt.Sprintf("unknown error code 0x%x", uint32(e)) 79 } 80 81 // ConnectionError is an error that results in the termination of the 82 // entire connection. 83 type http2ConnectionError http2ErrCode 84 85 func (e http2ConnectionError) Error() string { 86 return fmt.Sprintf("connection error: %s", http2ErrCode(e)) 87 } 88 89 // StreamError is an error that only affects one stream within an 90 // HTTP/2 connection. 91 type http2StreamError struct { 92 StreamID uint32 93 Code http2ErrCode 94 } 95 96 func (e http2StreamError) Error() string { 97 return fmt.Sprintf("stream error: stream ID %d; %v", e.StreamID, e.Code) 98 } 99 100 // 6.9.1 The Flow Control Window 101 // "If a sender receives a WINDOW_UPDATE that causes a flow control 102 // window to exceed this maximum it MUST terminate either the stream 103 // or the connection, as appropriate. For streams, [...]; for the 104 // connection, a GOAWAY frame with a FLOW_CONTROL_ERROR code." 105 type http2goAwayFlowError struct{} 106 107 func (http2goAwayFlowError) Error() string { return "connection exceeded flow control window size" } 108 109 // fixedBuffer is an io.ReadWriter backed by a fixed size buffer. 110 // It never allocates, but moves old data as new data is written. 111 type http2fixedBuffer struct { 112 buf []byte 113 r, w int 114 } 115 116 var ( 117 http2errReadEmpty = errors.New("read from empty fixedBuffer") 118 http2errWriteFull = errors.New("write on full fixedBuffer") 119 ) 120 121 // Read copies bytes from the buffer into p. 122 // It is an error to read when no data is available. 123 func (b *http2fixedBuffer) Read(p []byte) (n int, err error) { 124 if b.r == b.w { 125 return 0, http2errReadEmpty 126 } 127 n = copy(p, b.buf[b.r:b.w]) 128 b.r += n 129 if b.r == b.w { 130 b.r = 0 131 b.w = 0 132 } 133 return n, nil 134 } 135 136 // Len returns the number of bytes of the unread portion of the buffer. 137 func (b *http2fixedBuffer) Len() int { 138 return b.w - b.r 139 } 140 141 // Write copies bytes from p into the buffer. 142 // It is an error to write more data than the buffer can hold. 143 func (b *http2fixedBuffer) Write(p []byte) (n int, err error) { 144 145 if b.r > 0 && len(p) > len(b.buf)-b.w { 146 copy(b.buf, b.buf[b.r:b.w]) 147 b.w -= b.r 148 b.r = 0 149 } 150 151 n = copy(b.buf[b.w:], p) 152 b.w += n 153 if n < len(p) { 154 err = http2errWriteFull 155 } 156 return n, err 157 } 158 159 // flow is the flow control window's size. 160 type http2flow struct { 161 // n is the number of DATA bytes we're allowed to send. 162 // A flow is kept both on a conn and a per-stream. 163 n int32 164 165 // conn points to the shared connection-level flow that is 166 // shared by all streams on that conn. It is nil for the flow 167 // that's on the conn directly. 168 conn *http2flow 169 } 170 171 func (f *http2flow) setConnFlow(cf *http2flow) { f.conn = cf } 172 173 func (f *http2flow) available() int32 { 174 n := f.n 175 if f.conn != nil && f.conn.n < n { 176 n = f.conn.n 177 } 178 return n 179 } 180 181 func (f *http2flow) take(n int32) { 182 if n > f.available() { 183 panic("internal error: took too much") 184 } 185 f.n -= n 186 if f.conn != nil { 187 f.conn.n -= n 188 } 189 } 190 191 // add adds n bytes (positive or negative) to the flow control window. 192 // It returns false if the sum would exceed 2^31-1. 193 func (f *http2flow) add(n int32) bool { 194 remain := (1<<31 - 1) - f.n 195 if n > remain { 196 return false 197 } 198 f.n += n 199 return true 200 } 201 202 const http2frameHeaderLen = 9 203 204 var http2padZeros = make([]byte, 255) // zeros for padding 205 206 // A FrameType is a registered frame type as defined in 207 // http://http2.github.io/http2-spec/#rfc.section.11.2 208 type http2FrameType uint8 209 210 const ( 211 http2FrameData http2FrameType = 0x0 212 http2FrameHeaders http2FrameType = 0x1 213 http2FramePriority http2FrameType = 0x2 214 http2FrameRSTStream http2FrameType = 0x3 215 http2FrameSettings http2FrameType = 0x4 216 http2FramePushPromise http2FrameType = 0x5 217 http2FramePing http2FrameType = 0x6 218 http2FrameGoAway http2FrameType = 0x7 219 http2FrameWindowUpdate http2FrameType = 0x8 220 http2FrameContinuation http2FrameType = 0x9 221 ) 222 223 var http2frameName = map[http2FrameType]string{ 224 http2FrameData: "DATA", 225 http2FrameHeaders: "HEADERS", 226 http2FramePriority: "PRIORITY", 227 http2FrameRSTStream: "RST_STREAM", 228 http2FrameSettings: "SETTINGS", 229 http2FramePushPromise: "PUSH_PROMISE", 230 http2FramePing: "PING", 231 http2FrameGoAway: "GOAWAY", 232 http2FrameWindowUpdate: "WINDOW_UPDATE", 233 http2FrameContinuation: "CONTINUATION", 234 } 235 236 func (t http2FrameType) String() string { 237 if s, ok := http2frameName[t]; ok { 238 return s 239 } 240 return fmt.Sprintf("UNKNOWN_FRAME_TYPE_%d", uint8(t)) 241 } 242 243 // Flags is a bitmask of HTTP/2 flags. 244 // The meaning of flags varies depending on the frame type. 245 type http2Flags uint8 246 247 // Has reports whether f contains all (0 or more) flags in v. 248 func (f http2Flags) Has(v http2Flags) bool { 249 return (f & v) == v 250 } 251 252 // Frame-specific FrameHeader flag bits. 253 const ( 254 // Data Frame 255 http2FlagDataEndStream http2Flags = 0x1 256 http2FlagDataPadded http2Flags = 0x8 257 258 // Headers Frame 259 http2FlagHeadersEndStream http2Flags = 0x1 260 http2FlagHeadersEndHeaders http2Flags = 0x4 261 http2FlagHeadersPadded http2Flags = 0x8 262 http2FlagHeadersPriority http2Flags = 0x20 263 264 // Settings Frame 265 http2FlagSettingsAck http2Flags = 0x1 266 267 // Ping Frame 268 http2FlagPingAck http2Flags = 0x1 269 270 // Continuation Frame 271 http2FlagContinuationEndHeaders http2Flags = 0x4 272 273 http2FlagPushPromiseEndHeaders http2Flags = 0x4 274 http2FlagPushPromisePadded http2Flags = 0x8 275 ) 276 277 var http2flagName = map[http2FrameType]map[http2Flags]string{ 278 http2FrameData: { 279 http2FlagDataEndStream: "END_STREAM", 280 http2FlagDataPadded: "PADDED", 281 }, 282 http2FrameHeaders: { 283 http2FlagHeadersEndStream: "END_STREAM", 284 http2FlagHeadersEndHeaders: "END_HEADERS", 285 http2FlagHeadersPadded: "PADDED", 286 http2FlagHeadersPriority: "PRIORITY", 287 }, 288 http2FrameSettings: { 289 http2FlagSettingsAck: "ACK", 290 }, 291 http2FramePing: { 292 http2FlagPingAck: "ACK", 293 }, 294 http2FrameContinuation: { 295 http2FlagContinuationEndHeaders: "END_HEADERS", 296 }, 297 http2FramePushPromise: { 298 http2FlagPushPromiseEndHeaders: "END_HEADERS", 299 http2FlagPushPromisePadded: "PADDED", 300 }, 301 } 302 303 // a frameParser parses a frame given its FrameHeader and payload 304 // bytes. The length of payload will always equal fh.Length (which 305 // might be 0). 306 type http2frameParser func(fh http2FrameHeader, payload []byte) (http2Frame, error) 307 308 var http2frameParsers = map[http2FrameType]http2frameParser{ 309 http2FrameData: http2parseDataFrame, 310 http2FrameHeaders: http2parseHeadersFrame, 311 http2FramePriority: http2parsePriorityFrame, 312 http2FrameRSTStream: http2parseRSTStreamFrame, 313 http2FrameSettings: http2parseSettingsFrame, 314 http2FramePushPromise: http2parsePushPromise, 315 http2FramePing: http2parsePingFrame, 316 http2FrameGoAway: http2parseGoAwayFrame, 317 http2FrameWindowUpdate: http2parseWindowUpdateFrame, 318 http2FrameContinuation: http2parseContinuationFrame, 319 } 320 321 func http2typeFrameParser(t http2FrameType) http2frameParser { 322 if f := http2frameParsers[t]; f != nil { 323 return f 324 } 325 return http2parseUnknownFrame 326 } 327 328 // A FrameHeader is the 9 byte header of all HTTP/2 frames. 329 // 330 // See http://http2.github.io/http2-spec/#FrameHeader 331 type http2FrameHeader struct { 332 valid bool // caller can access []byte fields in the Frame 333 334 // Type is the 1 byte frame type. There are ten standard frame 335 // types, but extension frame types may be written by WriteRawFrame 336 // and will be returned by ReadFrame (as UnknownFrame). 337 Type http2FrameType 338 339 // Flags are the 1 byte of 8 potential bit flags per frame. 340 // They are specific to the frame type. 341 Flags http2Flags 342 343 // Length is the length of the frame, not including the 9 byte header. 344 // The maximum size is one byte less than 16MB (uint24), but only 345 // frames up to 16KB are allowed without peer agreement. 346 Length uint32 347 348 // StreamID is which stream this frame is for. Certain frames 349 // are not stream-specific, in which case this field is 0. 350 StreamID uint32 351 } 352 353 // Header returns h. It exists so FrameHeaders can be embedded in other 354 // specific frame types and implement the Frame interface. 355 func (h http2FrameHeader) Header() http2FrameHeader { return h } 356 357 func (h http2FrameHeader) String() string { 358 var buf bytes.Buffer 359 buf.WriteString("[FrameHeader ") 360 buf.WriteString(h.Type.String()) 361 if h.Flags != 0 { 362 buf.WriteString(" flags=") 363 set := 0 364 for i := uint8(0); i < 8; i++ { 365 if h.Flags&(1<<i) == 0 { 366 continue 367 } 368 set++ 369 if set > 1 { 370 buf.WriteByte('|') 371 } 372 name := http2flagName[h.Type][http2Flags(1<<i)] 373 if name != "" { 374 buf.WriteString(name) 375 } else { 376 fmt.Fprintf(&buf, "0x%x", 1<<i) 377 } 378 } 379 } 380 if h.StreamID != 0 { 381 fmt.Fprintf(&buf, " stream=%d", h.StreamID) 382 } 383 fmt.Fprintf(&buf, " len=%d]", h.Length) 384 return buf.String() 385 } 386 387 func (h *http2FrameHeader) checkValid() { 388 if !h.valid { 389 panic("Frame accessor called on non-owned Frame") 390 } 391 } 392 393 func (h *http2FrameHeader) invalidate() { h.valid = false } 394 395 // frame header bytes. 396 // Used only by ReadFrameHeader. 397 var http2fhBytes = sync.Pool{ 398 New: func() interface{} { 399 buf := make([]byte, http2frameHeaderLen) 400 return &buf 401 }, 402 } 403 404 // ReadFrameHeader reads 9 bytes from r and returns a FrameHeader. 405 // Most users should use Framer.ReadFrame instead. 406 func http2ReadFrameHeader(r io.Reader) (http2FrameHeader, error) { 407 bufp := http2fhBytes.Get().(*[]byte) 408 defer http2fhBytes.Put(bufp) 409 return http2readFrameHeader(*bufp, r) 410 } 411 412 func http2readFrameHeader(buf []byte, r io.Reader) (http2FrameHeader, error) { 413 _, err := io.ReadFull(r, buf[:http2frameHeaderLen]) 414 if err != nil { 415 return http2FrameHeader{}, err 416 } 417 return http2FrameHeader{ 418 Length: (uint32(buf[0])<<16 | uint32(buf[1])<<8 | uint32(buf[2])), 419 Type: http2FrameType(buf[3]), 420 Flags: http2Flags(buf[4]), 421 StreamID: binary.BigEndian.Uint32(buf[5:]) & (1<<31 - 1), 422 valid: true, 423 }, nil 424 } 425 426 // A Frame is the base interface implemented by all frame types. 427 // Callers will generally type-assert the specific frame type: 428 // *HeadersFrame, *SettingsFrame, *WindowUpdateFrame, etc. 429 // 430 // Frames are only valid until the next call to Framer.ReadFrame. 431 type http2Frame interface { 432 Header() http2FrameHeader 433 434 // invalidate is called by Framer.ReadFrame to make this 435 // frame's buffers as being invalid, since the subsequent 436 // frame will reuse them. 437 invalidate() 438 } 439 440 // A Framer reads and writes Frames. 441 type http2Framer struct { 442 r io.Reader 443 lastFrame http2Frame 444 445 maxReadSize uint32 446 headerBuf [http2frameHeaderLen]byte 447 448 // TODO: let getReadBuf be configurable, and use a less memory-pinning 449 // allocator in server.go to minimize memory pinned for many idle conns. 450 // Will probably also need to make frame invalidation have a hook too. 451 getReadBuf func(size uint32) []byte 452 readBuf []byte // cache for default getReadBuf 453 454 maxWriteSize uint32 // zero means unlimited; TODO: implement 455 456 w io.Writer 457 wbuf []byte 458 459 // AllowIllegalWrites permits the Framer's Write methods to 460 // write frames that do not conform to the HTTP/2 spec. This 461 // permits using the Framer to test other HTTP/2 462 // implementations' conformance to the spec. 463 // If false, the Write methods will prefer to return an error 464 // rather than comply. 465 AllowIllegalWrites bool 466 } 467 468 func (f *http2Framer) startWrite(ftype http2FrameType, flags http2Flags, streamID uint32) { 469 470 f.wbuf = append(f.wbuf[:0], 471 0, 472 0, 473 0, 474 byte(ftype), 475 byte(flags), 476 byte(streamID>>24), 477 byte(streamID>>16), 478 byte(streamID>>8), 479 byte(streamID)) 480 } 481 482 func (f *http2Framer) endWrite() error { 483 484 length := len(f.wbuf) - http2frameHeaderLen 485 if length >= (1 << 24) { 486 return http2ErrFrameTooLarge 487 } 488 _ = append(f.wbuf[:0], 489 byte(length>>16), 490 byte(length>>8), 491 byte(length)) 492 n, err := f.w.Write(f.wbuf) 493 if err == nil && n != len(f.wbuf) { 494 err = io.ErrShortWrite 495 } 496 return err 497 } 498 499 func (f *http2Framer) writeByte(v byte) { f.wbuf = append(f.wbuf, v) } 500 501 func (f *http2Framer) writeBytes(v []byte) { f.wbuf = append(f.wbuf, v...) } 502 503 func (f *http2Framer) writeUint16(v uint16) { f.wbuf = append(f.wbuf, byte(v>>8), byte(v)) } 504 505 func (f *http2Framer) writeUint32(v uint32) { 506 f.wbuf = append(f.wbuf, byte(v>>24), byte(v>>16), byte(v>>8), byte(v)) 507 } 508 509 const ( 510 http2minMaxFrameSize = 1 << 14 511 http2maxFrameSize = 1<<24 - 1 512 ) 513 514 // NewFramer returns a Framer that writes frames to w and reads them from r. 515 func http2NewFramer(w io.Writer, r io.Reader) *http2Framer { 516 fr := &http2Framer{ 517 w: w, 518 r: r, 519 } 520 fr.getReadBuf = func(size uint32) []byte { 521 if cap(fr.readBuf) >= int(size) { 522 return fr.readBuf[:size] 523 } 524 fr.readBuf = make([]byte, size) 525 return fr.readBuf 526 } 527 fr.SetMaxReadFrameSize(http2maxFrameSize) 528 return fr 529 } 530 531 // SetMaxReadFrameSize sets the maximum size of a frame 532 // that will be read by a subsequent call to ReadFrame. 533 // It is the caller's responsibility to advertise this 534 // limit with a SETTINGS frame. 535 func (fr *http2Framer) SetMaxReadFrameSize(v uint32) { 536 if v > http2maxFrameSize { 537 v = http2maxFrameSize 538 } 539 fr.maxReadSize = v 540 } 541 542 // ErrFrameTooLarge is returned from Framer.ReadFrame when the peer 543 // sends a frame that is larger than declared with SetMaxReadFrameSize. 544 var http2ErrFrameTooLarge = errors.New("http2: frame too large") 545 546 // ReadFrame reads a single frame. The returned Frame is only valid 547 // until the next call to ReadFrame. 548 // If the frame is larger than previously set with SetMaxReadFrameSize, 549 // the returned error is ErrFrameTooLarge. 550 func (fr *http2Framer) ReadFrame() (http2Frame, error) { 551 if fr.lastFrame != nil { 552 fr.lastFrame.invalidate() 553 } 554 fh, err := http2readFrameHeader(fr.headerBuf[:], fr.r) 555 if err != nil { 556 return nil, err 557 } 558 if fh.Length > fr.maxReadSize { 559 return nil, http2ErrFrameTooLarge 560 } 561 payload := fr.getReadBuf(fh.Length) 562 if _, err := io.ReadFull(fr.r, payload); err != nil { 563 return nil, err 564 } 565 f, err := http2typeFrameParser(fh.Type)(fh, payload) 566 if err != nil { 567 return nil, err 568 } 569 fr.lastFrame = f 570 return f, nil 571 } 572 573 // A DataFrame conveys arbitrary, variable-length sequences of octets 574 // associated with a stream. 575 // See http://http2.github.io/http2-spec/#rfc.section.6.1 576 type http2DataFrame struct { 577 http2FrameHeader 578 data []byte 579 } 580 581 func (f *http2DataFrame) StreamEnded() bool { 582 return f.http2FrameHeader.Flags.Has(http2FlagDataEndStream) 583 } 584 585 // Data returns the frame's data octets, not including any padding 586 // size byte or padding suffix bytes. 587 // The caller must not retain the returned memory past the next 588 // call to ReadFrame. 589 func (f *http2DataFrame) Data() []byte { 590 f.checkValid() 591 return f.data 592 } 593 594 func http2parseDataFrame(fh http2FrameHeader, payload []byte) (http2Frame, error) { 595 if fh.StreamID == 0 { 596 597 return nil, http2ConnectionError(http2ErrCodeProtocol) 598 } 599 f := &http2DataFrame{ 600 http2FrameHeader: fh, 601 } 602 var padSize byte 603 if fh.Flags.Has(http2FlagDataPadded) { 604 var err error 605 payload, padSize, err = http2readByte(payload) 606 if err != nil { 607 return nil, err 608 } 609 } 610 if int(padSize) > len(payload) { 611 612 return nil, http2ConnectionError(http2ErrCodeProtocol) 613 } 614 f.data = payload[:len(payload)-int(padSize)] 615 return f, nil 616 } 617 618 var http2errStreamID = errors.New("invalid streamid") 619 620 func http2validStreamID(streamID uint32) bool { 621 return streamID != 0 && streamID&(1<<31) == 0 622 } 623 624 // WriteData writes a DATA frame. 625 // 626 // It will perform exactly one Write to the underlying Writer. 627 // It is the caller's responsibility to not call other Write methods concurrently. 628 func (f *http2Framer) WriteData(streamID uint32, endStream bool, data []byte) error { 629 630 if !http2validStreamID(streamID) && !f.AllowIllegalWrites { 631 return http2errStreamID 632 } 633 var flags http2Flags 634 if endStream { 635 flags |= http2FlagDataEndStream 636 } 637 f.startWrite(http2FrameData, flags, streamID) 638 f.wbuf = append(f.wbuf, data...) 639 return f.endWrite() 640 } 641 642 // A SettingsFrame conveys configuration parameters that affect how 643 // endpoints communicate, such as preferences and constraints on peer 644 // behavior. 645 // 646 // See http://http2.github.io/http2-spec/#SETTINGS 647 type http2SettingsFrame struct { 648 http2FrameHeader 649 p []byte 650 } 651 652 func http2parseSettingsFrame(fh http2FrameHeader, p []byte) (http2Frame, error) { 653 if fh.Flags.Has(http2FlagSettingsAck) && fh.Length > 0 { 654 655 return nil, http2ConnectionError(http2ErrCodeFrameSize) 656 } 657 if fh.StreamID != 0 { 658 659 return nil, http2ConnectionError(http2ErrCodeProtocol) 660 } 661 if len(p)%6 != 0 { 662 663 return nil, http2ConnectionError(http2ErrCodeFrameSize) 664 } 665 f := &http2SettingsFrame{http2FrameHeader: fh, p: p} 666 if v, ok := f.Value(http2SettingInitialWindowSize); ok && v > (1<<31)-1 { 667 668 return nil, http2ConnectionError(http2ErrCodeFlowControl) 669 } 670 return f, nil 671 } 672 673 func (f *http2SettingsFrame) IsAck() bool { 674 return f.http2FrameHeader.Flags.Has(http2FlagSettingsAck) 675 } 676 677 func (f *http2SettingsFrame) Value(s http2SettingID) (v uint32, ok bool) { 678 f.checkValid() 679 buf := f.p 680 for len(buf) > 0 { 681 settingID := http2SettingID(binary.BigEndian.Uint16(buf[:2])) 682 if settingID == s { 683 return binary.BigEndian.Uint32(buf[2:6]), true 684 } 685 buf = buf[6:] 686 } 687 return 0, false 688 } 689 690 // ForeachSetting runs fn for each setting. 691 // It stops and returns the first error. 692 func (f *http2SettingsFrame) ForeachSetting(fn func(http2Setting) error) error { 693 f.checkValid() 694 buf := f.p 695 for len(buf) > 0 { 696 if err := fn(http2Setting{ 697 http2SettingID(binary.BigEndian.Uint16(buf[:2])), 698 binary.BigEndian.Uint32(buf[2:6]), 699 }); err != nil { 700 return err 701 } 702 buf = buf[6:] 703 } 704 return nil 705 } 706 707 // WriteSettings writes a SETTINGS frame with zero or more settings 708 // specified and the ACK bit not set. 709 // 710 // It will perform exactly one Write to the underlying Writer. 711 // It is the caller's responsibility to not call other Write methods concurrently. 712 func (f *http2Framer) WriteSettings(settings ...http2Setting) error { 713 f.startWrite(http2FrameSettings, 0, 0) 714 for _, s := range settings { 715 f.writeUint16(uint16(s.ID)) 716 f.writeUint32(s.Val) 717 } 718 return f.endWrite() 719 } 720 721 // WriteSettings writes an empty SETTINGS frame with the ACK bit set. 722 // 723 // It will perform exactly one Write to the underlying Writer. 724 // It is the caller's responsibility to not call other Write methods concurrently. 725 func (f *http2Framer) WriteSettingsAck() error { 726 f.startWrite(http2FrameSettings, http2FlagSettingsAck, 0) 727 return f.endWrite() 728 } 729 730 // A PingFrame is a mechanism for measuring a minimal round trip time 731 // from the sender, as well as determining whether an idle connection 732 // is still functional. 733 // See http://http2.github.io/http2-spec/#rfc.section.6.7 734 type http2PingFrame struct { 735 http2FrameHeader 736 Data [8]byte 737 } 738 739 func http2parsePingFrame(fh http2FrameHeader, payload []byte) (http2Frame, error) { 740 if len(payload) != 8 { 741 return nil, http2ConnectionError(http2ErrCodeFrameSize) 742 } 743 if fh.StreamID != 0 { 744 return nil, http2ConnectionError(http2ErrCodeProtocol) 745 } 746 f := &http2PingFrame{http2FrameHeader: fh} 747 copy(f.Data[:], payload) 748 return f, nil 749 } 750 751 func (f *http2Framer) WritePing(ack bool, data [8]byte) error { 752 var flags http2Flags 753 if ack { 754 flags = http2FlagPingAck 755 } 756 f.startWrite(http2FramePing, flags, 0) 757 f.writeBytes(data[:]) 758 return f.endWrite() 759 } 760 761 // A GoAwayFrame informs the remote peer to stop creating streams on this connection. 762 // See http://http2.github.io/http2-spec/#rfc.section.6.8 763 type http2GoAwayFrame struct { 764 http2FrameHeader 765 LastStreamID uint32 766 ErrCode http2ErrCode 767 debugData []byte 768 } 769 770 // DebugData returns any debug data in the GOAWAY frame. Its contents 771 // are not defined. 772 // The caller must not retain the returned memory past the next 773 // call to ReadFrame. 774 func (f *http2GoAwayFrame) DebugData() []byte { 775 f.checkValid() 776 return f.debugData 777 } 778 779 func http2parseGoAwayFrame(fh http2FrameHeader, p []byte) (http2Frame, error) { 780 if fh.StreamID != 0 { 781 return nil, http2ConnectionError(http2ErrCodeProtocol) 782 } 783 if len(p) < 8 { 784 return nil, http2ConnectionError(http2ErrCodeFrameSize) 785 } 786 return &http2GoAwayFrame{ 787 http2FrameHeader: fh, 788 LastStreamID: binary.BigEndian.Uint32(p[:4]) & (1<<31 - 1), 789 ErrCode: http2ErrCode(binary.BigEndian.Uint32(p[4:8])), 790 debugData: p[8:], 791 }, nil 792 } 793 794 func (f *http2Framer) WriteGoAway(maxStreamID uint32, code http2ErrCode, debugData []byte) error { 795 f.startWrite(http2FrameGoAway, 0, 0) 796 f.writeUint32(maxStreamID & (1<<31 - 1)) 797 f.writeUint32(uint32(code)) 798 f.writeBytes(debugData) 799 return f.endWrite() 800 } 801 802 // An UnknownFrame is the frame type returned when the frame type is unknown 803 // or no specific frame type parser exists. 804 type http2UnknownFrame struct { 805 http2FrameHeader 806 p []byte 807 } 808 809 // Payload returns the frame's payload (after the header). It is not 810 // valid to call this method after a subsequent call to 811 // Framer.ReadFrame, nor is it valid to retain the returned slice. 812 // The memory is owned by the Framer and is invalidated when the next 813 // frame is read. 814 func (f *http2UnknownFrame) Payload() []byte { 815 f.checkValid() 816 return f.p 817 } 818 819 func http2parseUnknownFrame(fh http2FrameHeader, p []byte) (http2Frame, error) { 820 return &http2UnknownFrame{fh, p}, nil 821 } 822 823 // A WindowUpdateFrame is used to implement flow control. 824 // See http://http2.github.io/http2-spec/#rfc.section.6.9 825 type http2WindowUpdateFrame struct { 826 http2FrameHeader 827 Increment uint32 // never read with high bit set 828 } 829 830 func http2parseWindowUpdateFrame(fh http2FrameHeader, p []byte) (http2Frame, error) { 831 if len(p) != 4 { 832 return nil, http2ConnectionError(http2ErrCodeFrameSize) 833 } 834 inc := binary.BigEndian.Uint32(p[:4]) & 0x7fffffff 835 if inc == 0 { 836 837 if fh.StreamID == 0 { 838 return nil, http2ConnectionError(http2ErrCodeProtocol) 839 } 840 return nil, http2StreamError{fh.StreamID, http2ErrCodeProtocol} 841 } 842 return &http2WindowUpdateFrame{ 843 http2FrameHeader: fh, 844 Increment: inc, 845 }, nil 846 } 847 848 // WriteWindowUpdate writes a WINDOW_UPDATE frame. 849 // The increment value must be between 1 and 2,147,483,647, inclusive. 850 // If the Stream ID is zero, the window update applies to the 851 // connection as a whole. 852 func (f *http2Framer) WriteWindowUpdate(streamID, incr uint32) error { 853 854 if (incr < 1 || incr > 2147483647) && !f.AllowIllegalWrites { 855 return errors.New("illegal window increment value") 856 } 857 f.startWrite(http2FrameWindowUpdate, 0, streamID) 858 f.writeUint32(incr) 859 return f.endWrite() 860 } 861 862 // A HeadersFrame is used to open a stream and additionally carries a 863 // header block fragment. 864 type http2HeadersFrame struct { 865 http2FrameHeader 866 867 // Priority is set if FlagHeadersPriority is set in the FrameHeader. 868 Priority http2PriorityParam 869 870 headerFragBuf []byte // not owned 871 } 872 873 func (f *http2HeadersFrame) HeaderBlockFragment() []byte { 874 f.checkValid() 875 return f.headerFragBuf 876 } 877 878 func (f *http2HeadersFrame) HeadersEnded() bool { 879 return f.http2FrameHeader.Flags.Has(http2FlagHeadersEndHeaders) 880 } 881 882 func (f *http2HeadersFrame) StreamEnded() bool { 883 return f.http2FrameHeader.Flags.Has(http2FlagHeadersEndStream) 884 } 885 886 func (f *http2HeadersFrame) HasPriority() bool { 887 return f.http2FrameHeader.Flags.Has(http2FlagHeadersPriority) 888 } 889 890 func http2parseHeadersFrame(fh http2FrameHeader, p []byte) (_ http2Frame, err error) { 891 hf := &http2HeadersFrame{ 892 http2FrameHeader: fh, 893 } 894 if fh.StreamID == 0 { 895 896 return nil, http2ConnectionError(http2ErrCodeProtocol) 897 } 898 var padLength uint8 899 if fh.Flags.Has(http2FlagHeadersPadded) { 900 if p, padLength, err = http2readByte(p); err != nil { 901 return 902 } 903 } 904 if fh.Flags.Has(http2FlagHeadersPriority) { 905 var v uint32 906 p, v, err = http2readUint32(p) 907 if err != nil { 908 return nil, err 909 } 910 hf.Priority.StreamDep = v & 0x7fffffff 911 hf.Priority.Exclusive = (v != hf.Priority.StreamDep) 912 p, hf.Priority.Weight, err = http2readByte(p) 913 if err != nil { 914 return nil, err 915 } 916 } 917 if len(p)-int(padLength) <= 0 { 918 return nil, http2StreamError{fh.StreamID, http2ErrCodeProtocol} 919 } 920 hf.headerFragBuf = p[:len(p)-int(padLength)] 921 return hf, nil 922 } 923 924 // HeadersFrameParam are the parameters for writing a HEADERS frame. 925 type http2HeadersFrameParam struct { 926 // StreamID is the required Stream ID to initiate. 927 StreamID uint32 928 // BlockFragment is part (or all) of a Header Block. 929 BlockFragment []byte 930 931 // EndStream indicates that the header block is the last that 932 // the endpoint will send for the identified stream. Setting 933 // this flag causes the stream to enter one of "half closed" 934 // states. 935 EndStream bool 936 937 // EndHeaders indicates that this frame contains an entire 938 // header block and is not followed by any 939 // CONTINUATION frames. 940 EndHeaders bool 941 942 // PadLength is the optional number of bytes of zeros to add 943 // to this frame. 944 PadLength uint8 945 946 // Priority, if non-zero, includes stream priority information 947 // in the HEADER frame. 948 Priority http2PriorityParam 949 } 950 951 // WriteHeaders writes a single HEADERS frame. 952 // 953 // This is a low-level header writing method. Encoding headers and 954 // splitting them into any necessary CONTINUATION frames is handled 955 // elsewhere. 956 // 957 // It will perform exactly one Write to the underlying Writer. 958 // It is the caller's responsibility to not call other Write methods concurrently. 959 func (f *http2Framer) WriteHeaders(p http2HeadersFrameParam) error { 960 if !http2validStreamID(p.StreamID) && !f.AllowIllegalWrites { 961 return http2errStreamID 962 } 963 var flags http2Flags 964 if p.PadLength != 0 { 965 flags |= http2FlagHeadersPadded 966 } 967 if p.EndStream { 968 flags |= http2FlagHeadersEndStream 969 } 970 if p.EndHeaders { 971 flags |= http2FlagHeadersEndHeaders 972 } 973 if !p.Priority.IsZero() { 974 flags |= http2FlagHeadersPriority 975 } 976 f.startWrite(http2FrameHeaders, flags, p.StreamID) 977 if p.PadLength != 0 { 978 f.writeByte(p.PadLength) 979 } 980 if !p.Priority.IsZero() { 981 v := p.Priority.StreamDep 982 if !http2validStreamID(v) && !f.AllowIllegalWrites { 983 return errors.New("invalid dependent stream id") 984 } 985 if p.Priority.Exclusive { 986 v |= 1 << 31 987 } 988 f.writeUint32(v) 989 f.writeByte(p.Priority.Weight) 990 } 991 f.wbuf = append(f.wbuf, p.BlockFragment...) 992 f.wbuf = append(f.wbuf, http2padZeros[:p.PadLength]...) 993 return f.endWrite() 994 } 995 996 // A PriorityFrame specifies the sender-advised priority of a stream. 997 // See http://http2.github.io/http2-spec/#rfc.section.6.3 998 type http2PriorityFrame struct { 999 http2FrameHeader 1000 http2PriorityParam 1001 } 1002 1003 // PriorityParam are the stream prioritzation parameters. 1004 type http2PriorityParam struct { 1005 // StreamDep is a 31-bit stream identifier for the 1006 // stream that this stream depends on. Zero means no 1007 // dependency. 1008 StreamDep uint32 1009 1010 // Exclusive is whether the dependency is exclusive. 1011 Exclusive bool 1012 1013 // Weight is the stream's zero-indexed weight. It should be 1014 // set together with StreamDep, or neither should be set. Per 1015 // the spec, "Add one to the value to obtain a weight between 1016 // 1 and 256." 1017 Weight uint8 1018 } 1019 1020 func (p http2PriorityParam) IsZero() bool { 1021 return p == http2PriorityParam{} 1022 } 1023 1024 func http2parsePriorityFrame(fh http2FrameHeader, payload []byte) (http2Frame, error) { 1025 if fh.StreamID == 0 { 1026 return nil, http2ConnectionError(http2ErrCodeProtocol) 1027 } 1028 if len(payload) != 5 { 1029 return nil, http2ConnectionError(http2ErrCodeFrameSize) 1030 } 1031 v := binary.BigEndian.Uint32(payload[:4]) 1032 streamID := v & 0x7fffffff 1033 return &http2PriorityFrame{ 1034 http2FrameHeader: fh, 1035 http2PriorityParam: http2PriorityParam{ 1036 Weight: payload[4], 1037 StreamDep: streamID, 1038 Exclusive: streamID != v, 1039 }, 1040 }, nil 1041 } 1042 1043 // WritePriority writes a PRIORITY frame. 1044 // 1045 // It will perform exactly one Write to the underlying Writer. 1046 // It is the caller's responsibility to not call other Write methods concurrently. 1047 func (f *http2Framer) WritePriority(streamID uint32, p http2PriorityParam) error { 1048 if !http2validStreamID(streamID) && !f.AllowIllegalWrites { 1049 return http2errStreamID 1050 } 1051 f.startWrite(http2FramePriority, 0, streamID) 1052 v := p.StreamDep 1053 if p.Exclusive { 1054 v |= 1 << 31 1055 } 1056 f.writeUint32(v) 1057 f.writeByte(p.Weight) 1058 return f.endWrite() 1059 } 1060 1061 // A RSTStreamFrame allows for abnormal termination of a stream. 1062 // See http://http2.github.io/http2-spec/#rfc.section.6.4 1063 type http2RSTStreamFrame struct { 1064 http2FrameHeader 1065 ErrCode http2ErrCode 1066 } 1067 1068 func http2parseRSTStreamFrame(fh http2FrameHeader, p []byte) (http2Frame, error) { 1069 if len(p) != 4 { 1070 return nil, http2ConnectionError(http2ErrCodeFrameSize) 1071 } 1072 if fh.StreamID == 0 { 1073 return nil, http2ConnectionError(http2ErrCodeProtocol) 1074 } 1075 return &http2RSTStreamFrame{fh, http2ErrCode(binary.BigEndian.Uint32(p[:4]))}, nil 1076 } 1077 1078 // WriteRSTStream writes a RST_STREAM frame. 1079 // 1080 // It will perform exactly one Write to the underlying Writer. 1081 // It is the caller's responsibility to not call other Write methods concurrently. 1082 func (f *http2Framer) WriteRSTStream(streamID uint32, code http2ErrCode) error { 1083 if !http2validStreamID(streamID) && !f.AllowIllegalWrites { 1084 return http2errStreamID 1085 } 1086 f.startWrite(http2FrameRSTStream, 0, streamID) 1087 f.writeUint32(uint32(code)) 1088 return f.endWrite() 1089 } 1090 1091 // A ContinuationFrame is used to continue a sequence of header block fragments. 1092 // See http://http2.github.io/http2-spec/#rfc.section.6.10 1093 type http2ContinuationFrame struct { 1094 http2FrameHeader 1095 headerFragBuf []byte 1096 } 1097 1098 func http2parseContinuationFrame(fh http2FrameHeader, p []byte) (http2Frame, error) { 1099 return &http2ContinuationFrame{fh, p}, nil 1100 } 1101 1102 func (f *http2ContinuationFrame) StreamEnded() bool { 1103 return f.http2FrameHeader.Flags.Has(http2FlagDataEndStream) 1104 } 1105 1106 func (f *http2ContinuationFrame) HeaderBlockFragment() []byte { 1107 f.checkValid() 1108 return f.headerFragBuf 1109 } 1110 1111 func (f *http2ContinuationFrame) HeadersEnded() bool { 1112 return f.http2FrameHeader.Flags.Has(http2FlagContinuationEndHeaders) 1113 } 1114 1115 // WriteContinuation writes a CONTINUATION frame. 1116 // 1117 // It will perform exactly one Write to the underlying Writer. 1118 // It is the caller's responsibility to not call other Write methods concurrently. 1119 func (f *http2Framer) WriteContinuation(streamID uint32, endHeaders bool, headerBlockFragment []byte) error { 1120 if !http2validStreamID(streamID) && !f.AllowIllegalWrites { 1121 return http2errStreamID 1122 } 1123 var flags http2Flags 1124 if endHeaders { 1125 flags |= http2FlagContinuationEndHeaders 1126 } 1127 f.startWrite(http2FrameContinuation, flags, streamID) 1128 f.wbuf = append(f.wbuf, headerBlockFragment...) 1129 return f.endWrite() 1130 } 1131 1132 // A PushPromiseFrame is used to initiate a server stream. 1133 // See http://http2.github.io/http2-spec/#rfc.section.6.6 1134 type http2PushPromiseFrame struct { 1135 http2FrameHeader 1136 PromiseID uint32 1137 headerFragBuf []byte // not owned 1138 } 1139 1140 func (f *http2PushPromiseFrame) HeaderBlockFragment() []byte { 1141 f.checkValid() 1142 return f.headerFragBuf 1143 } 1144 1145 func (f *http2PushPromiseFrame) HeadersEnded() bool { 1146 return f.http2FrameHeader.Flags.Has(http2FlagPushPromiseEndHeaders) 1147 } 1148 1149 func http2parsePushPromise(fh http2FrameHeader, p []byte) (_ http2Frame, err error) { 1150 pp := &http2PushPromiseFrame{ 1151 http2FrameHeader: fh, 1152 } 1153 if pp.StreamID == 0 { 1154 1155 return nil, http2ConnectionError(http2ErrCodeProtocol) 1156 } 1157 // The PUSH_PROMISE frame includes optional padding. 1158 // Padding fields and flags are identical to those defined for DATA frames 1159 var padLength uint8 1160 if fh.Flags.Has(http2FlagPushPromisePadded) { 1161 if p, padLength, err = http2readByte(p); err != nil { 1162 return 1163 } 1164 } 1165 1166 p, pp.PromiseID, err = http2readUint32(p) 1167 if err != nil { 1168 return 1169 } 1170 pp.PromiseID = pp.PromiseID & (1<<31 - 1) 1171 1172 if int(padLength) > len(p) { 1173 1174 return nil, http2ConnectionError(http2ErrCodeProtocol) 1175 } 1176 pp.headerFragBuf = p[:len(p)-int(padLength)] 1177 return pp, nil 1178 } 1179 1180 // PushPromiseParam are the parameters for writing a PUSH_PROMISE frame. 1181 type http2PushPromiseParam struct { 1182 // StreamID is the required Stream ID to initiate. 1183 StreamID uint32 1184 1185 // PromiseID is the required Stream ID which this 1186 // Push Promises 1187 PromiseID uint32 1188 1189 // BlockFragment is part (or all) of a Header Block. 1190 BlockFragment []byte 1191 1192 // EndHeaders indicates that this frame contains an entire 1193 // header block and is not followed by any 1194 // CONTINUATION frames. 1195 EndHeaders bool 1196 1197 // PadLength is the optional number of bytes of zeros to add 1198 // to this frame. 1199 PadLength uint8 1200 } 1201 1202 // WritePushPromise writes a single PushPromise Frame. 1203 // 1204 // As with Header Frames, This is the low level call for writing 1205 // individual frames. Continuation frames are handled elsewhere. 1206 // 1207 // It will perform exactly one Write to the underlying Writer. 1208 // It is the caller's responsibility to not call other Write methods concurrently. 1209 func (f *http2Framer) WritePushPromise(p http2PushPromiseParam) error { 1210 if !http2validStreamID(p.StreamID) && !f.AllowIllegalWrites { 1211 return http2errStreamID 1212 } 1213 var flags http2Flags 1214 if p.PadLength != 0 { 1215 flags |= http2FlagPushPromisePadded 1216 } 1217 if p.EndHeaders { 1218 flags |= http2FlagPushPromiseEndHeaders 1219 } 1220 f.startWrite(http2FramePushPromise, flags, p.StreamID) 1221 if p.PadLength != 0 { 1222 f.writeByte(p.PadLength) 1223 } 1224 if !http2validStreamID(p.PromiseID) && !f.AllowIllegalWrites { 1225 return http2errStreamID 1226 } 1227 f.writeUint32(p.PromiseID) 1228 f.wbuf = append(f.wbuf, p.BlockFragment...) 1229 f.wbuf = append(f.wbuf, http2padZeros[:p.PadLength]...) 1230 return f.endWrite() 1231 } 1232 1233 // WriteRawFrame writes a raw frame. This can be used to write 1234 // extension frames unknown to this package. 1235 func (f *http2Framer) WriteRawFrame(t http2FrameType, flags http2Flags, streamID uint32, payload []byte) error { 1236 f.startWrite(t, flags, streamID) 1237 f.writeBytes(payload) 1238 return f.endWrite() 1239 } 1240 1241 func http2readByte(p []byte) (remain []byte, b byte, err error) { 1242 if len(p) == 0 { 1243 return nil, 0, io.ErrUnexpectedEOF 1244 } 1245 return p[1:], p[0], nil 1246 } 1247 1248 func http2readUint32(p []byte) (remain []byte, v uint32, err error) { 1249 if len(p) < 4 { 1250 return nil, 0, io.ErrUnexpectedEOF 1251 } 1252 return p[4:], binary.BigEndian.Uint32(p[:4]), nil 1253 } 1254 1255 type http2streamEnder interface { 1256 StreamEnded() bool 1257 } 1258 1259 type http2headersEnder interface { 1260 HeadersEnded() bool 1261 } 1262 1263 var http2DebugGoroutines = os.Getenv("DEBUG_HTTP2_GOROUTINES") == "1" 1264 1265 type http2goroutineLock uint64 1266 1267 func http2newGoroutineLock() http2goroutineLock { 1268 if !http2DebugGoroutines { 1269 return 0 1270 } 1271 return http2goroutineLock(http2curGoroutineID()) 1272 } 1273 1274 func (g http2goroutineLock) check() { 1275 if !http2DebugGoroutines { 1276 return 1277 } 1278 if http2curGoroutineID() != uint64(g) { 1279 panic("running on the wrong goroutine") 1280 } 1281 } 1282 1283 func (g http2goroutineLock) checkNotOn() { 1284 if !http2DebugGoroutines { 1285 return 1286 } 1287 if http2curGoroutineID() == uint64(g) { 1288 panic("running on the wrong goroutine") 1289 } 1290 } 1291 1292 var http2goroutineSpace = []byte("goroutine ") 1293 1294 func http2curGoroutineID() uint64 { 1295 bp := http2littleBuf.Get().(*[]byte) 1296 defer http2littleBuf.Put(bp) 1297 b := *bp 1298 b = b[:runtime.Stack(b, false)] 1299 1300 b = bytes.TrimPrefix(b, http2goroutineSpace) 1301 i := bytes.IndexByte(b, ' ') 1302 if i < 0 { 1303 panic(fmt.Sprintf("No space found in %q", b)) 1304 } 1305 b = b[:i] 1306 n, err := http2parseUintBytes(b, 10, 64) 1307 if err != nil { 1308 panic(fmt.Sprintf("Failed to parse goroutine ID out of %q: %v", b, err)) 1309 } 1310 return n 1311 } 1312 1313 var http2littleBuf = sync.Pool{ 1314 New: func() interface{} { 1315 buf := make([]byte, 64) 1316 return &buf 1317 }, 1318 } 1319 1320 // parseUintBytes is like strconv.ParseUint, but using a []byte. 1321 func http2parseUintBytes(s []byte, base int, bitSize int) (n uint64, err error) { 1322 var cutoff, maxVal uint64 1323 1324 if bitSize == 0 { 1325 bitSize = int(strconv.IntSize) 1326 } 1327 1328 s0 := s 1329 switch { 1330 case len(s) < 1: 1331 err = strconv.ErrSyntax 1332 goto Error 1333 1334 case 2 <= base && base <= 36: 1335 1336 case base == 0: 1337 1338 switch { 1339 case s[0] == '0' && len(s) > 1 && (s[1] == 'x' || s[1] == 'X'): 1340 base = 16 1341 s = s[2:] 1342 if len(s) < 1 { 1343 err = strconv.ErrSyntax 1344 goto Error 1345 } 1346 case s[0] == '0': 1347 base = 8 1348 default: 1349 base = 10 1350 } 1351 1352 default: 1353 err = errors.New("invalid base " + strconv.Itoa(base)) 1354 goto Error 1355 } 1356 1357 n = 0 1358 cutoff = http2cutoff64(base) 1359 maxVal = 1<<uint(bitSize) - 1 1360 1361 for i := 0; i < len(s); i++ { 1362 var v byte 1363 d := s[i] 1364 switch { 1365 case '0' <= d && d <= '9': 1366 v = d - '0' 1367 case 'a' <= d && d <= 'z': 1368 v = d - 'a' + 10 1369 case 'A' <= d && d <= 'Z': 1370 v = d - 'A' + 10 1371 default: 1372 n = 0 1373 err = strconv.ErrSyntax 1374 goto Error 1375 } 1376 if int(v) >= base { 1377 n = 0 1378 err = strconv.ErrSyntax 1379 goto Error 1380 } 1381 1382 if n >= cutoff { 1383 1384 n = 1<<64 - 1 1385 err = strconv.ErrRange 1386 goto Error 1387 } 1388 n *= uint64(base) 1389 1390 n1 := n + uint64(v) 1391 if n1 < n || n1 > maxVal { 1392 1393 n = 1<<64 - 1 1394 err = strconv.ErrRange 1395 goto Error 1396 } 1397 n = n1 1398 } 1399 1400 return n, nil 1401 1402 Error: 1403 return n, &strconv.NumError{Func: "ParseUint", Num: string(s0), Err: err} 1404 } 1405 1406 // Return the first number n such that n*base >= 1<<64. 1407 func http2cutoff64(base int) uint64 { 1408 if base < 2 { 1409 return 0 1410 } 1411 return (1<<64-1)/uint64(base) + 1 1412 } 1413 1414 var ( 1415 http2commonLowerHeader = map[string]string{} // Go-Canonical-Case -> lower-case 1416 http2commonCanonHeader = map[string]string{} // lower-case -> Go-Canonical-Case 1417 ) 1418 1419 func init() { 1420 for _, v := range []string{ 1421 "accept", 1422 "accept-charset", 1423 "accept-encoding", 1424 "accept-language", 1425 "accept-ranges", 1426 "age", 1427 "access-control-allow-origin", 1428 "allow", 1429 "authorization", 1430 "cache-control", 1431 "content-disposition", 1432 "content-encoding", 1433 "content-language", 1434 "content-length", 1435 "content-location", 1436 "content-range", 1437 "content-type", 1438 "cookie", 1439 "date", 1440 "etag", 1441 "expect", 1442 "expires", 1443 "from", 1444 "host", 1445 "if-match", 1446 "if-modified-since", 1447 "if-none-match", 1448 "if-unmodified-since", 1449 "last-modified", 1450 "link", 1451 "location", 1452 "max-forwards", 1453 "proxy-authenticate", 1454 "proxy-authorization", 1455 "range", 1456 "referer", 1457 "refresh", 1458 "retry-after", 1459 "server", 1460 "set-cookie", 1461 "strict-transport-security", 1462 "transfer-encoding", 1463 "user-agent", 1464 "vary", 1465 "via", 1466 "www-authenticate", 1467 } { 1468 chk := CanonicalHeaderKey(v) 1469 http2commonLowerHeader[chk] = v 1470 http2commonCanonHeader[v] = chk 1471 } 1472 } 1473 1474 func http2lowerHeader(v string) string { 1475 if s, ok := http2commonLowerHeader[v]; ok { 1476 return s 1477 } 1478 return strings.ToLower(v) 1479 } 1480 1481 var http2VerboseLogs = false 1482 1483 const ( 1484 // ClientPreface is the string that must be sent by new 1485 // connections from clients. 1486 http2ClientPreface = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" 1487 1488 // SETTINGS_MAX_FRAME_SIZE default 1489 // http://http2.github.io/http2-spec/#rfc.section.6.5.2 1490 http2initialMaxFrameSize = 16384 1491 1492 // NextProtoTLS is the NPN/ALPN protocol negotiated during 1493 // HTTP/2's TLS setup. 1494 http2NextProtoTLS = "h2" 1495 1496 // http://http2.github.io/http2-spec/#SettingValues 1497 http2initialHeaderTableSize = 4096 1498 1499 http2initialWindowSize = 65535 // 6.9.2 Initial Flow Control Window Size 1500 1501 http2defaultMaxReadFrameSize = 1 << 20 1502 ) 1503 1504 var ( 1505 http2clientPreface = []byte(http2ClientPreface) 1506 ) 1507 1508 type http2streamState int 1509 1510 const ( 1511 http2stateIdle http2streamState = iota 1512 http2stateOpen 1513 http2stateHalfClosedLocal 1514 http2stateHalfClosedRemote 1515 http2stateResvLocal 1516 http2stateResvRemote 1517 http2stateClosed 1518 ) 1519 1520 var http2stateName = [...]string{ 1521 http2stateIdle: "Idle", 1522 http2stateOpen: "Open", 1523 http2stateHalfClosedLocal: "HalfClosedLocal", 1524 http2stateHalfClosedRemote: "HalfClosedRemote", 1525 http2stateResvLocal: "ResvLocal", 1526 http2stateResvRemote: "ResvRemote", 1527 http2stateClosed: "Closed", 1528 } 1529 1530 func (st http2streamState) String() string { 1531 return http2stateName[st] 1532 } 1533 1534 // Setting is a setting parameter: which setting it is, and its value. 1535 type http2Setting struct { 1536 // ID is which setting is being set. 1537 // See http://http2.github.io/http2-spec/#SettingValues 1538 ID http2SettingID 1539 1540 // Val is the value. 1541 Val uint32 1542 } 1543 1544 func (s http2Setting) String() string { 1545 return fmt.Sprintf("[%v = %d]", s.ID, s.Val) 1546 } 1547 1548 // Valid reports whether the setting is valid. 1549 func (s http2Setting) Valid() error { 1550 1551 switch s.ID { 1552 case http2SettingEnablePush: 1553 if s.Val != 1 && s.Val != 0 { 1554 return http2ConnectionError(http2ErrCodeProtocol) 1555 } 1556 case http2SettingInitialWindowSize: 1557 if s.Val > 1<<31-1 { 1558 return http2ConnectionError(http2ErrCodeFlowControl) 1559 } 1560 case http2SettingMaxFrameSize: 1561 if s.Val < 16384 || s.Val > 1<<24-1 { 1562 return http2ConnectionError(http2ErrCodeProtocol) 1563 } 1564 } 1565 return nil 1566 } 1567 1568 // A SettingID is an HTTP/2 setting as defined in 1569 // http://http2.github.io/http2-spec/#iana-settings 1570 type http2SettingID uint16 1571 1572 const ( 1573 http2SettingHeaderTableSize http2SettingID = 0x1 1574 http2SettingEnablePush http2SettingID = 0x2 1575 http2SettingMaxConcurrentStreams http2SettingID = 0x3 1576 http2SettingInitialWindowSize http2SettingID = 0x4 1577 http2SettingMaxFrameSize http2SettingID = 0x5 1578 http2SettingMaxHeaderListSize http2SettingID = 0x6 1579 ) 1580 1581 var http2settingName = map[http2SettingID]string{ 1582 http2SettingHeaderTableSize: "HEADER_TABLE_SIZE", 1583 http2SettingEnablePush: "ENABLE_PUSH", 1584 http2SettingMaxConcurrentStreams: "MAX_CONCURRENT_STREAMS", 1585 http2SettingInitialWindowSize: "INITIAL_WINDOW_SIZE", 1586 http2SettingMaxFrameSize: "MAX_FRAME_SIZE", 1587 http2SettingMaxHeaderListSize: "MAX_HEADER_LIST_SIZE", 1588 } 1589 1590 func (s http2SettingID) String() string { 1591 if v, ok := http2settingName[s]; ok { 1592 return v 1593 } 1594 return fmt.Sprintf("UNKNOWN_SETTING_%d", uint16(s)) 1595 } 1596 1597 func http2validHeader(v string) bool { 1598 if len(v) == 0 { 1599 return false 1600 } 1601 for _, r := range v { 1602 1603 if r >= 127 || ('A' <= r && r <= 'Z') { 1604 return false 1605 } 1606 } 1607 return true 1608 } 1609 1610 var http2httpCodeStringCommon = map[int]string{} // n -> strconv.Itoa(n) 1611 1612 func init() { 1613 for i := 100; i <= 999; i++ { 1614 if v := StatusText(i); v != "" { 1615 http2httpCodeStringCommon[i] = strconv.Itoa(i) 1616 } 1617 } 1618 } 1619 1620 func http2httpCodeString(code int) string { 1621 if s, ok := http2httpCodeStringCommon[code]; ok { 1622 return s 1623 } 1624 return strconv.Itoa(code) 1625 } 1626 1627 // from pkg io 1628 type http2stringWriter interface { 1629 WriteString(s string) (n int, err error) 1630 } 1631 1632 // A gate lets two goroutines coordinate their activities. 1633 type http2gate chan struct{} 1634 1635 func (g http2gate) Done() { g <- struct{}{} } 1636 1637 func (g http2gate) Wait() { <-g } 1638 1639 // A closeWaiter is like a sync.WaitGroup but only goes 1 to 0 (open to closed). 1640 type http2closeWaiter chan struct{} 1641 1642 // Init makes a closeWaiter usable. 1643 // It exists because so a closeWaiter value can be placed inside a 1644 // larger struct and have the Mutex and Cond's memory in the same 1645 // allocation. 1646 func (cw *http2closeWaiter) Init() { 1647 *cw = make(chan struct{}) 1648 } 1649 1650 // Close marks the closeWaiter as closed and unblocks any waiters. 1651 func (cw http2closeWaiter) Close() { 1652 close(cw) 1653 } 1654 1655 // Wait waits for the closeWaiter to become closed. 1656 func (cw http2closeWaiter) Wait() { 1657 <-cw 1658 } 1659 1660 // bufferedWriter is a buffered writer that writes to w. 1661 // Its buffered writer is lazily allocated as needed, to minimize 1662 // idle memory usage with many connections. 1663 type http2bufferedWriter struct { 1664 w io.Writer // immutable 1665 bw *bufio.Writer // non-nil when data is buffered 1666 } 1667 1668 func http2newBufferedWriter(w io.Writer) *http2bufferedWriter { 1669 return &http2bufferedWriter{w: w} 1670 } 1671 1672 var http2bufWriterPool = sync.Pool{ 1673 New: func() interface{} { 1674 1675 return bufio.NewWriterSize(nil, 4<<10) 1676 }, 1677 } 1678 1679 func (w *http2bufferedWriter) Write(p []byte) (n int, err error) { 1680 if w.bw == nil { 1681 bw := http2bufWriterPool.Get().(*bufio.Writer) 1682 bw.Reset(w.w) 1683 w.bw = bw 1684 } 1685 return w.bw.Write(p) 1686 } 1687 1688 func (w *http2bufferedWriter) Flush() error { 1689 bw := w.bw 1690 if bw == nil { 1691 return nil 1692 } 1693 err := bw.Flush() 1694 bw.Reset(nil) 1695 http2bufWriterPool.Put(bw) 1696 w.bw = nil 1697 return err 1698 } 1699 1700 func http2mustUint31(v int32) uint32 { 1701 if v < 0 || v > 2147483647 { 1702 panic("out of range") 1703 } 1704 return uint32(v) 1705 } 1706 1707 // pipe is a goroutine-safe io.Reader/io.Writer pair. It's like 1708 // io.Pipe except there are no PipeReader/PipeWriter halves, and the 1709 // underlying buffer is an interface. (io.Pipe is always unbuffered) 1710 type http2pipe struct { 1711 mu sync.Mutex 1712 c sync.Cond // c.L must point to 1713 b http2pipeBuffer 1714 err error // read error once empty. non-nil means closed. 1715 } 1716 1717 type http2pipeBuffer interface { 1718 Len() int 1719 io.Writer 1720 io.Reader 1721 } 1722 1723 // Read waits until data is available and copies bytes 1724 // from the buffer into p. 1725 func (p *http2pipe) Read(d []byte) (n int, err error) { 1726 p.mu.Lock() 1727 defer p.mu.Unlock() 1728 if p.c.L == nil { 1729 p.c.L = &p.mu 1730 } 1731 for { 1732 if p.b.Len() > 0 { 1733 return p.b.Read(d) 1734 } 1735 if p.err != nil { 1736 return 0, p.err 1737 } 1738 p.c.Wait() 1739 } 1740 } 1741 1742 var http2errClosedPipeWrite = errors.New("write on closed buffer") 1743 1744 // Write copies bytes from p into the buffer and wakes a reader. 1745 // It is an error to write more data than the buffer can hold. 1746 func (p *http2pipe) Write(d []byte) (n int, err error) { 1747 p.mu.Lock() 1748 defer p.mu.Unlock() 1749 if p.c.L == nil { 1750 p.c.L = &p.mu 1751 } 1752 defer p.c.Signal() 1753 if p.err != nil { 1754 return 0, http2errClosedPipeWrite 1755 } 1756 return p.b.Write(d) 1757 } 1758 1759 // CloseWithError causes Reads to wake up and return the 1760 // provided err after all data has been read. 1761 // 1762 // The error must be non-nil. 1763 func (p *http2pipe) CloseWithError(err error) { 1764 if err == nil { 1765 panic("CloseWithError must be non-nil") 1766 } 1767 p.mu.Lock() 1768 defer p.mu.Unlock() 1769 if p.c.L == nil { 1770 p.c.L = &p.mu 1771 } 1772 defer p.c.Signal() 1773 if p.err == nil { 1774 p.err = err 1775 } 1776 } 1777 1778 // Err returns the error (if any) first set with CloseWithError. 1779 // This is the error which will be returned after the reader is exhausted. 1780 func (p *http2pipe) Err() error { 1781 p.mu.Lock() 1782 defer p.mu.Unlock() 1783 return p.err 1784 } 1785 1786 const ( 1787 http2prefaceTimeout = 10 * time.Second 1788 http2firstSettingsTimeout = 2 * time.Second // should be in-flight with preface anyway 1789 http2handlerChunkWriteSize = 4 << 10 1790 http2defaultMaxStreams = 250 // TODO: make this 100 as the GFE seems to? 1791 ) 1792 1793 var ( 1794 http2errClientDisconnected = errors.New("client disconnected") 1795 http2errClosedBody = errors.New("body closed by handler") 1796 http2errHandlerComplete = errors.New("http2: request body closed due to handler exiting") 1797 http2errStreamClosed = errors.New("http2: stream closed") 1798 ) 1799 1800 var http2responseWriterStatePool = sync.Pool{ 1801 New: func() interface{} { 1802 rws := &http2responseWriterState{} 1803 rws.bw = bufio.NewWriterSize(http2chunkWriter{rws}, http2handlerChunkWriteSize) 1804 return rws 1805 }, 1806 } 1807 1808 // Test hooks. 1809 var ( 1810 http2testHookOnConn func() 1811 http2testHookGetServerConn func(*http2serverConn) 1812 http2testHookOnPanicMu *sync.Mutex // nil except in tests 1813 http2testHookOnPanic func(sc *http2serverConn, panicVal interface{}) (rePanic bool) 1814 ) 1815 1816 // Server is an HTTP/2 server. 1817 type http2Server struct { 1818 // MaxHandlers limits the number of http.Handler ServeHTTP goroutines 1819 // which may run at a time over all connections. 1820 // Negative or zero no limit. 1821 // TODO: implement 1822 MaxHandlers int 1823 1824 // MaxConcurrentStreams optionally specifies the number of 1825 // concurrent streams that each client may have open at a 1826 // time. This is unrelated to the number of http.Handler goroutines 1827 // which may be active globally, which is MaxHandlers. 1828 // If zero, MaxConcurrentStreams defaults to at least 100, per 1829 // the HTTP/2 spec's recommendations. 1830 MaxConcurrentStreams uint32 1831 1832 // MaxReadFrameSize optionally specifies the largest frame 1833 // this server is willing to read. A valid value is between 1834 // 16k and 16M, inclusive. If zero or otherwise invalid, a 1835 // default value is used. 1836 MaxReadFrameSize uint32 1837 1838 // PermitProhibitedCipherSuites, if true, permits the use of 1839 // cipher suites prohibited by the HTTP/2 spec. 1840 PermitProhibitedCipherSuites bool 1841 } 1842 1843 func (s *http2Server) maxReadFrameSize() uint32 { 1844 if v := s.MaxReadFrameSize; v >= http2minMaxFrameSize && v <= http2maxFrameSize { 1845 return v 1846 } 1847 return http2defaultMaxReadFrameSize 1848 } 1849 1850 func (s *http2Server) maxConcurrentStreams() uint32 { 1851 if v := s.MaxConcurrentStreams; v > 0 { 1852 return v 1853 } 1854 return http2defaultMaxStreams 1855 } 1856 1857 // ConfigureServer adds HTTP/2 support to a net/http Server. 1858 // 1859 // The configuration conf may be nil. 1860 // 1861 // ConfigureServer must be called before s begins serving. 1862 func http2ConfigureServer(s *Server, conf *http2Server) error { 1863 if conf == nil { 1864 conf = new(http2Server) 1865 } 1866 1867 if s.TLSConfig == nil { 1868 s.TLSConfig = new(tls.Config) 1869 } else if s.TLSConfig.CipherSuites != nil { 1870 // If they already provided a CipherSuite list, return 1871 // an error if it has a bad order or is missing 1872 // ECDHE_RSA_WITH_AES_128_GCM_SHA256. 1873 const requiredCipher = tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 1874 haveRequired := false 1875 sawBad := false 1876 for i, cs := range s.TLSConfig.CipherSuites { 1877 if cs == requiredCipher { 1878 haveRequired = true 1879 } 1880 if http2isBadCipher(cs) { 1881 sawBad = true 1882 } else if sawBad { 1883 return fmt.Errorf("http2: TLSConfig.CipherSuites index %d contains an HTTP/2-approved cipher suite (%#04x), but it comes after unapproved cipher suites. With this configuration, clients that don't support previous, approved cipher suites may be given an unapproved one and reject the connection.", i, cs) 1884 } 1885 } 1886 if !haveRequired { 1887 return fmt.Errorf("http2: TLSConfig.CipherSuites is missing HTTP/2-required TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256") 1888 } 1889 } 1890 1891 s.TLSConfig.PreferServerCipherSuites = true 1892 1893 haveNPN := false 1894 for _, p := range s.TLSConfig.NextProtos { 1895 if p == http2NextProtoTLS { 1896 haveNPN = true 1897 break 1898 } 1899 } 1900 if !haveNPN { 1901 s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, http2NextProtoTLS) 1902 } 1903 1904 s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, "h2-14") 1905 1906 if s.TLSNextProto == nil { 1907 s.TLSNextProto = map[string]func(*Server, *tls.Conn, Handler){} 1908 } 1909 protoHandler := func(hs *Server, c *tls.Conn, h Handler) { 1910 if http2testHookOnConn != nil { 1911 http2testHookOnConn() 1912 } 1913 conf.handleConn(hs, c, h) 1914 } 1915 s.TLSNextProto[http2NextProtoTLS] = protoHandler 1916 s.TLSNextProto["h2-14"] = protoHandler 1917 return nil 1918 } 1919 1920 func (srv *http2Server) handleConn(hs *Server, c net.Conn, h Handler) { 1921 sc := &http2serverConn{ 1922 srv: srv, 1923 hs: hs, 1924 conn: c, 1925 remoteAddrStr: c.RemoteAddr().String(), 1926 bw: http2newBufferedWriter(c), 1927 handler: h, 1928 streams: make(map[uint32]*http2stream), 1929 readFrameCh: make(chan http2readFrameResult), 1930 wantWriteFrameCh: make(chan http2frameWriteMsg, 8), 1931 wroteFrameCh: make(chan http2frameWriteResult, 1), 1932 bodyReadCh: make(chan http2bodyReadMsg), 1933 doneServing: make(chan struct{}), 1934 advMaxStreams: srv.maxConcurrentStreams(), 1935 writeSched: http2writeScheduler{ 1936 maxFrameSize: http2initialMaxFrameSize, 1937 }, 1938 initialWindowSize: http2initialWindowSize, 1939 headerTableSize: http2initialHeaderTableSize, 1940 serveG: http2newGoroutineLock(), 1941 pushEnabled: true, 1942 } 1943 sc.flow.add(http2initialWindowSize) 1944 sc.inflow.add(http2initialWindowSize) 1945 sc.hpackEncoder = hpack.NewEncoder(&sc.headerWriteBuf) 1946 sc.hpackDecoder = hpack.NewDecoder(http2initialHeaderTableSize, sc.onNewHeaderField) 1947 sc.hpackDecoder.SetMaxStringLength(sc.maxHeaderStringLen()) 1948 1949 fr := http2NewFramer(sc.bw, c) 1950 fr.SetMaxReadFrameSize(srv.maxReadFrameSize()) 1951 sc.framer = fr 1952 1953 if tc, ok := c.(*tls.Conn); ok { 1954 sc.tlsState = new(tls.ConnectionState) 1955 *sc.tlsState = tc.ConnectionState() 1956 1957 if sc.tlsState.Version < tls.VersionTLS12 { 1958 sc.rejectConn(http2ErrCodeInadequateSecurity, "TLS version too low") 1959 return 1960 } 1961 1962 if sc.tlsState.ServerName == "" { 1963 1964 } 1965 1966 if !srv.PermitProhibitedCipherSuites && http2isBadCipher(sc.tlsState.CipherSuite) { 1967 1968 sc.rejectConn(http2ErrCodeInadequateSecurity, fmt.Sprintf("Prohibited TLS 1.2 Cipher Suite: %x", sc.tlsState.CipherSuite)) 1969 return 1970 } 1971 } 1972 1973 if hook := http2testHookGetServerConn; hook != nil { 1974 hook(sc) 1975 } 1976 sc.serve() 1977 } 1978 1979 // isBadCipher reports whether the cipher is blacklisted by the HTTP/2 spec. 1980 func http2isBadCipher(cipher uint16) bool { 1981 switch cipher { 1982 case tls.TLS_RSA_WITH_RC4_128_SHA, 1983 tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA, 1984 tls.TLS_RSA_WITH_AES_128_CBC_SHA, 1985 tls.TLS_RSA_WITH_AES_256_CBC_SHA, 1986 tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 1987 tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 1988 tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 1989 tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA, 1990 tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 1991 tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 1992 tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: 1993 1994 return true 1995 default: 1996 return false 1997 } 1998 } 1999 2000 func (sc *http2serverConn) rejectConn(err http2ErrCode, debug string) { 2001 sc.vlogf("REJECTING conn: %v, %s", err, debug) 2002 2003 sc.framer.WriteGoAway(0, err, []byte(debug)) 2004 sc.bw.Flush() 2005 sc.conn.Close() 2006 } 2007 2008 type http2serverConn struct { 2009 // Immutable: 2010 srv *http2Server 2011 hs *Server 2012 conn net.Conn 2013 bw *http2bufferedWriter // writing to conn 2014 handler Handler 2015 framer *http2Framer 2016 hpackDecoder *hpack.Decoder 2017 doneServing chan struct{} // closed when serverConn.serve ends 2018 readFrameCh chan http2readFrameResult // written by serverConn.readFrames 2019 wantWriteFrameCh chan http2frameWriteMsg // from handlers -> serve 2020 wroteFrameCh chan http2frameWriteResult // from writeFrameAsync -> serve, tickles more frame writes 2021 bodyReadCh chan http2bodyReadMsg // from handlers -> serve 2022 testHookCh chan func(int) // code to run on the serve loop 2023 flow http2flow // conn-wide (not stream-specific) outbound flow control 2024 inflow http2flow // conn-wide inbound flow control 2025 tlsState *tls.ConnectionState // shared by all handlers, like net/http 2026 remoteAddrStr string 2027 2028 // Everything following is owned by the serve loop; use serveG.check(): 2029 serveG http2goroutineLock // used to verify funcs are on serve() 2030 pushEnabled bool 2031 sawFirstSettings bool // got the initial SETTINGS frame after the preface 2032 needToSendSettingsAck bool 2033 unackedSettings int // how many SETTINGS have we sent without ACKs? 2034 clientMaxStreams uint32 // SETTINGS_MAX_CONCURRENT_STREAMS from client (our PUSH_PROMISE limit) 2035 advMaxStreams uint32 // our SETTINGS_MAX_CONCURRENT_STREAMS advertised the client 2036 curOpenStreams uint32 // client's number of open streams 2037 maxStreamID uint32 // max ever seen 2038 streams map[uint32]*http2stream 2039 initialWindowSize int32 2040 headerTableSize uint32 2041 peerMaxHeaderListSize uint32 // zero means unknown (default) 2042 canonHeader map[string]string // http2-lower-case -> Go-Canonical-Case 2043 req http2requestParam // non-zero while reading request headers 2044 writingFrame bool // started write goroutine but haven't heard back on wroteFrameCh 2045 needsFrameFlush bool // last frame write wasn't a flush 2046 writeSched http2writeScheduler 2047 inGoAway bool // we've started to or sent GOAWAY 2048 needToSendGoAway bool // we need to schedule a GOAWAY frame write 2049 goAwayCode http2ErrCode 2050 shutdownTimerCh <-chan time.Time // nil until used 2051 shutdownTimer *time.Timer // nil until used 2052 2053 // Owned by the writeFrameAsync goroutine: 2054 headerWriteBuf bytes.Buffer 2055 hpackEncoder *hpack.Encoder 2056 } 2057 2058 func (sc *http2serverConn) maxHeaderStringLen() int { 2059 v := sc.maxHeaderListSize() 2060 if uint32(int(v)) == v { 2061 return int(v) 2062 } 2063 2064 return 0 2065 } 2066 2067 func (sc *http2serverConn) maxHeaderListSize() uint32 { 2068 n := sc.hs.MaxHeaderBytes 2069 if n <= 0 { 2070 n = DefaultMaxHeaderBytes 2071 } 2072 // http2's count is in a slightly different unit and includes 32 bytes per pair. 2073 // So, take the net/http.Server value and pad it up a bit, assuming 10 headers. 2074 const perFieldOverhead = 32 // per http2 spec 2075 const typicalHeaders = 10 // conservative 2076 return uint32(n + typicalHeaders*perFieldOverhead) 2077 } 2078 2079 // requestParam is the state of the next request, initialized over 2080 // potentially several frames HEADERS + zero or more CONTINUATION 2081 // frames. 2082 type http2requestParam struct { 2083 // stream is non-nil if we're reading (HEADER or CONTINUATION) 2084 // frames for a request (but not DATA). 2085 stream *http2stream 2086 header Header 2087 method, path string 2088 scheme, authority string 2089 sawRegularHeader bool // saw a non-pseudo header already 2090 invalidHeader bool // an invalid header was seen 2091 headerListSize int64 // actually uint32, but easier math this way 2092 } 2093 2094 // stream represents a stream. This is the minimal metadata needed by 2095 // the serve goroutine. Most of the actual stream state is owned by 2096 // the http.Handler's goroutine in the responseWriter. Because the 2097 // responseWriter's responseWriterState is recycled at the end of a 2098 // handler, this struct intentionally has no pointer to the 2099 // *responseWriter{,State} itself, as the Handler ending nils out the 2100 // responseWriter's state field. 2101 type http2stream struct { 2102 // immutable: 2103 id uint32 2104 body *http2pipe // non-nil if expecting DATA frames 2105 cw http2closeWaiter // closed wait stream transitions to closed state 2106 2107 // owned by serverConn's serve loop: 2108 bodyBytes int64 // body bytes seen so far 2109 declBodyBytes int64 // or -1 if undeclared 2110 flow http2flow // limits writing from Handler to client 2111 inflow http2flow // what the client is allowed to POST/etc to us 2112 parent *http2stream // or nil 2113 weight uint8 2114 state http2streamState 2115 sentReset bool // only true once detached from streams map 2116 gotReset bool // only true once detacted from streams map 2117 } 2118 2119 func (sc *http2serverConn) Framer() *http2Framer { return sc.framer } 2120 2121 func (sc *http2serverConn) CloseConn() error { return sc.conn.Close() } 2122 2123 func (sc *http2serverConn) Flush() error { return sc.bw.Flush() } 2124 2125 func (sc *http2serverConn) HeaderEncoder() (*hpack.Encoder, *bytes.Buffer) { 2126 return sc.hpackEncoder, &sc.headerWriteBuf 2127 } 2128 2129 func (sc *http2serverConn) state(streamID uint32) (http2streamState, *http2stream) { 2130 sc.serveG.check() 2131 2132 if st, ok := sc.streams[streamID]; ok { 2133 return st.state, st 2134 } 2135 2136 if streamID <= sc.maxStreamID { 2137 return http2stateClosed, nil 2138 } 2139 return http2stateIdle, nil 2140 } 2141 2142 // setConnState calls the net/http ConnState hook for this connection, if configured. 2143 // Note that the net/http package does StateNew and StateClosed for us. 2144 // There is currently no plan for StateHijacked or hijacking HTTP/2 connections. 2145 func (sc *http2serverConn) setConnState(state ConnState) { 2146 if sc.hs.ConnState != nil { 2147 sc.hs.ConnState(sc.conn, state) 2148 } 2149 } 2150 2151 func (sc *http2serverConn) vlogf(format string, args ...interface{}) { 2152 if http2VerboseLogs { 2153 sc.logf(format, args...) 2154 } 2155 } 2156 2157 func (sc *http2serverConn) logf(format string, args ...interface{}) { 2158 if lg := sc.hs.ErrorLog; lg != nil { 2159 lg.Printf(format, args...) 2160 } else { 2161 log.Printf(format, args...) 2162 } 2163 } 2164 2165 func (sc *http2serverConn) condlogf(err error, format string, args ...interface{}) { 2166 if err == nil { 2167 return 2168 } 2169 str := err.Error() 2170 if err == io.EOF || strings.Contains(str, "use of closed network connection") { 2171 2172 sc.vlogf(format, args...) 2173 } else { 2174 sc.logf(format, args...) 2175 } 2176 } 2177 2178 func (sc *http2serverConn) onNewHeaderField(f hpack.HeaderField) { 2179 sc.serveG.check() 2180 sc.vlogf("got header field %+v", f) 2181 switch { 2182 case !http2validHeader(f.Name): 2183 sc.req.invalidHeader = true 2184 case strings.HasPrefix(f.Name, ":"): 2185 if sc.req.sawRegularHeader { 2186 sc.logf("pseudo-header after regular header") 2187 sc.req.invalidHeader = true 2188 return 2189 } 2190 var dst *string 2191 switch f.Name { 2192 case ":method": 2193 dst = &sc.req.method 2194 case ":path": 2195 dst = &sc.req.path 2196 case ":scheme": 2197 dst = &sc.req.scheme 2198 case ":authority": 2199 dst = &sc.req.authority 2200 default: 2201 2202 sc.logf("invalid pseudo-header %q", f.Name) 2203 sc.req.invalidHeader = true 2204 return 2205 } 2206 if *dst != "" { 2207 sc.logf("duplicate pseudo-header %q sent", f.Name) 2208 sc.req.invalidHeader = true 2209 return 2210 } 2211 *dst = f.Value 2212 default: 2213 sc.req.sawRegularHeader = true 2214 sc.req.header.Add(sc.canonicalHeader(f.Name), f.Value) 2215 const headerFieldOverhead = 32 // per spec 2216 sc.req.headerListSize += int64(len(f.Name)) + int64(len(f.Value)) + headerFieldOverhead 2217 if sc.req.headerListSize > int64(sc.maxHeaderListSize()) { 2218 sc.hpackDecoder.SetEmitEnabled(false) 2219 } 2220 } 2221 } 2222 2223 func (sc *http2serverConn) canonicalHeader(v string) string { 2224 sc.serveG.check() 2225 cv, ok := http2commonCanonHeader[v] 2226 if ok { 2227 return cv 2228 } 2229 cv, ok = sc.canonHeader[v] 2230 if ok { 2231 return cv 2232 } 2233 if sc.canonHeader == nil { 2234 sc.canonHeader = make(map[string]string) 2235 } 2236 cv = CanonicalHeaderKey(v) 2237 sc.canonHeader[v] = cv 2238 return cv 2239 } 2240 2241 type http2readFrameResult struct { 2242 f http2Frame // valid until readMore is called 2243 err error 2244 2245 // readMore should be called once the consumer no longer needs or 2246 // retains f. After readMore, f is invalid and more frames can be 2247 // read. 2248 readMore func() 2249 } 2250 2251 // readFrames is the loop that reads incoming frames. 2252 // It takes care to only read one frame at a time, blocking until the 2253 // consumer is done with the frame. 2254 // It's run on its own goroutine. 2255 func (sc *http2serverConn) readFrames() { 2256 gate := make(http2gate) 2257 for { 2258 f, err := sc.framer.ReadFrame() 2259 select { 2260 case sc.readFrameCh <- http2readFrameResult{f, err, gate.Done}: 2261 case <-sc.doneServing: 2262 return 2263 } 2264 select { 2265 case <-gate: 2266 case <-sc.doneServing: 2267 return 2268 } 2269 } 2270 } 2271 2272 // frameWriteResult is the message passed from writeFrameAsync to the serve goroutine. 2273 type http2frameWriteResult struct { 2274 wm http2frameWriteMsg // what was written (or attempted) 2275 err error // result of the writeFrame call 2276 } 2277 2278 // writeFrameAsync runs in its own goroutine and writes a single frame 2279 // and then reports when it's done. 2280 // At most one goroutine can be running writeFrameAsync at a time per 2281 // serverConn. 2282 func (sc *http2serverConn) writeFrameAsync(wm http2frameWriteMsg) { 2283 err := wm.write.writeFrame(sc) 2284 sc.wroteFrameCh <- http2frameWriteResult{wm, err} 2285 } 2286 2287 func (sc *http2serverConn) closeAllStreamsOnConnClose() { 2288 sc.serveG.check() 2289 for _, st := range sc.streams { 2290 sc.closeStream(st, http2errClientDisconnected) 2291 } 2292 } 2293 2294 func (sc *http2serverConn) stopShutdownTimer() { 2295 sc.serveG.check() 2296 if t := sc.shutdownTimer; t != nil { 2297 t.Stop() 2298 } 2299 } 2300 2301 func (sc *http2serverConn) notePanic() { 2302 if http2testHookOnPanicMu != nil { 2303 http2testHookOnPanicMu.Lock() 2304 defer http2testHookOnPanicMu.Unlock() 2305 } 2306 if http2testHookOnPanic != nil { 2307 if e := recover(); e != nil { 2308 if http2testHookOnPanic(sc, e) { 2309 panic(e) 2310 } 2311 } 2312 } 2313 } 2314 2315 func (sc *http2serverConn) serve() { 2316 sc.serveG.check() 2317 defer sc.notePanic() 2318 defer sc.conn.Close() 2319 defer sc.closeAllStreamsOnConnClose() 2320 defer sc.stopShutdownTimer() 2321 defer close(sc.doneServing) 2322 2323 sc.vlogf("HTTP/2 connection from %v on %p", sc.conn.RemoteAddr(), sc.hs) 2324 2325 sc.writeFrame(http2frameWriteMsg{ 2326 write: http2writeSettings{ 2327 {http2SettingMaxFrameSize, sc.srv.maxReadFrameSize()}, 2328 {http2SettingMaxConcurrentStreams, sc.advMaxStreams}, 2329 {http2SettingMaxHeaderListSize, sc.maxHeaderListSize()}, 2330 }, 2331 }) 2332 sc.unackedSettings++ 2333 2334 if err := sc.readPreface(); err != nil { 2335 sc.condlogf(err, "error reading preface from client %v: %v", sc.conn.RemoteAddr(), err) 2336 return 2337 } 2338 2339 sc.setConnState(StateActive) 2340 sc.setConnState(StateIdle) 2341 2342 go sc.readFrames() 2343 2344 settingsTimer := time.NewTimer(http2firstSettingsTimeout) 2345 loopNum := 0 2346 for { 2347 loopNum++ 2348 select { 2349 case wm := <-sc.wantWriteFrameCh: 2350 sc.writeFrame(wm) 2351 case res := <-sc.wroteFrameCh: 2352 sc.wroteFrame(res) 2353 case res := <-sc.readFrameCh: 2354 if !sc.processFrameFromReader(res) { 2355 return 2356 } 2357 res.readMore() 2358 if settingsTimer.C != nil { 2359 settingsTimer.Stop() 2360 settingsTimer.C = nil 2361 } 2362 case m := <-sc.bodyReadCh: 2363 sc.noteBodyRead(m.st, m.n) 2364 case <-settingsTimer.C: 2365 sc.logf("timeout waiting for SETTINGS frames from %v", sc.conn.RemoteAddr()) 2366 return 2367 case <-sc.shutdownTimerCh: 2368 sc.vlogf("GOAWAY close timer fired; closing conn from %v", sc.conn.RemoteAddr()) 2369 return 2370 case fn := <-sc.testHookCh: 2371 fn(loopNum) 2372 } 2373 } 2374 } 2375 2376 // readPreface reads the ClientPreface greeting from the peer 2377 // or returns an error on timeout or an invalid greeting. 2378 func (sc *http2serverConn) readPreface() error { 2379 errc := make(chan error, 1) 2380 go func() { 2381 2382 buf := make([]byte, len(http2ClientPreface)) 2383 if _, err := io.ReadFull(sc.conn, buf); err != nil { 2384 errc <- err 2385 } else if !bytes.Equal(buf, http2clientPreface) { 2386 errc <- fmt.Errorf("bogus greeting %q", buf) 2387 } else { 2388 errc <- nil 2389 } 2390 }() 2391 timer := time.NewTimer(http2prefaceTimeout) 2392 defer timer.Stop() 2393 select { 2394 case <-timer.C: 2395 return errors.New("timeout waiting for client preface") 2396 case err := <-errc: 2397 if err == nil { 2398 sc.vlogf("client %v said hello", sc.conn.RemoteAddr()) 2399 } 2400 return err 2401 } 2402 } 2403 2404 var http2errChanPool = sync.Pool{ 2405 New: func() interface{} { return make(chan error, 1) }, 2406 } 2407 2408 var http2writeDataPool = sync.Pool{ 2409 New: func() interface{} { return new(http2writeData) }, 2410 } 2411 2412 // writeDataFromHandler writes DATA response frames from a handler on 2413 // the given stream. 2414 func (sc *http2serverConn) writeDataFromHandler(stream *http2stream, data []byte, endStream bool) error { 2415 ch := http2errChanPool.Get().(chan error) 2416 writeArg := http2writeDataPool.Get().(*http2writeData) 2417 *writeArg = http2writeData{stream.id, data, endStream} 2418 err := sc.writeFrameFromHandler(http2frameWriteMsg{ 2419 write: writeArg, 2420 stream: stream, 2421 done: ch, 2422 }) 2423 if err != nil { 2424 return err 2425 } 2426 var frameWriteDone bool // the frame write is done (successfully or not) 2427 select { 2428 case err = <-ch: 2429 frameWriteDone = true 2430 case <-sc.doneServing: 2431 return http2errClientDisconnected 2432 case <-stream.cw: 2433 2434 select { 2435 case err = <-ch: 2436 frameWriteDone = true 2437 default: 2438 return http2errStreamClosed 2439 } 2440 } 2441 http2errChanPool.Put(ch) 2442 if frameWriteDone { 2443 http2writeDataPool.Put(writeArg) 2444 } 2445 return err 2446 } 2447 2448 // writeFrameFromHandler sends wm to sc.wantWriteFrameCh, but aborts 2449 // if the connection has gone away. 2450 // 2451 // This must not be run from the serve goroutine itself, else it might 2452 // deadlock writing to sc.wantWriteFrameCh (which is only mildly 2453 // buffered and is read by serve itself). If you're on the serve 2454 // goroutine, call writeFrame instead. 2455 func (sc *http2serverConn) writeFrameFromHandler(wm http2frameWriteMsg) error { 2456 sc.serveG.checkNotOn() 2457 select { 2458 case sc.wantWriteFrameCh <- wm: 2459 return nil 2460 case <-sc.doneServing: 2461 2462 return http2errClientDisconnected 2463 } 2464 } 2465 2466 // writeFrame schedules a frame to write and sends it if there's nothing 2467 // already being written. 2468 // 2469 // There is no pushback here (the serve goroutine never blocks). It's 2470 // the http.Handlers that block, waiting for their previous frames to 2471 // make it onto the wire 2472 // 2473 // If you're not on the serve goroutine, use writeFrameFromHandler instead. 2474 func (sc *http2serverConn) writeFrame(wm http2frameWriteMsg) { 2475 sc.serveG.check() 2476 sc.writeSched.add(wm) 2477 sc.scheduleFrameWrite() 2478 } 2479 2480 // startFrameWrite starts a goroutine to write wm (in a separate 2481 // goroutine since that might block on the network), and updates the 2482 // serve goroutine's state about the world, updated from info in wm. 2483 func (sc *http2serverConn) startFrameWrite(wm http2frameWriteMsg) { 2484 sc.serveG.check() 2485 if sc.writingFrame { 2486 panic("internal error: can only be writing one frame at a time") 2487 } 2488 2489 st := wm.stream 2490 if st != nil { 2491 switch st.state { 2492 case http2stateHalfClosedLocal: 2493 panic("internal error: attempt to send frame on half-closed-local stream") 2494 case http2stateClosed: 2495 if st.sentReset || st.gotReset { 2496 2497 sc.scheduleFrameWrite() 2498 return 2499 } 2500 panic(fmt.Sprintf("internal error: attempt to send a write %v on a closed stream", wm)) 2501 } 2502 } 2503 2504 sc.writingFrame = true 2505 sc.needsFrameFlush = true 2506 go sc.writeFrameAsync(wm) 2507 } 2508 2509 // wroteFrame is called on the serve goroutine with the result of 2510 // whatever happened on writeFrameAsync. 2511 func (sc *http2serverConn) wroteFrame(res http2frameWriteResult) { 2512 sc.serveG.check() 2513 if !sc.writingFrame { 2514 panic("internal error: expected to be already writing a frame") 2515 } 2516 sc.writingFrame = false 2517 2518 wm := res.wm 2519 st := wm.stream 2520 2521 closeStream := http2endsStream(wm.write) 2522 2523 if ch := wm.done; ch != nil { 2524 select { 2525 case ch <- res.err: 2526 default: 2527 panic(fmt.Sprintf("unbuffered done channel passed in for type %T", wm.write)) 2528 } 2529 } 2530 wm.write = nil 2531 2532 if closeStream { 2533 if st == nil { 2534 panic("internal error: expecting non-nil stream") 2535 } 2536 switch st.state { 2537 case http2stateOpen: 2538 2539 st.state = http2stateHalfClosedLocal 2540 errCancel := http2StreamError{st.id, http2ErrCodeCancel} 2541 sc.resetStream(errCancel) 2542 case http2stateHalfClosedRemote: 2543 sc.closeStream(st, http2errHandlerComplete) 2544 } 2545 } 2546 2547 sc.scheduleFrameWrite() 2548 } 2549 2550 // scheduleFrameWrite tickles the frame writing scheduler. 2551 // 2552 // If a frame is already being written, nothing happens. This will be called again 2553 // when the frame is done being written. 2554 // 2555 // If a frame isn't being written we need to send one, the best frame 2556 // to send is selected, preferring first things that aren't 2557 // stream-specific (e.g. ACKing settings), and then finding the 2558 // highest priority stream. 2559 // 2560 // If a frame isn't being written and there's nothing else to send, we 2561 // flush the write buffer. 2562 func (sc *http2serverConn) scheduleFrameWrite() { 2563 sc.serveG.check() 2564 if sc.writingFrame { 2565 return 2566 } 2567 if sc.needToSendGoAway { 2568 sc.needToSendGoAway = false 2569 sc.startFrameWrite(http2frameWriteMsg{ 2570 write: &http2writeGoAway{ 2571 maxStreamID: sc.maxStreamID, 2572 code: sc.goAwayCode, 2573 }, 2574 }) 2575 return 2576 } 2577 if sc.needToSendSettingsAck { 2578 sc.needToSendSettingsAck = false 2579 sc.startFrameWrite(http2frameWriteMsg{write: http2writeSettingsAck{}}) 2580 return 2581 } 2582 if !sc.inGoAway { 2583 if wm, ok := sc.writeSched.take(); ok { 2584 sc.startFrameWrite(wm) 2585 return 2586 } 2587 } 2588 if sc.needsFrameFlush { 2589 sc.startFrameWrite(http2frameWriteMsg{write: http2flushFrameWriter{}}) 2590 sc.needsFrameFlush = false 2591 return 2592 } 2593 } 2594 2595 func (sc *http2serverConn) goAway(code http2ErrCode) { 2596 sc.serveG.check() 2597 if sc.inGoAway { 2598 return 2599 } 2600 if code != http2ErrCodeNo { 2601 sc.shutDownIn(250 * time.Millisecond) 2602 } else { 2603 2604 sc.shutDownIn(1 * time.Second) 2605 } 2606 sc.inGoAway = true 2607 sc.needToSendGoAway = true 2608 sc.goAwayCode = code 2609 sc.scheduleFrameWrite() 2610 } 2611 2612 func (sc *http2serverConn) shutDownIn(d time.Duration) { 2613 sc.serveG.check() 2614 sc.shutdownTimer = time.NewTimer(d) 2615 sc.shutdownTimerCh = sc.shutdownTimer.C 2616 } 2617 2618 func (sc *http2serverConn) resetStream(se http2StreamError) { 2619 sc.serveG.check() 2620 sc.writeFrame(http2frameWriteMsg{write: se}) 2621 if st, ok := sc.streams[se.StreamID]; ok { 2622 st.sentReset = true 2623 sc.closeStream(st, se) 2624 } 2625 } 2626 2627 // curHeaderStreamID returns the stream ID of the header block we're 2628 // currently in the middle of reading. If this returns non-zero, the 2629 // next frame must be a CONTINUATION with this stream id. 2630 func (sc *http2serverConn) curHeaderStreamID() uint32 { 2631 sc.serveG.check() 2632 st := sc.req.stream 2633 if st == nil { 2634 return 0 2635 } 2636 return st.id 2637 } 2638 2639 // processFrameFromReader processes the serve loop's read from readFrameCh from the 2640 // frame-reading goroutine. 2641 // processFrameFromReader returns whether the connection should be kept open. 2642 func (sc *http2serverConn) processFrameFromReader(res http2readFrameResult) bool { 2643 sc.serveG.check() 2644 err := res.err 2645 if err != nil { 2646 if err == http2ErrFrameTooLarge { 2647 sc.goAway(http2ErrCodeFrameSize) 2648 return true 2649 } 2650 clientGone := err == io.EOF || strings.Contains(err.Error(), "use of closed network connection") 2651 if clientGone { 2652 2653 return false 2654 } 2655 } else { 2656 f := res.f 2657 sc.vlogf("got %v: %#v", f.Header(), f) 2658 err = sc.processFrame(f) 2659 if err == nil { 2660 return true 2661 } 2662 } 2663 2664 switch ev := err.(type) { 2665 case http2StreamError: 2666 sc.resetStream(ev) 2667 return true 2668 case http2goAwayFlowError: 2669 sc.goAway(http2ErrCodeFlowControl) 2670 return true 2671 case http2ConnectionError: 2672 sc.logf("%v: %v", sc.conn.RemoteAddr(), ev) 2673 sc.goAway(http2ErrCode(ev)) 2674 return true 2675 default: 2676 if res.err != nil { 2677 sc.logf("disconnecting; error reading frame from client %s: %v", sc.conn.RemoteAddr(), err) 2678 } else { 2679 sc.logf("disconnection due to other error: %v", err) 2680 } 2681 return false 2682 } 2683 } 2684 2685 func (sc *http2serverConn) processFrame(f http2Frame) error { 2686 sc.serveG.check() 2687 2688 if !sc.sawFirstSettings { 2689 if _, ok := f.(*http2SettingsFrame); !ok { 2690 return http2ConnectionError(http2ErrCodeProtocol) 2691 } 2692 sc.sawFirstSettings = true 2693 } 2694 2695 if s := sc.curHeaderStreamID(); s != 0 { 2696 if cf, ok := f.(*http2ContinuationFrame); !ok { 2697 return http2ConnectionError(http2ErrCodeProtocol) 2698 } else if cf.Header().StreamID != s { 2699 return http2ConnectionError(http2ErrCodeProtocol) 2700 } 2701 } 2702 2703 switch f := f.(type) { 2704 case *http2SettingsFrame: 2705 return sc.processSettings(f) 2706 case *http2HeadersFrame: 2707 return sc.processHeaders(f) 2708 case *http2ContinuationFrame: 2709 return sc.processContinuation(f) 2710 case *http2WindowUpdateFrame: 2711 return sc.processWindowUpdate(f) 2712 case *http2PingFrame: 2713 return sc.processPing(f) 2714 case *http2DataFrame: 2715 return sc.processData(f) 2716 case *http2RSTStreamFrame: 2717 return sc.processResetStream(f) 2718 case *http2PriorityFrame: 2719 return sc.processPriority(f) 2720 case *http2PushPromiseFrame: 2721 2722 return http2ConnectionError(http2ErrCodeProtocol) 2723 default: 2724 sc.vlogf("Ignoring frame: %v", f.Header()) 2725 return nil 2726 } 2727 } 2728 2729 func (sc *http2serverConn) processPing(f *http2PingFrame) error { 2730 sc.serveG.check() 2731 if f.Flags.Has(http2FlagSettingsAck) { 2732 2733 return nil 2734 } 2735 if f.StreamID != 0 { 2736 2737 return http2ConnectionError(http2ErrCodeProtocol) 2738 } 2739 sc.writeFrame(http2frameWriteMsg{write: http2writePingAck{f}}) 2740 return nil 2741 } 2742 2743 func (sc *http2serverConn) processWindowUpdate(f *http2WindowUpdateFrame) error { 2744 sc.serveG.check() 2745 switch { 2746 case f.StreamID != 0: 2747 st := sc.streams[f.StreamID] 2748 if st == nil { 2749 2750 return nil 2751 } 2752 if !st.flow.add(int32(f.Increment)) { 2753 return http2StreamError{f.StreamID, http2ErrCodeFlowControl} 2754 } 2755 default: 2756 if !sc.flow.add(int32(f.Increment)) { 2757 return http2goAwayFlowError{} 2758 } 2759 } 2760 sc.scheduleFrameWrite() 2761 return nil 2762 } 2763 2764 func (sc *http2serverConn) processResetStream(f *http2RSTStreamFrame) error { 2765 sc.serveG.check() 2766 2767 state, st := sc.state(f.StreamID) 2768 if state == http2stateIdle { 2769 2770 return http2ConnectionError(http2ErrCodeProtocol) 2771 } 2772 if st != nil { 2773 st.gotReset = true 2774 sc.closeStream(st, http2StreamError{f.StreamID, f.ErrCode}) 2775 } 2776 return nil 2777 } 2778 2779 func (sc *http2serverConn) closeStream(st *http2stream, err error) { 2780 sc.serveG.check() 2781 if st.state == http2stateIdle || st.state == http2stateClosed { 2782 panic(fmt.Sprintf("invariant; can't close stream in state %v", st.state)) 2783 } 2784 st.state = http2stateClosed 2785 sc.curOpenStreams-- 2786 if sc.curOpenStreams == 0 { 2787 sc.setConnState(StateIdle) 2788 } 2789 delete(sc.streams, st.id) 2790 if p := st.body; p != nil { 2791 p.CloseWithError(err) 2792 } 2793 st.cw.Close() 2794 sc.writeSched.forgetStream(st.id) 2795 } 2796 2797 func (sc *http2serverConn) processSettings(f *http2SettingsFrame) error { 2798 sc.serveG.check() 2799 if f.IsAck() { 2800 sc.unackedSettings-- 2801 if sc.unackedSettings < 0 { 2802 2803 return http2ConnectionError(http2ErrCodeProtocol) 2804 } 2805 return nil 2806 } 2807 if err := f.ForeachSetting(sc.processSetting); err != nil { 2808 return err 2809 } 2810 sc.needToSendSettingsAck = true 2811 sc.scheduleFrameWrite() 2812 return nil 2813 } 2814 2815 func (sc *http2serverConn) processSetting(s http2Setting) error { 2816 sc.serveG.check() 2817 if err := s.Valid(); err != nil { 2818 return err 2819 } 2820 sc.vlogf("processing setting %v", s) 2821 switch s.ID { 2822 case http2SettingHeaderTableSize: 2823 sc.headerTableSize = s.Val 2824 sc.hpackEncoder.SetMaxDynamicTableSize(s.Val) 2825 case http2SettingEnablePush: 2826 sc.pushEnabled = s.Val != 0 2827 case http2SettingMaxConcurrentStreams: 2828 sc.clientMaxStreams = s.Val 2829 case http2SettingInitialWindowSize: 2830 return sc.processSettingInitialWindowSize(s.Val) 2831 case http2SettingMaxFrameSize: 2832 sc.writeSched.maxFrameSize = s.Val 2833 case http2SettingMaxHeaderListSize: 2834 sc.peerMaxHeaderListSize = s.Val 2835 default: 2836 2837 } 2838 return nil 2839 } 2840 2841 func (sc *http2serverConn) processSettingInitialWindowSize(val uint32) error { 2842 sc.serveG.check() 2843 2844 old := sc.initialWindowSize 2845 sc.initialWindowSize = int32(val) 2846 growth := sc.initialWindowSize - old 2847 for _, st := range sc.streams { 2848 if !st.flow.add(growth) { 2849 2850 return http2ConnectionError(http2ErrCodeFlowControl) 2851 } 2852 } 2853 return nil 2854 } 2855 2856 func (sc *http2serverConn) processData(f *http2DataFrame) error { 2857 sc.serveG.check() 2858 2859 id := f.Header().StreamID 2860 st, ok := sc.streams[id] 2861 if !ok || st.state != http2stateOpen { 2862 2863 return http2StreamError{id, http2ErrCodeStreamClosed} 2864 } 2865 if st.body == nil { 2866 panic("internal error: should have a body in this state") 2867 } 2868 data := f.Data() 2869 2870 if st.declBodyBytes != -1 && st.bodyBytes+int64(len(data)) > st.declBodyBytes { 2871 st.body.CloseWithError(fmt.Errorf("sender tried to send more than declared Content-Length of %d bytes", st.declBodyBytes)) 2872 return http2StreamError{id, http2ErrCodeStreamClosed} 2873 } 2874 if len(data) > 0 { 2875 2876 if int(st.inflow.available()) < len(data) { 2877 return http2StreamError{id, http2ErrCodeFlowControl} 2878 } 2879 st.inflow.take(int32(len(data))) 2880 wrote, err := st.body.Write(data) 2881 if err != nil { 2882 return http2StreamError{id, http2ErrCodeStreamClosed} 2883 } 2884 if wrote != len(data) { 2885 panic("internal error: bad Writer") 2886 } 2887 st.bodyBytes += int64(len(data)) 2888 } 2889 if f.StreamEnded() { 2890 if st.declBodyBytes != -1 && st.declBodyBytes != st.bodyBytes { 2891 st.body.CloseWithError(fmt.Errorf("request declared a Content-Length of %d but only wrote %d bytes", 2892 st.declBodyBytes, st.bodyBytes)) 2893 } else { 2894 st.body.CloseWithError(io.EOF) 2895 } 2896 st.state = http2stateHalfClosedRemote 2897 } 2898 return nil 2899 } 2900 2901 func (sc *http2serverConn) processHeaders(f *http2HeadersFrame) error { 2902 sc.serveG.check() 2903 id := f.Header().StreamID 2904 if sc.inGoAway { 2905 2906 return nil 2907 } 2908 2909 if id%2 != 1 || id <= sc.maxStreamID || sc.req.stream != nil { 2910 2911 return http2ConnectionError(http2ErrCodeProtocol) 2912 } 2913 if id > sc.maxStreamID { 2914 sc.maxStreamID = id 2915 } 2916 st := &http2stream{ 2917 id: id, 2918 state: http2stateOpen, 2919 } 2920 if f.StreamEnded() { 2921 st.state = http2stateHalfClosedRemote 2922 } 2923 st.cw.Init() 2924 2925 st.flow.conn = &sc.flow 2926 st.flow.add(sc.initialWindowSize) 2927 st.inflow.conn = &sc.inflow 2928 st.inflow.add(http2initialWindowSize) 2929 2930 sc.streams[id] = st 2931 if f.HasPriority() { 2932 http2adjustStreamPriority(sc.streams, st.id, f.Priority) 2933 } 2934 sc.curOpenStreams++ 2935 if sc.curOpenStreams == 1 { 2936 sc.setConnState(StateActive) 2937 } 2938 sc.req = http2requestParam{ 2939 stream: st, 2940 header: make(Header), 2941 } 2942 sc.hpackDecoder.SetEmitEnabled(true) 2943 return sc.processHeaderBlockFragment(st, f.HeaderBlockFragment(), f.HeadersEnded()) 2944 } 2945 2946 func (sc *http2serverConn) processContinuation(f *http2ContinuationFrame) error { 2947 sc.serveG.check() 2948 st := sc.streams[f.Header().StreamID] 2949 if st == nil || sc.curHeaderStreamID() != st.id { 2950 return http2ConnectionError(http2ErrCodeProtocol) 2951 } 2952 return sc.processHeaderBlockFragment(st, f.HeaderBlockFragment(), f.HeadersEnded()) 2953 } 2954 2955 func (sc *http2serverConn) processHeaderBlockFragment(st *http2stream, frag []byte, end bool) error { 2956 sc.serveG.check() 2957 if _, err := sc.hpackDecoder.Write(frag); err != nil { 2958 return http2ConnectionError(http2ErrCodeCompression) 2959 } 2960 if !end { 2961 return nil 2962 } 2963 if err := sc.hpackDecoder.Close(); err != nil { 2964 return http2ConnectionError(http2ErrCodeCompression) 2965 } 2966 defer sc.resetPendingRequest() 2967 if sc.curOpenStreams > sc.advMaxStreams { 2968 2969 if sc.unackedSettings == 0 { 2970 2971 return http2StreamError{st.id, http2ErrCodeProtocol} 2972 } 2973 2974 return http2StreamError{st.id, http2ErrCodeRefusedStream} 2975 } 2976 2977 rw, req, err := sc.newWriterAndRequest() 2978 if err != nil { 2979 return err 2980 } 2981 st.body = req.Body.(*http2requestBody).pipe 2982 st.declBodyBytes = req.ContentLength 2983 2984 handler := sc.handler.ServeHTTP 2985 if !sc.hpackDecoder.EmitEnabled() { 2986 2987 handler = http2handleHeaderListTooLong 2988 } 2989 2990 go sc.runHandler(rw, req, handler) 2991 return nil 2992 } 2993 2994 func (sc *http2serverConn) processPriority(f *http2PriorityFrame) error { 2995 http2adjustStreamPriority(sc.streams, f.StreamID, f.http2PriorityParam) 2996 return nil 2997 } 2998 2999 func http2adjustStreamPriority(streams map[uint32]*http2stream, streamID uint32, priority http2PriorityParam) { 3000 st, ok := streams[streamID] 3001 if !ok { 3002 3003 return 3004 } 3005 st.weight = priority.Weight 3006 parent := streams[priority.StreamDep] 3007 if parent == st { 3008 3009 return 3010 } 3011 3012 for piter := parent; piter != nil; piter = piter.parent { 3013 if piter == st { 3014 parent.parent = st.parent 3015 break 3016 } 3017 } 3018 st.parent = parent 3019 if priority.Exclusive && (st.parent != nil || priority.StreamDep == 0) { 3020 for _, openStream := range streams { 3021 if openStream != st && openStream.parent == st.parent { 3022 openStream.parent = st 3023 } 3024 } 3025 } 3026 } 3027 3028 // resetPendingRequest zeros out all state related to a HEADERS frame 3029 // and its zero or more CONTINUATION frames sent to start a new 3030 // request. 3031 func (sc *http2serverConn) resetPendingRequest() { 3032 sc.serveG.check() 3033 sc.req = http2requestParam{} 3034 } 3035 3036 func (sc *http2serverConn) newWriterAndRequest() (*http2responseWriter, *Request, error) { 3037 sc.serveG.check() 3038 rp := &sc.req 3039 if rp.invalidHeader || rp.method == "" || rp.path == "" || 3040 (rp.scheme != "https" && rp.scheme != "http") { 3041 3042 return nil, nil, http2StreamError{rp.stream.id, http2ErrCodeProtocol} 3043 } 3044 var tlsState *tls.ConnectionState // nil if not scheme https 3045 if rp.scheme == "https" { 3046 tlsState = sc.tlsState 3047 } 3048 authority := rp.authority 3049 if authority == "" { 3050 authority = rp.header.Get("Host") 3051 } 3052 needsContinue := rp.header.Get("Expect") == "100-continue" 3053 if needsContinue { 3054 rp.header.Del("Expect") 3055 } 3056 3057 if cookies := rp.header["Cookie"]; len(cookies) > 1 { 3058 rp.header.Set("Cookie", strings.Join(cookies, "; ")) 3059 } 3060 bodyOpen := rp.stream.state == http2stateOpen 3061 body := &http2requestBody{ 3062 conn: sc, 3063 stream: rp.stream, 3064 needsContinue: needsContinue, 3065 } 3066 3067 url, err := url.ParseRequestURI(rp.path) 3068 if err != nil { 3069 3070 return nil, nil, http2StreamError{rp.stream.id, http2ErrCodeProtocol} 3071 } 3072 req := &Request{ 3073 Method: rp.method, 3074 URL: url, 3075 RemoteAddr: sc.remoteAddrStr, 3076 Header: rp.header, 3077 RequestURI: rp.path, 3078 Proto: "HTTP/2.0", 3079 ProtoMajor: 2, 3080 ProtoMinor: 0, 3081 TLS: tlsState, 3082 Host: authority, 3083 Body: body, 3084 } 3085 if bodyOpen { 3086 body.pipe = &http2pipe{ 3087 b: &http2fixedBuffer{buf: make([]byte, http2initialWindowSize)}, 3088 } 3089 3090 if vv, ok := rp.header["Content-Length"]; ok { 3091 req.ContentLength, _ = strconv.ParseInt(vv[0], 10, 64) 3092 } else { 3093 req.ContentLength = -1 3094 } 3095 } 3096 3097 rws := http2responseWriterStatePool.Get().(*http2responseWriterState) 3098 bwSave := rws.bw 3099 *rws = http2responseWriterState{} 3100 rws.conn = sc 3101 rws.bw = bwSave 3102 rws.bw.Reset(http2chunkWriter{rws}) 3103 rws.stream = rp.stream 3104 rws.req = req 3105 rws.body = body 3106 3107 rw := &http2responseWriter{rws: rws} 3108 return rw, req, nil 3109 } 3110 3111 // Run on its own goroutine. 3112 func (sc *http2serverConn) runHandler(rw *http2responseWriter, req *Request, handler func(ResponseWriter, *Request)) { 3113 defer rw.handlerDone() 3114 3115 handler(rw, req) 3116 } 3117 3118 func http2handleHeaderListTooLong(w ResponseWriter, r *Request) { 3119 // 10.5.1 Limits on Header Block Size: 3120 // .. "A server that receives a larger header block than it is 3121 // willing to handle can send an HTTP 431 (Request Header Fields Too 3122 // Large) status code" 3123 const statusRequestHeaderFieldsTooLarge = 431 // only in Go 1.6+ 3124 w.WriteHeader(statusRequestHeaderFieldsTooLarge) 3125 io.WriteString(w, "<h1>HTTP Error 431</h1><p>Request Header Field(s) Too Large</p>") 3126 } 3127 3128 // called from handler goroutines. 3129 // h may be nil. 3130 func (sc *http2serverConn) writeHeaders(st *http2stream, headerData *http2writeResHeaders) error { 3131 sc.serveG.checkNotOn() 3132 var errc chan error 3133 if headerData.h != nil { 3134 3135 errc = http2errChanPool.Get().(chan error) 3136 } 3137 if err := sc.writeFrameFromHandler(http2frameWriteMsg{ 3138 write: headerData, 3139 stream: st, 3140 done: errc, 3141 }); err != nil { 3142 return err 3143 } 3144 if errc != nil { 3145 select { 3146 case err := <-errc: 3147 http2errChanPool.Put(errc) 3148 return err 3149 case <-sc.doneServing: 3150 return http2errClientDisconnected 3151 case <-st.cw: 3152 return http2errStreamClosed 3153 } 3154 } 3155 return nil 3156 } 3157 3158 // called from handler goroutines. 3159 func (sc *http2serverConn) write100ContinueHeaders(st *http2stream) { 3160 sc.writeFrameFromHandler(http2frameWriteMsg{ 3161 write: http2write100ContinueHeadersFrame{st.id}, 3162 stream: st, 3163 }) 3164 } 3165 3166 // A bodyReadMsg tells the server loop that the http.Handler read n 3167 // bytes of the DATA from the client on the given stream. 3168 type http2bodyReadMsg struct { 3169 st *http2stream 3170 n int 3171 } 3172 3173 // called from handler goroutines. 3174 // Notes that the handler for the given stream ID read n bytes of its body 3175 // and schedules flow control tokens to be sent. 3176 func (sc *http2serverConn) noteBodyReadFromHandler(st *http2stream, n int) { 3177 sc.serveG.checkNotOn() 3178 select { 3179 case sc.bodyReadCh <- http2bodyReadMsg{st, n}: 3180 case <-sc.doneServing: 3181 } 3182 } 3183 3184 func (sc *http2serverConn) noteBodyRead(st *http2stream, n int) { 3185 sc.serveG.check() 3186 sc.sendWindowUpdate(nil, n) 3187 if st.state != http2stateHalfClosedRemote && st.state != http2stateClosed { 3188 3189 sc.sendWindowUpdate(st, n) 3190 } 3191 } 3192 3193 // st may be nil for conn-level 3194 func (sc *http2serverConn) sendWindowUpdate(st *http2stream, n int) { 3195 sc.serveG.check() 3196 // "The legal range for the increment to the flow control 3197 // window is 1 to 2^31-1 (2,147,483,647) octets." 3198 // A Go Read call on 64-bit machines could in theory read 3199 // a larger Read than this. Very unlikely, but we handle it here 3200 // rather than elsewhere for now. 3201 const maxUint31 = 1<<31 - 1 3202 for n >= maxUint31 { 3203 sc.sendWindowUpdate32(st, maxUint31) 3204 n -= maxUint31 3205 } 3206 sc.sendWindowUpdate32(st, int32(n)) 3207 } 3208 3209 // st may be nil for conn-level 3210 func (sc *http2serverConn) sendWindowUpdate32(st *http2stream, n int32) { 3211 sc.serveG.check() 3212 if n == 0 { 3213 return 3214 } 3215 if n < 0 { 3216 panic("negative update") 3217 } 3218 var streamID uint32 3219 if st != nil { 3220 streamID = st.id 3221 } 3222 sc.writeFrame(http2frameWriteMsg{ 3223 write: http2writeWindowUpdate{streamID: streamID, n: uint32(n)}, 3224 stream: st, 3225 }) 3226 var ok bool 3227 if st == nil { 3228 ok = sc.inflow.add(n) 3229 } else { 3230 ok = st.inflow.add(n) 3231 } 3232 if !ok { 3233 panic("internal error; sent too many window updates without decrements?") 3234 } 3235 } 3236 3237 type http2requestBody struct { 3238 stream *http2stream 3239 conn *http2serverConn 3240 closed bool 3241 pipe *http2pipe // non-nil if we have a HTTP entity message body 3242 needsContinue bool // need to send a 100-continue 3243 } 3244 3245 func (b *http2requestBody) Close() error { 3246 if b.pipe != nil { 3247 b.pipe.CloseWithError(http2errClosedBody) 3248 } 3249 b.closed = true 3250 return nil 3251 } 3252 3253 func (b *http2requestBody) Read(p []byte) (n int, err error) { 3254 if b.needsContinue { 3255 b.needsContinue = false 3256 b.conn.write100ContinueHeaders(b.stream) 3257 } 3258 if b.pipe == nil { 3259 return 0, io.EOF 3260 } 3261 n, err = b.pipe.Read(p) 3262 if n > 0 { 3263 b.conn.noteBodyReadFromHandler(b.stream, n) 3264 } 3265 return 3266 } 3267 3268 // responseWriter is the http.ResponseWriter implementation. It's 3269 // intentionally small (1 pointer wide) to minimize garbage. The 3270 // responseWriterState pointer inside is zeroed at the end of a 3271 // request (in handlerDone) and calls on the responseWriter thereafter 3272 // simply crash (caller's mistake), but the much larger responseWriterState 3273 // and buffers are reused between multiple requests. 3274 type http2responseWriter struct { 3275 rws *http2responseWriterState 3276 } 3277 3278 // Optional http.ResponseWriter interfaces implemented. 3279 var ( 3280 _ CloseNotifier = (*http2responseWriter)(nil) 3281 _ Flusher = (*http2responseWriter)(nil) 3282 _ http2stringWriter = (*http2responseWriter)(nil) 3283 ) 3284 3285 type http2responseWriterState struct { 3286 // immutable within a request: 3287 stream *http2stream 3288 req *Request 3289 body *http2requestBody // to close at end of request, if DATA frames didn't 3290 conn *http2serverConn 3291 3292 // TODO: adjust buffer writing sizes based on server config, frame size updates from peer, etc 3293 bw *bufio.Writer // writing to a chunkWriter{this *responseWriterState} 3294 3295 // mutated by http.Handler goroutine: 3296 handlerHeader Header // nil until called 3297 snapHeader Header // snapshot of handlerHeader at WriteHeader time 3298 status int // status code passed to WriteHeader 3299 wroteHeader bool // WriteHeader called (explicitly or implicitly). Not necessarily sent to user yet. 3300 sentHeader bool // have we sent the header frame? 3301 handlerDone bool // handler has finished 3302 3303 closeNotifierMu sync.Mutex // guards closeNotifierCh 3304 closeNotifierCh chan bool // nil until first used 3305 } 3306 3307 type http2chunkWriter struct{ rws *http2responseWriterState } 3308 3309 func (cw http2chunkWriter) Write(p []byte) (n int, err error) { return cw.rws.writeChunk(p) } 3310 3311 // writeChunk writes chunks from the bufio.Writer. But because 3312 // bufio.Writer may bypass its chunking, sometimes p may be 3313 // arbitrarily large. 3314 // 3315 // writeChunk is also responsible (on the first chunk) for sending the 3316 // HEADER response. 3317 func (rws *http2responseWriterState) writeChunk(p []byte) (n int, err error) { 3318 if !rws.wroteHeader { 3319 rws.writeHeader(200) 3320 } 3321 if !rws.sentHeader { 3322 rws.sentHeader = true 3323 var ctype, clen string // implicit ones, if we can calculate it 3324 if rws.handlerDone && rws.snapHeader.Get("Content-Length") == "" { 3325 clen = strconv.Itoa(len(p)) 3326 } 3327 if rws.snapHeader.Get("Content-Type") == "" { 3328 ctype = DetectContentType(p) 3329 } 3330 endStream := rws.handlerDone && len(p) == 0 3331 err = rws.conn.writeHeaders(rws.stream, &http2writeResHeaders{ 3332 streamID: rws.stream.id, 3333 httpResCode: rws.status, 3334 h: rws.snapHeader, 3335 endStream: endStream, 3336 contentType: ctype, 3337 contentLength: clen, 3338 }) 3339 if err != nil { 3340 return 0, err 3341 } 3342 if endStream { 3343 return 0, nil 3344 } 3345 } 3346 if len(p) == 0 && !rws.handlerDone { 3347 return 0, nil 3348 } 3349 3350 if err := rws.conn.writeDataFromHandler(rws.stream, p, rws.handlerDone); err != nil { 3351 return 0, err 3352 } 3353 return len(p), nil 3354 } 3355 3356 func (w *http2responseWriter) Flush() { 3357 rws := w.rws 3358 if rws == nil { 3359 panic("Header called after Handler finished") 3360 } 3361 if rws.bw.Buffered() > 0 { 3362 if err := rws.bw.Flush(); err != nil { 3363 3364 return 3365 } 3366 } else { 3367 3368 rws.writeChunk(nil) 3369 } 3370 } 3371 3372 func (w *http2responseWriter) CloseNotify() <-chan bool { 3373 rws := w.rws 3374 if rws == nil { 3375 panic("CloseNotify called after Handler finished") 3376 } 3377 rws.closeNotifierMu.Lock() 3378 ch := rws.closeNotifierCh 3379 if ch == nil { 3380 ch = make(chan bool, 1) 3381 rws.closeNotifierCh = ch 3382 go func() { 3383 rws.stream.cw.Wait() 3384 ch <- true 3385 }() 3386 } 3387 rws.closeNotifierMu.Unlock() 3388 return ch 3389 } 3390 3391 func (w *http2responseWriter) Header() Header { 3392 rws := w.rws 3393 if rws == nil { 3394 panic("Header called after Handler finished") 3395 } 3396 if rws.handlerHeader == nil { 3397 rws.handlerHeader = make(Header) 3398 } 3399 return rws.handlerHeader 3400 } 3401 3402 func (w *http2responseWriter) WriteHeader(code int) { 3403 rws := w.rws 3404 if rws == nil { 3405 panic("WriteHeader called after Handler finished") 3406 } 3407 rws.writeHeader(code) 3408 } 3409 3410 func (rws *http2responseWriterState) writeHeader(code int) { 3411 if !rws.wroteHeader { 3412 rws.wroteHeader = true 3413 rws.status = code 3414 if len(rws.handlerHeader) > 0 { 3415 rws.snapHeader = http2cloneHeader(rws.handlerHeader) 3416 } 3417 } 3418 } 3419 3420 func http2cloneHeader(h Header) Header { 3421 h2 := make(Header, len(h)) 3422 for k, vv := range h { 3423 vv2 := make([]string, len(vv)) 3424 copy(vv2, vv) 3425 h2[k] = vv2 3426 } 3427 return h2 3428 } 3429 3430 // The Life Of A Write is like this: 3431 // 3432 // * Handler calls w.Write or w.WriteString -> 3433 // * -> rws.bw (*bufio.Writer) -> 3434 // * (Handler migth call Flush) 3435 // * -> chunkWriter{rws} 3436 // * -> responseWriterState.writeChunk(p []byte) 3437 // * -> responseWriterState.writeChunk (most of the magic; see comment there) 3438 func (w *http2responseWriter) Write(p []byte) (n int, err error) { 3439 return w.write(len(p), p, "") 3440 } 3441 3442 func (w *http2responseWriter) WriteString(s string) (n int, err error) { 3443 return w.write(len(s), nil, s) 3444 } 3445 3446 // either dataB or dataS is non-zero. 3447 func (w *http2responseWriter) write(lenData int, dataB []byte, dataS string) (n int, err error) { 3448 rws := w.rws 3449 if rws == nil { 3450 panic("Write called after Handler finished") 3451 } 3452 if !rws.wroteHeader { 3453 w.WriteHeader(200) 3454 } 3455 if dataB != nil { 3456 return rws.bw.Write(dataB) 3457 } else { 3458 return rws.bw.WriteString(dataS) 3459 } 3460 } 3461 3462 func (w *http2responseWriter) handlerDone() { 3463 rws := w.rws 3464 if rws == nil { 3465 panic("handlerDone called twice") 3466 } 3467 rws.handlerDone = true 3468 w.Flush() 3469 w.rws = nil 3470 http2responseWriterStatePool.Put(rws) 3471 } 3472 3473 const ( 3474 // transportDefaultConnFlow is how many connection-level flow control 3475 // tokens we give the server at start-up, past the default 64k. 3476 http2transportDefaultConnFlow = 1 << 30 3477 3478 // transportDefaultStreamFlow is how many stream-level flow 3479 // control tokens we announce to the peer, and how many bytes 3480 // we buffer per stream. 3481 http2transportDefaultStreamFlow = 4 << 20 3482 3483 // transportDefaultStreamMinRefresh is the minimum number of bytes we'll send 3484 // a stream-level WINDOW_UPDATE for at a time. 3485 http2transportDefaultStreamMinRefresh = 4 << 10 3486 ) 3487 3488 // Transport is an HTTP/2 Transport. 3489 // 3490 // A Transport internally caches connections to servers. It is safe 3491 // for concurrent use by multiple goroutines. 3492 type http2Transport struct { 3493 // DialTLS specifies an optional dial function for creating 3494 // TLS connections for requests. 3495 // 3496 // If DialTLS is nil, tls.Dial is used. 3497 // 3498 // If the returned net.Conn has a ConnectionState method like tls.Conn, 3499 // it will be used to set http.Response.TLS. 3500 DialTLS func(network, addr string, cfg *tls.Config) (net.Conn, error) 3501 3502 // TLSClientConfig specifies the TLS configuration to use with 3503 // tls.Client. If nil, the default configuration is used. 3504 TLSClientConfig *tls.Config 3505 3506 // TODO: switch to RWMutex 3507 // TODO: add support for sharing conns based on cert names 3508 // (e.g. share conn for googleapis.com and appspot.com) 3509 connMu sync.Mutex 3510 conns map[string][]*http2clientConn // key is host:port 3511 } 3512 3513 // clientConn is the state of a single HTTP/2 client connection to an 3514 // HTTP/2 server. 3515 type http2clientConn struct { 3516 t *http2Transport 3517 tconn net.Conn 3518 tlsState *tls.ConnectionState 3519 connKey []string // key(s) this connection is cached in, in t.conns 3520 3521 // readLoop goroutine fields: 3522 readerDone chan struct{} // closed on error 3523 readerErr error // set before readerDone is closed 3524 3525 mu sync.Mutex // guards following 3526 cond *sync.Cond // hold mu; broadcast on flow/closed changes 3527 flow http2flow // our conn-level flow control quota (cs.flow is per stream) 3528 inflow http2flow // peer's conn-level flow control 3529 closed bool 3530 goAway *http2GoAwayFrame // if non-nil, the GoAwayFrame we received 3531 streams map[uint32]*http2clientStream // client-initiated 3532 nextStreamID uint32 3533 bw *bufio.Writer 3534 br *bufio.Reader 3535 fr *http2Framer 3536 // Settings from peer: 3537 maxFrameSize uint32 3538 maxConcurrentStreams uint32 3539 initialWindowSize uint32 3540 hbuf bytes.Buffer // HPACK encoder writes into this 3541 henc *hpack.Encoder 3542 freeBuf [][]byte 3543 3544 wmu sync.Mutex // held while writing; acquire AFTER wmu if holding both 3545 werr error // first write error that has occurred 3546 } 3547 3548 // clientStream is the state for a single HTTP/2 stream. One of these 3549 // is created for each Transport.RoundTrip call. 3550 type http2clientStream struct { 3551 cc *http2clientConn 3552 ID uint32 3553 resc chan http2resAndError 3554 bufPipe http2pipe // buffered pipe with the flow-controlled response payload 3555 3556 flow http2flow // guarded by cc.mu 3557 inflow http2flow // guarded by cc.mu 3558 3559 peerReset chan struct{} // closed on peer reset 3560 resetErr error // populated before peerReset is closed 3561 } 3562 3563 // checkReset reports any error sent in a RST_STREAM frame by the 3564 // server. 3565 func (cs *http2clientStream) checkReset() error { 3566 select { 3567 case <-cs.peerReset: 3568 return cs.resetErr 3569 default: 3570 return nil 3571 } 3572 } 3573 3574 type http2stickyErrWriter struct { 3575 w io.Writer 3576 err *error 3577 } 3578 3579 func (sew http2stickyErrWriter) Write(p []byte) (n int, err error) { 3580 if *sew.err != nil { 3581 return 0, *sew.err 3582 } 3583 n, err = sew.w.Write(p) 3584 *sew.err = err 3585 return 3586 } 3587 3588 func (t *http2Transport) RoundTrip(req *Request) (*Response, error) { 3589 if req.URL.Scheme != "https" { 3590 return nil, errors.New("http2: unsupported scheme") 3591 } 3592 3593 host, port, err := net.SplitHostPort(req.URL.Host) 3594 if err != nil { 3595 host = req.URL.Host 3596 port = "443" 3597 } 3598 3599 for { 3600 cc, err := t.getClientConn(host, port) 3601 if err != nil { 3602 return nil, err 3603 } 3604 res, err := cc.roundTrip(req) 3605 if http2shouldRetryRequest(err) { 3606 continue 3607 } 3608 if err != nil { 3609 return nil, err 3610 } 3611 return res, nil 3612 } 3613 } 3614 3615 // CloseIdleConnections closes any connections which were previously 3616 // connected from previous requests but are now sitting idle. 3617 // It does not interrupt any connections currently in use. 3618 func (t *http2Transport) CloseIdleConnections() { 3619 t.connMu.Lock() 3620 defer t.connMu.Unlock() 3621 for _, vv := range t.conns { 3622 for _, cc := range vv { 3623 cc.closeIfIdle() 3624 } 3625 } 3626 } 3627 3628 var http2errClientConnClosed = errors.New("http2: client conn is closed") 3629 3630 func http2shouldRetryRequest(err error) bool { 3631 3632 return err == http2errClientConnClosed 3633 } 3634 3635 func (t *http2Transport) removeClientConn(cc *http2clientConn) { 3636 t.connMu.Lock() 3637 defer t.connMu.Unlock() 3638 for _, key := range cc.connKey { 3639 vv, ok := t.conns[key] 3640 if !ok { 3641 continue 3642 } 3643 newList := http2filterOutClientConn(vv, cc) 3644 if len(newList) > 0 { 3645 t.conns[key] = newList 3646 } else { 3647 delete(t.conns, key) 3648 } 3649 } 3650 } 3651 3652 func http2filterOutClientConn(in []*http2clientConn, exclude *http2clientConn) []*http2clientConn { 3653 out := in[:0] 3654 for _, v := range in { 3655 if v != exclude { 3656 out = append(out, v) 3657 } 3658 } 3659 3660 if len(in) != len(out) { 3661 in[len(in)-1] = nil 3662 } 3663 return out 3664 } 3665 3666 // AddIdleConn adds c as an idle conn for Transport. 3667 // It assumes that c has not yet exchanged SETTINGS frames. 3668 // The addr maybe be either "host" or "host:port". 3669 func (t *http2Transport) AddIdleConn(addr string, c *tls.Conn) error { 3670 var key string 3671 _, _, err := net.SplitHostPort(addr) 3672 if err == nil { 3673 key = addr 3674 } else { 3675 key = addr + ":443" 3676 } 3677 cc, err := t.newClientConn(key, c) 3678 if err != nil { 3679 return err 3680 } 3681 3682 t.addConn(key, cc) 3683 return nil 3684 } 3685 3686 func (t *http2Transport) addConn(key string, cc *http2clientConn) { 3687 t.connMu.Lock() 3688 defer t.connMu.Unlock() 3689 if t.conns == nil { 3690 t.conns = make(map[string][]*http2clientConn) 3691 } 3692 t.conns[key] = append(t.conns[key], cc) 3693 } 3694 3695 func (t *http2Transport) getClientConn(host, port string) (*http2clientConn, error) { 3696 key := net.JoinHostPort(host, port) 3697 3698 t.connMu.Lock() 3699 for _, cc := range t.conns[key] { 3700 if cc.canTakeNewRequest() { 3701 t.connMu.Unlock() 3702 return cc, nil 3703 } 3704 } 3705 t.connMu.Unlock() 3706 3707 cc, err := t.dialClientConn(host, port, key) 3708 if err != nil { 3709 return nil, err 3710 } 3711 t.addConn(key, cc) 3712 return cc, nil 3713 } 3714 3715 func (t *http2Transport) dialClientConn(host, port, key string) (*http2clientConn, error) { 3716 tconn, err := t.dialTLS()("tcp", net.JoinHostPort(host, port), t.newTLSConfig(host)) 3717 if err != nil { 3718 return nil, err 3719 } 3720 return t.newClientConn(key, tconn) 3721 } 3722 3723 func (t *http2Transport) newTLSConfig(host string) *tls.Config { 3724 cfg := new(tls.Config) 3725 if t.TLSClientConfig != nil { 3726 *cfg = *t.TLSClientConfig 3727 } 3728 cfg.NextProtos = []string{http2NextProtoTLS} 3729 cfg.ServerName = host 3730 return cfg 3731 } 3732 3733 func (t *http2Transport) dialTLS() func(string, string, *tls.Config) (net.Conn, error) { 3734 if t.DialTLS != nil { 3735 return t.DialTLS 3736 } 3737 return t.dialTLSDefault 3738 } 3739 3740 func (t *http2Transport) dialTLSDefault(network, addr string, cfg *tls.Config) (net.Conn, error) { 3741 cn, err := tls.Dial(network, addr, cfg) 3742 if err != nil { 3743 return nil, err 3744 } 3745 if err := cn.Handshake(); err != nil { 3746 return nil, err 3747 } 3748 if !cfg.InsecureSkipVerify { 3749 if err := cn.VerifyHostname(cfg.ServerName); err != nil { 3750 return nil, err 3751 } 3752 } 3753 state := cn.ConnectionState() 3754 if p := state.NegotiatedProtocol; p != http2NextProtoTLS { 3755 return nil, fmt.Errorf("http2: unexpected ALPN protocol %q; want %q", p, http2NextProtoTLS) 3756 } 3757 if !state.NegotiatedProtocolIsMutual { 3758 return nil, errors.New("http2: could not negotiate protocol mutually") 3759 } 3760 return cn, nil 3761 } 3762 3763 func (t *http2Transport) newClientConn(key string, tconn net.Conn) (*http2clientConn, error) { 3764 if _, err := tconn.Write(http2clientPreface); err != nil { 3765 return nil, err 3766 } 3767 3768 cc := &http2clientConn{ 3769 t: t, 3770 tconn: tconn, 3771 connKey: []string{key}, 3772 readerDone: make(chan struct{}), 3773 nextStreamID: 1, 3774 maxFrameSize: 16 << 10, 3775 initialWindowSize: 65535, 3776 maxConcurrentStreams: 1000, 3777 streams: make(map[uint32]*http2clientStream), 3778 } 3779 cc.cond = sync.NewCond(&cc.mu) 3780 cc.flow.add(int32(http2initialWindowSize)) 3781 3782 cc.bw = bufio.NewWriter(http2stickyErrWriter{tconn, &cc.werr}) 3783 cc.br = bufio.NewReader(tconn) 3784 cc.fr = http2NewFramer(cc.bw, cc.br) 3785 cc.henc = hpack.NewEncoder(&cc.hbuf) 3786 3787 type connectionStater interface { 3788 ConnectionState() tls.ConnectionState 3789 } 3790 if cs, ok := tconn.(connectionStater); ok { 3791 state := cs.ConnectionState() 3792 cc.tlsState = &state 3793 } 3794 3795 cc.fr.WriteSettings( 3796 http2Setting{ID: http2SettingEnablePush, Val: 0}, 3797 http2Setting{ID: http2SettingInitialWindowSize, Val: http2transportDefaultStreamFlow}, 3798 ) 3799 cc.fr.WriteWindowUpdate(0, http2transportDefaultConnFlow) 3800 cc.inflow.add(http2transportDefaultConnFlow + http2initialWindowSize) 3801 cc.bw.Flush() 3802 if cc.werr != nil { 3803 return nil, cc.werr 3804 } 3805 3806 f, err := cc.fr.ReadFrame() 3807 if err != nil { 3808 return nil, err 3809 } 3810 sf, ok := f.(*http2SettingsFrame) 3811 if !ok { 3812 return nil, fmt.Errorf("expected settings frame, got: %T", f) 3813 } 3814 cc.fr.WriteSettingsAck() 3815 cc.bw.Flush() 3816 3817 sf.ForeachSetting(func(s http2Setting) error { 3818 switch s.ID { 3819 case http2SettingMaxFrameSize: 3820 cc.maxFrameSize = s.Val 3821 case http2SettingMaxConcurrentStreams: 3822 cc.maxConcurrentStreams = s.Val 3823 case http2SettingInitialWindowSize: 3824 cc.initialWindowSize = s.Val 3825 default: 3826 3827 t.vlogf("Unhandled Setting: %v", s) 3828 } 3829 return nil 3830 }) 3831 3832 go cc.readLoop() 3833 return cc, nil 3834 } 3835 3836 func (cc *http2clientConn) setGoAway(f *http2GoAwayFrame) { 3837 cc.mu.Lock() 3838 defer cc.mu.Unlock() 3839 cc.goAway = f 3840 } 3841 3842 func (cc *http2clientConn) canTakeNewRequest() bool { 3843 cc.mu.Lock() 3844 defer cc.mu.Unlock() 3845 return cc.goAway == nil && 3846 int64(len(cc.streams)+1) < int64(cc.maxConcurrentStreams) && 3847 cc.nextStreamID < 2147483647 3848 } 3849 3850 func (cc *http2clientConn) closeIfIdle() { 3851 cc.mu.Lock() 3852 if len(cc.streams) > 0 { 3853 cc.mu.Unlock() 3854 return 3855 } 3856 cc.closed = true 3857 3858 cc.mu.Unlock() 3859 3860 cc.tconn.Close() 3861 } 3862 3863 const http2maxAllocFrameSize = 512 << 10 3864 3865 // frameBuffer returns a scratch buffer suitable for writing DATA frames. 3866 // They're capped at the min of the peer's max frame size or 512KB 3867 // (kinda arbitrarily), but definitely capped so we don't allocate 4GB 3868 // bufers. 3869 func (cc *http2clientConn) frameScratchBuffer() []byte { 3870 cc.mu.Lock() 3871 size := cc.maxFrameSize 3872 if size > http2maxAllocFrameSize { 3873 size = http2maxAllocFrameSize 3874 } 3875 for i, buf := range cc.freeBuf { 3876 if len(buf) >= int(size) { 3877 cc.freeBuf[i] = nil 3878 cc.mu.Unlock() 3879 return buf[:size] 3880 } 3881 } 3882 cc.mu.Unlock() 3883 return make([]byte, size) 3884 } 3885 3886 func (cc *http2clientConn) putFrameScratchBuffer(buf []byte) { 3887 cc.mu.Lock() 3888 defer cc.mu.Unlock() 3889 const maxBufs = 4 // arbitrary; 4 concurrent requests per conn? investigate. 3890 if len(cc.freeBuf) < maxBufs { 3891 cc.freeBuf = append(cc.freeBuf, buf) 3892 return 3893 } 3894 for i, old := range cc.freeBuf { 3895 if old == nil { 3896 cc.freeBuf[i] = buf 3897 return 3898 } 3899 } 3900 3901 } 3902 3903 func (cc *http2clientConn) roundTrip(req *Request) (*Response, error) { 3904 cc.mu.Lock() 3905 3906 if cc.closed { 3907 cc.mu.Unlock() 3908 return nil, http2errClientConnClosed 3909 } 3910 3911 cs := cc.newStream() 3912 hasBody := req.Body != nil 3913 3914 hdrs := cc.encodeHeaders(req) 3915 first := true 3916 3917 cc.wmu.Lock() 3918 frameSize := int(cc.maxFrameSize) 3919 for len(hdrs) > 0 && cc.werr == nil { 3920 chunk := hdrs 3921 if len(chunk) > frameSize { 3922 chunk = chunk[:frameSize] 3923 } 3924 hdrs = hdrs[len(chunk):] 3925 endHeaders := len(hdrs) == 0 3926 if first { 3927 cc.fr.WriteHeaders(http2HeadersFrameParam{ 3928 StreamID: cs.ID, 3929 BlockFragment: chunk, 3930 EndStream: !hasBody, 3931 EndHeaders: endHeaders, 3932 }) 3933 first = false 3934 } else { 3935 cc.fr.WriteContinuation(cs.ID, endHeaders, chunk) 3936 } 3937 } 3938 cc.bw.Flush() 3939 werr := cc.werr 3940 cc.wmu.Unlock() 3941 cc.mu.Unlock() 3942 3943 if werr != nil { 3944 return nil, werr 3945 } 3946 3947 var bodyCopyErrc chan error 3948 var gotResHeaders chan struct{} // closed on resheaders 3949 if hasBody { 3950 bodyCopyErrc = make(chan error, 1) 3951 gotResHeaders = make(chan struct{}) 3952 go func() { 3953 bodyCopyErrc <- cs.writeRequestBody(req.Body, gotResHeaders) 3954 }() 3955 } 3956 3957 for { 3958 select { 3959 case re := <-cs.resc: 3960 if gotResHeaders != nil { 3961 close(gotResHeaders) 3962 } 3963 if re.err != nil { 3964 return nil, re.err 3965 } 3966 res := re.res 3967 res.Request = req 3968 res.TLS = cc.tlsState 3969 return res, nil 3970 case err := <-bodyCopyErrc: 3971 if err != nil { 3972 return nil, err 3973 } 3974 } 3975 } 3976 } 3977 3978 var http2errServerResponseBeforeRequestBody = errors.New("http2: server sent response while still writing request body") 3979 3980 func (cs *http2clientStream) writeRequestBody(body io.Reader, gotResHeaders <-chan struct{}) error { 3981 cc := cs.cc 3982 sentEnd := false 3983 buf := cc.frameScratchBuffer() 3984 defer cc.putFrameScratchBuffer(buf) 3985 3986 for !sentEnd { 3987 var sawEOF bool 3988 n, err := io.ReadFull(body, buf) 3989 if err == io.ErrUnexpectedEOF { 3990 sawEOF = true 3991 err = nil 3992 } else if err == io.EOF { 3993 break 3994 } else if err != nil { 3995 return err 3996 } 3997 3998 toWrite := buf[:n] 3999 for len(toWrite) > 0 && err == nil { 4000 var allowed int32 4001 allowed, err = cs.awaitFlowControl(int32(len(toWrite))) 4002 if err != nil { 4003 return err 4004 } 4005 4006 cc.wmu.Lock() 4007 select { 4008 case <-gotResHeaders: 4009 err = http2errServerResponseBeforeRequestBody 4010 case <-cs.peerReset: 4011 err = cs.resetErr 4012 default: 4013 data := toWrite[:allowed] 4014 toWrite = toWrite[allowed:] 4015 sentEnd = sawEOF && len(toWrite) == 0 4016 err = cc.fr.WriteData(cs.ID, sentEnd, data) 4017 } 4018 cc.wmu.Unlock() 4019 } 4020 if err != nil { 4021 return err 4022 } 4023 } 4024 4025 var err error 4026 4027 cc.wmu.Lock() 4028 if !sentEnd { 4029 err = cc.fr.WriteData(cs.ID, true, nil) 4030 } 4031 if ferr := cc.bw.Flush(); ferr != nil && err == nil { 4032 err = ferr 4033 } 4034 cc.wmu.Unlock() 4035 4036 return err 4037 } 4038 4039 // awaitFlowControl waits for [1, min(maxBytes, cc.cs.maxFrameSize)] flow 4040 // control tokens from the server. 4041 // It returns either the non-zero number of tokens taken or an error 4042 // if the stream is dead. 4043 func (cs *http2clientStream) awaitFlowControl(maxBytes int32) (taken int32, err error) { 4044 cc := cs.cc 4045 cc.mu.Lock() 4046 defer cc.mu.Unlock() 4047 for { 4048 if cc.closed { 4049 return 0, http2errClientConnClosed 4050 } 4051 if err := cs.checkReset(); err != nil { 4052 return 0, err 4053 } 4054 if a := cs.flow.available(); a > 0 { 4055 take := a 4056 if take > maxBytes { 4057 take = maxBytes 4058 } 4059 if take > int32(cc.maxFrameSize) { 4060 take = int32(cc.maxFrameSize) 4061 } 4062 cs.flow.take(take) 4063 return take, nil 4064 } 4065 cc.cond.Wait() 4066 } 4067 } 4068 4069 // requires cc.mu be held. 4070 func (cc *http2clientConn) encodeHeaders(req *Request) []byte { 4071 cc.hbuf.Reset() 4072 4073 host := req.Host 4074 if host == "" { 4075 host = req.URL.Host 4076 } 4077 4078 cc.writeHeader(":authority", host) 4079 cc.writeHeader(":method", req.Method) 4080 cc.writeHeader(":path", req.URL.RequestURI()) 4081 cc.writeHeader(":scheme", "https") 4082 4083 for k, vv := range req.Header { 4084 lowKey := strings.ToLower(k) 4085 if lowKey == "host" { 4086 continue 4087 } 4088 for _, v := range vv { 4089 cc.writeHeader(lowKey, v) 4090 } 4091 } 4092 return cc.hbuf.Bytes() 4093 } 4094 4095 func (cc *http2clientConn) writeHeader(name, value string) { 4096 cc.henc.WriteField(hpack.HeaderField{Name: name, Value: value}) 4097 } 4098 4099 type http2resAndError struct { 4100 res *Response 4101 err error 4102 } 4103 4104 // requires cc.mu be held. 4105 func (cc *http2clientConn) newStream() *http2clientStream { 4106 cs := &http2clientStream{ 4107 cc: cc, 4108 ID: cc.nextStreamID, 4109 resc: make(chan http2resAndError, 1), 4110 peerReset: make(chan struct{}), 4111 } 4112 cs.flow.add(int32(cc.initialWindowSize)) 4113 cs.flow.setConnFlow(&cc.flow) 4114 cs.inflow.add(http2transportDefaultStreamFlow) 4115 cs.inflow.setConnFlow(&cc.inflow) 4116 cc.nextStreamID += 2 4117 cc.streams[cs.ID] = cs 4118 return cs 4119 } 4120 4121 func (cc *http2clientConn) streamByID(id uint32, andRemove bool) *http2clientStream { 4122 cc.mu.Lock() 4123 defer cc.mu.Unlock() 4124 cs := cc.streams[id] 4125 if andRemove { 4126 delete(cc.streams, id) 4127 } 4128 return cs 4129 } 4130 4131 // clientConnReadLoop is the state owned by the clientConn's frame-reading readLoop. 4132 type http2clientConnReadLoop struct { 4133 cc *http2clientConn 4134 activeRes map[uint32]*http2clientStream // keyed by streamID 4135 4136 // continueStreamID is the stream ID we're waiting for 4137 // continuation frames for. 4138 continueStreamID uint32 4139 4140 hdec *hpack.Decoder 4141 4142 // Fields reset on each HEADERS: 4143 nextRes *Response 4144 sawRegHeader bool // saw non-pseudo header 4145 reqMalformed error // non-nil once known to be malformed 4146 } 4147 4148 // readLoop runs in its own goroutine and reads and dispatches frames. 4149 func (cc *http2clientConn) readLoop() { 4150 rl := &http2clientConnReadLoop{ 4151 cc: cc, 4152 activeRes: make(map[uint32]*http2clientStream), 4153 } 4154 4155 rl.hdec = hpack.NewDecoder(http2initialHeaderTableSize, rl.onNewHeaderField) 4156 4157 defer rl.cleanup() 4158 cc.readerErr = rl.run() 4159 if ce, ok := cc.readerErr.(http2ConnectionError); ok { 4160 cc.wmu.Lock() 4161 cc.fr.WriteGoAway(0, http2ErrCode(ce), nil) 4162 cc.wmu.Unlock() 4163 } 4164 } 4165 4166 func (rl *http2clientConnReadLoop) cleanup() { 4167 cc := rl.cc 4168 defer cc.tconn.Close() 4169 defer cc.t.removeClientConn(cc) 4170 defer close(cc.readerDone) 4171 4172 err := cc.readerErr 4173 if err == io.EOF { 4174 err = io.ErrUnexpectedEOF 4175 } 4176 cc.mu.Lock() 4177 for _, cs := range rl.activeRes { 4178 cs.bufPipe.CloseWithError(err) 4179 } 4180 for _, cs := range cc.streams { 4181 select { 4182 case cs.resc <- http2resAndError{err: err}: 4183 default: 4184 } 4185 } 4186 cc.closed = true 4187 cc.cond.Broadcast() 4188 cc.mu.Unlock() 4189 } 4190 4191 func (rl *http2clientConnReadLoop) run() error { 4192 cc := rl.cc 4193 for { 4194 f, err := cc.fr.ReadFrame() 4195 if se, ok := err.(http2StreamError); ok { 4196 4197 return se 4198 } else if err != nil { 4199 return err 4200 } 4201 cc.vlogf("Transport received %v: %#v", f.Header(), f) 4202 4203 streamID := f.Header().StreamID 4204 4205 _, isContinue := f.(*http2ContinuationFrame) 4206 if isContinue { 4207 if streamID != rl.continueStreamID { 4208 cc.logf("Protocol violation: got CONTINUATION with id %d; want %d", streamID, rl.continueStreamID) 4209 return http2ConnectionError(http2ErrCodeProtocol) 4210 } 4211 } else if rl.continueStreamID != 0 { 4212 4213 cc.logf("Protocol violation: got %T for stream %d, want CONTINUATION for %d", f, streamID, rl.continueStreamID) 4214 return http2ConnectionError(http2ErrCodeProtocol) 4215 } 4216 4217 switch f := f.(type) { 4218 case *http2HeadersFrame: 4219 err = rl.processHeaders(f) 4220 case *http2ContinuationFrame: 4221 err = rl.processContinuation(f) 4222 case *http2DataFrame: 4223 err = rl.processData(f) 4224 case *http2GoAwayFrame: 4225 err = rl.processGoAway(f) 4226 case *http2RSTStreamFrame: 4227 err = rl.processResetStream(f) 4228 case *http2SettingsFrame: 4229 err = rl.processSettings(f) 4230 case *http2PushPromiseFrame: 4231 err = rl.processPushPromise(f) 4232 case *http2WindowUpdateFrame: 4233 err = rl.processWindowUpdate(f) 4234 default: 4235 cc.logf("Transport: unhandled response frame type %T", f) 4236 } 4237 if err != nil { 4238 return err 4239 } 4240 } 4241 } 4242 4243 func (rl *http2clientConnReadLoop) processHeaders(f *http2HeadersFrame) error { 4244 rl.sawRegHeader = false 4245 rl.reqMalformed = nil 4246 rl.nextRes = &Response{ 4247 Proto: "HTTP/2.0", 4248 ProtoMajor: 2, 4249 Header: make(Header), 4250 } 4251 return rl.processHeaderBlockFragment(f.HeaderBlockFragment(), f.StreamID, f.HeadersEnded(), f.StreamEnded()) 4252 } 4253 4254 func (rl *http2clientConnReadLoop) processContinuation(f *http2ContinuationFrame) error { 4255 return rl.processHeaderBlockFragment(f.HeaderBlockFragment(), f.StreamID, f.HeadersEnded(), f.StreamEnded()) 4256 } 4257 4258 func (rl *http2clientConnReadLoop) processHeaderBlockFragment(frag []byte, streamID uint32, headersEnded, streamEnded bool) error { 4259 cc := rl.cc 4260 cs := cc.streamByID(streamID, streamEnded) 4261 if cs == nil { 4262 4263 return nil 4264 } 4265 _, err := rl.hdec.Write(frag) 4266 if err != nil { 4267 return err 4268 } 4269 if !headersEnded { 4270 rl.continueStreamID = cs.ID 4271 return nil 4272 } 4273 4274 rl.continueStreamID = 0 4275 4276 if rl.reqMalformed != nil { 4277 cs.resc <- http2resAndError{err: rl.reqMalformed} 4278 rl.cc.writeStreamReset(cs.ID, http2ErrCodeProtocol, rl.reqMalformed) 4279 return nil 4280 } 4281 4282 res := rl.nextRes 4283 if streamEnded { 4284 res.Body = http2noBody 4285 } else { 4286 buf := new(bytes.Buffer) 4287 cs.bufPipe = http2pipe{b: buf} 4288 res.Body = http2transportResponseBody{cs} 4289 } 4290 rl.activeRes[cs.ID] = cs 4291 cs.resc <- http2resAndError{res: res} 4292 rl.nextRes = nil 4293 return nil 4294 } 4295 4296 // transportResponseBody is the concrete type of Transport.RoundTrip's 4297 // Response.Body. It is an io.ReadCloser. On Read, it reads from cs.body. 4298 // On Close it sends RST_STREAM if EOF wasn't already seen. 4299 type http2transportResponseBody struct { 4300 cs *http2clientStream 4301 } 4302 4303 func (b http2transportResponseBody) Read(p []byte) (n int, err error) { 4304 n, err = b.cs.bufPipe.Read(p) 4305 if n == 0 { 4306 return 4307 } 4308 4309 cs := b.cs 4310 cc := cs.cc 4311 cc.mu.Lock() 4312 defer cc.mu.Unlock() 4313 4314 var connAdd, streamAdd int32 4315 4316 if v := cc.inflow.available(); v < http2transportDefaultConnFlow/2 { 4317 connAdd = http2transportDefaultConnFlow - v 4318 cc.inflow.add(connAdd) 4319 } 4320 if err == nil { 4321 if v := cs.inflow.available(); v < http2transportDefaultStreamFlow-http2transportDefaultStreamMinRefresh { 4322 streamAdd = http2transportDefaultStreamFlow - v 4323 cs.inflow.add(streamAdd) 4324 } 4325 } 4326 if connAdd != 0 || streamAdd != 0 { 4327 cc.wmu.Lock() 4328 defer cc.wmu.Unlock() 4329 if connAdd != 0 { 4330 cc.fr.WriteWindowUpdate(0, http2mustUint31(connAdd)) 4331 } 4332 if streamAdd != 0 { 4333 cc.fr.WriteWindowUpdate(cs.ID, http2mustUint31(streamAdd)) 4334 } 4335 cc.bw.Flush() 4336 } 4337 return 4338 } 4339 4340 func (b http2transportResponseBody) Close() error { 4341 if b.cs.bufPipe.Err() != io.EOF { 4342 4343 b.cs.cc.writeStreamReset(b.cs.ID, http2ErrCodeCancel, nil) 4344 } 4345 return nil 4346 } 4347 4348 func (rl *http2clientConnReadLoop) processData(f *http2DataFrame) error { 4349 cc := rl.cc 4350 cs := cc.streamByID(f.StreamID, f.StreamEnded()) 4351 if cs == nil { 4352 return nil 4353 } 4354 data := f.Data() 4355 if http2VerboseLogs { 4356 rl.cc.logf("DATA: %q", data) 4357 } 4358 4359 cc.mu.Lock() 4360 if cs.inflow.available() >= int32(len(data)) { 4361 cs.inflow.take(int32(len(data))) 4362 } else { 4363 cc.mu.Unlock() 4364 return http2ConnectionError(http2ErrCodeFlowControl) 4365 } 4366 cc.mu.Unlock() 4367 4368 if _, err := cs.bufPipe.Write(data); err != nil { 4369 return err 4370 } 4371 4372 if f.StreamEnded() { 4373 cs.bufPipe.CloseWithError(io.EOF) 4374 delete(rl.activeRes, cs.ID) 4375 } 4376 return nil 4377 } 4378 4379 func (rl *http2clientConnReadLoop) processGoAway(f *http2GoAwayFrame) error { 4380 cc := rl.cc 4381 cc.t.removeClientConn(cc) 4382 if f.ErrCode != 0 { 4383 4384 cc.vlogf("transport got GOAWAY with error code = %v", f.ErrCode) 4385 } 4386 cc.setGoAway(f) 4387 return nil 4388 } 4389 4390 func (rl *http2clientConnReadLoop) processSettings(f *http2SettingsFrame) error { 4391 cc := rl.cc 4392 cc.mu.Lock() 4393 defer cc.mu.Unlock() 4394 return f.ForeachSetting(func(s http2Setting) error { 4395 switch s.ID { 4396 case http2SettingMaxFrameSize: 4397 cc.maxFrameSize = s.Val 4398 case http2SettingMaxConcurrentStreams: 4399 cc.maxConcurrentStreams = s.Val 4400 case http2SettingInitialWindowSize: 4401 4402 cc.initialWindowSize = s.Val 4403 default: 4404 4405 cc.vlogf("Unhandled Setting: %v", s) 4406 } 4407 return nil 4408 }) 4409 } 4410 4411 func (rl *http2clientConnReadLoop) processWindowUpdate(f *http2WindowUpdateFrame) error { 4412 cc := rl.cc 4413 cs := cc.streamByID(f.StreamID, false) 4414 if f.StreamID != 0 && cs == nil { 4415 return nil 4416 } 4417 4418 cc.mu.Lock() 4419 defer cc.mu.Unlock() 4420 4421 fl := &cc.flow 4422 if cs != nil { 4423 fl = &cs.flow 4424 } 4425 if !fl.add(int32(f.Increment)) { 4426 return http2ConnectionError(http2ErrCodeFlowControl) 4427 } 4428 cc.cond.Broadcast() 4429 return nil 4430 } 4431 4432 func (rl *http2clientConnReadLoop) processResetStream(f *http2RSTStreamFrame) error { 4433 cs := rl.cc.streamByID(f.StreamID, true) 4434 if cs == nil { 4435 4436 return nil 4437 } 4438 select { 4439 case <-cs.peerReset: 4440 4441 default: 4442 err := http2StreamError{cs.ID, f.ErrCode} 4443 cs.resetErr = err 4444 close(cs.peerReset) 4445 cs.bufPipe.CloseWithError(err) 4446 } 4447 delete(rl.activeRes, cs.ID) 4448 return nil 4449 } 4450 4451 func (rl *http2clientConnReadLoop) processPushPromise(f *http2PushPromiseFrame) error { 4452 4453 return http2ConnectionError(http2ErrCodeProtocol) 4454 } 4455 4456 func (cc *http2clientConn) writeStreamReset(streamID uint32, code http2ErrCode, err error) { 4457 4458 cc.wmu.Lock() 4459 cc.fr.WriteRSTStream(streamID, code) 4460 cc.wmu.Unlock() 4461 } 4462 4463 // onNewHeaderField runs on the readLoop goroutine whenever a new 4464 // hpack header field is decoded. 4465 func (rl *http2clientConnReadLoop) onNewHeaderField(f hpack.HeaderField) { 4466 cc := rl.cc 4467 if http2VerboseLogs { 4468 cc.logf("Header field: %+v", f) 4469 } 4470 isPseudo := strings.HasPrefix(f.Name, ":") 4471 if isPseudo { 4472 if rl.sawRegHeader { 4473 rl.reqMalformed = errors.New("http2: invalid pseudo header after regular header") 4474 return 4475 } 4476 switch f.Name { 4477 case ":status": 4478 code, err := strconv.Atoi(f.Value) 4479 if err != nil { 4480 rl.reqMalformed = errors.New("http2: invalid :status") 4481 return 4482 } 4483 rl.nextRes.Status = f.Value + " " + StatusText(code) 4484 rl.nextRes.StatusCode = code 4485 default: 4486 4487 rl.reqMalformed = fmt.Errorf("http2: unknown response pseudo header %q", f.Name) 4488 } 4489 } else { 4490 rl.sawRegHeader = true 4491 rl.nextRes.Header.Add(CanonicalHeaderKey(f.Name), f.Value) 4492 } 4493 } 4494 4495 func (cc *http2clientConn) logf(format string, args ...interface{}) { 4496 cc.t.logf(format, args...) 4497 } 4498 4499 func (cc *http2clientConn) vlogf(format string, args ...interface{}) { 4500 cc.t.vlogf(format, args...) 4501 } 4502 4503 func (t *http2Transport) vlogf(format string, args ...interface{}) { 4504 if http2VerboseLogs { 4505 t.logf(format, args...) 4506 } 4507 } 4508 4509 func (t *http2Transport) logf(format string, args ...interface{}) { 4510 log.Printf(format, args...) 4511 } 4512 4513 var http2noBody io.ReadCloser = ioutil.NopCloser(bytes.NewReader(nil)) 4514 4515 // writeFramer is implemented by any type that is used to write frames. 4516 type http2writeFramer interface { 4517 writeFrame(http2writeContext) error 4518 } 4519 4520 // writeContext is the interface needed by the various frame writer 4521 // types below. All the writeFrame methods below are scheduled via the 4522 // frame writing scheduler (see writeScheduler in writesched.go). 4523 // 4524 // This interface is implemented by *serverConn. 4525 // TODO: use it from the client code too, once it exists. 4526 type http2writeContext interface { 4527 Framer() *http2Framer 4528 Flush() error 4529 CloseConn() error 4530 // HeaderEncoder returns an HPACK encoder that writes to the 4531 // returned buffer. 4532 HeaderEncoder() (*hpack.Encoder, *bytes.Buffer) 4533 } 4534 4535 // endsStream reports whether the given frame writer w will locally 4536 // close the stream. 4537 func http2endsStream(w http2writeFramer) bool { 4538 switch v := w.(type) { 4539 case *http2writeData: 4540 return v.endStream 4541 case *http2writeResHeaders: 4542 return v.endStream 4543 case nil: 4544 4545 panic("endsStream called on nil writeFramer") 4546 } 4547 return false 4548 } 4549 4550 type http2flushFrameWriter struct{} 4551 4552 func (http2flushFrameWriter) writeFrame(ctx http2writeContext) error { 4553 return ctx.Flush() 4554 } 4555 4556 type http2writeSettings []http2Setting 4557 4558 func (s http2writeSettings) writeFrame(ctx http2writeContext) error { 4559 return ctx.Framer().WriteSettings([]http2Setting(s)...) 4560 } 4561 4562 type http2writeGoAway struct { 4563 maxStreamID uint32 4564 code http2ErrCode 4565 } 4566 4567 func (p *http2writeGoAway) writeFrame(ctx http2writeContext) error { 4568 err := ctx.Framer().WriteGoAway(p.maxStreamID, p.code, nil) 4569 if p.code != 0 { 4570 ctx.Flush() 4571 time.Sleep(50 * time.Millisecond) 4572 ctx.CloseConn() 4573 } 4574 return err 4575 } 4576 4577 type http2writeData struct { 4578 streamID uint32 4579 p []byte 4580 endStream bool 4581 } 4582 4583 func (w *http2writeData) String() string { 4584 return fmt.Sprintf("writeData(stream=%d, p=%d, endStream=%v)", w.streamID, len(w.p), w.endStream) 4585 } 4586 4587 func (w *http2writeData) writeFrame(ctx http2writeContext) error { 4588 return ctx.Framer().WriteData(w.streamID, w.endStream, w.p) 4589 } 4590 4591 func (se http2StreamError) writeFrame(ctx http2writeContext) error { 4592 return ctx.Framer().WriteRSTStream(se.StreamID, se.Code) 4593 } 4594 4595 type http2writePingAck struct{ pf *http2PingFrame } 4596 4597 func (w http2writePingAck) writeFrame(ctx http2writeContext) error { 4598 return ctx.Framer().WritePing(true, w.pf.Data) 4599 } 4600 4601 type http2writeSettingsAck struct{} 4602 4603 func (http2writeSettingsAck) writeFrame(ctx http2writeContext) error { 4604 return ctx.Framer().WriteSettingsAck() 4605 } 4606 4607 // writeResHeaders is a request to write a HEADERS and 0+ CONTINUATION frames 4608 // for HTTP response headers from a server handler. 4609 type http2writeResHeaders struct { 4610 streamID uint32 4611 httpResCode int 4612 h Header // may be nil 4613 endStream bool 4614 4615 contentType string 4616 contentLength string 4617 } 4618 4619 func (w *http2writeResHeaders) writeFrame(ctx http2writeContext) error { 4620 enc, buf := ctx.HeaderEncoder() 4621 buf.Reset() 4622 enc.WriteField(hpack.HeaderField{Name: ":status", Value: http2httpCodeString(w.httpResCode)}) 4623 for k, vv := range w.h { 4624 k = http2lowerHeader(k) 4625 for _, v := range vv { 4626 4627 if k == "transfer-encoding" && v != "trailers" { 4628 continue 4629 } 4630 enc.WriteField(hpack.HeaderField{Name: k, Value: v}) 4631 } 4632 } 4633 if w.contentType != "" { 4634 enc.WriteField(hpack.HeaderField{Name: "content-type", Value: w.contentType}) 4635 } 4636 if w.contentLength != "" { 4637 enc.WriteField(hpack.HeaderField{Name: "content-length", Value: w.contentLength}) 4638 } 4639 4640 headerBlock := buf.Bytes() 4641 if len(headerBlock) == 0 { 4642 panic("unexpected empty hpack") 4643 } 4644 4645 // For now we're lazy and just pick the minimum MAX_FRAME_SIZE 4646 // that all peers must support (16KB). Later we could care 4647 // more and send larger frames if the peer advertised it, but 4648 // there's little point. Most headers are small anyway (so we 4649 // generally won't have CONTINUATION frames), and extra frames 4650 // only waste 9 bytes anyway. 4651 const maxFrameSize = 16384 4652 4653 first := true 4654 for len(headerBlock) > 0 { 4655 frag := headerBlock 4656 if len(frag) > maxFrameSize { 4657 frag = frag[:maxFrameSize] 4658 } 4659 headerBlock = headerBlock[len(frag):] 4660 endHeaders := len(headerBlock) == 0 4661 var err error 4662 if first { 4663 first = false 4664 err = ctx.Framer().WriteHeaders(http2HeadersFrameParam{ 4665 StreamID: w.streamID, 4666 BlockFragment: frag, 4667 EndStream: w.endStream, 4668 EndHeaders: endHeaders, 4669 }) 4670 } else { 4671 err = ctx.Framer().WriteContinuation(w.streamID, endHeaders, frag) 4672 } 4673 if err != nil { 4674 return err 4675 } 4676 } 4677 return nil 4678 } 4679 4680 type http2write100ContinueHeadersFrame struct { 4681 streamID uint32 4682 } 4683 4684 func (w http2write100ContinueHeadersFrame) writeFrame(ctx http2writeContext) error { 4685 enc, buf := ctx.HeaderEncoder() 4686 buf.Reset() 4687 enc.WriteField(hpack.HeaderField{Name: ":status", Value: "100"}) 4688 return ctx.Framer().WriteHeaders(http2HeadersFrameParam{ 4689 StreamID: w.streamID, 4690 BlockFragment: buf.Bytes(), 4691 EndStream: false, 4692 EndHeaders: true, 4693 }) 4694 } 4695 4696 type http2writeWindowUpdate struct { 4697 streamID uint32 // or 0 for conn-level 4698 n uint32 4699 } 4700 4701 func (wu http2writeWindowUpdate) writeFrame(ctx http2writeContext) error { 4702 return ctx.Framer().WriteWindowUpdate(wu.streamID, wu.n) 4703 } 4704 4705 // frameWriteMsg is a request to write a frame. 4706 type http2frameWriteMsg struct { 4707 // write is the interface value that does the writing, once the 4708 // writeScheduler (below) has decided to select this frame 4709 // to write. The write functions are all defined in write.go. 4710 write http2writeFramer 4711 4712 stream *http2stream // used for prioritization. nil for non-stream frames. 4713 4714 // done, if non-nil, must be a buffered channel with space for 4715 // 1 message and is sent the return value from write (or an 4716 // earlier error) when the frame has been written. 4717 done chan error 4718 } 4719 4720 // for debugging only: 4721 func (wm http2frameWriteMsg) String() string { 4722 var streamID uint32 4723 if wm.stream != nil { 4724 streamID = wm.stream.id 4725 } 4726 var des string 4727 if s, ok := wm.write.(fmt.Stringer); ok { 4728 des = s.String() 4729 } else { 4730 des = fmt.Sprintf("%T", wm.write) 4731 } 4732 return fmt.Sprintf("[frameWriteMsg stream=%d, ch=%v, type: %v]", streamID, wm.done != nil, des) 4733 } 4734 4735 // writeScheduler tracks pending frames to write, priorities, and decides 4736 // the next one to use. It is not thread-safe. 4737 type http2writeScheduler struct { 4738 // zero are frames not associated with a specific stream. 4739 // They're sent before any stream-specific freams. 4740 zero http2writeQueue 4741 4742 // maxFrameSize is the maximum size of a DATA frame 4743 // we'll write. Must be non-zero and between 16K-16M. 4744 maxFrameSize uint32 4745 4746 // sq contains the stream-specific queues, keyed by stream ID. 4747 // when a stream is idle, it's deleted from the map. 4748 sq map[uint32]*http2writeQueue 4749 4750 // canSend is a slice of memory that's reused between frame 4751 // scheduling decisions to hold the list of writeQueues (from sq) 4752 // which have enough flow control data to send. After canSend is 4753 // built, the best is selected. 4754 canSend []*http2writeQueue 4755 4756 // pool of empty queues for reuse. 4757 queuePool []*http2writeQueue 4758 } 4759 4760 func (ws *http2writeScheduler) putEmptyQueue(q *http2writeQueue) { 4761 if len(q.s) != 0 { 4762 panic("queue must be empty") 4763 } 4764 ws.queuePool = append(ws.queuePool, q) 4765 } 4766 4767 func (ws *http2writeScheduler) getEmptyQueue() *http2writeQueue { 4768 ln := len(ws.queuePool) 4769 if ln == 0 { 4770 return new(http2writeQueue) 4771 } 4772 q := ws.queuePool[ln-1] 4773 ws.queuePool = ws.queuePool[:ln-1] 4774 return q 4775 } 4776 4777 func (ws *http2writeScheduler) empty() bool { return ws.zero.empty() && len(ws.sq) == 0 } 4778 4779 func (ws *http2writeScheduler) add(wm http2frameWriteMsg) { 4780 st := wm.stream 4781 if st == nil { 4782 ws.zero.push(wm) 4783 } else { 4784 ws.streamQueue(st.id).push(wm) 4785 } 4786 } 4787 4788 func (ws *http2writeScheduler) streamQueue(streamID uint32) *http2writeQueue { 4789 if q, ok := ws.sq[streamID]; ok { 4790 return q 4791 } 4792 if ws.sq == nil { 4793 ws.sq = make(map[uint32]*http2writeQueue) 4794 } 4795 q := ws.getEmptyQueue() 4796 ws.sq[streamID] = q 4797 return q 4798 } 4799 4800 // take returns the most important frame to write and removes it from the scheduler. 4801 // It is illegal to call this if the scheduler is empty or if there are no connection-level 4802 // flow control bytes available. 4803 func (ws *http2writeScheduler) take() (wm http2frameWriteMsg, ok bool) { 4804 if ws.maxFrameSize == 0 { 4805 panic("internal error: ws.maxFrameSize not initialized or invalid") 4806 } 4807 4808 if !ws.zero.empty() { 4809 return ws.zero.shift(), true 4810 } 4811 if len(ws.sq) == 0 { 4812 return 4813 } 4814 4815 for id, q := range ws.sq { 4816 if q.firstIsNoCost() { 4817 return ws.takeFrom(id, q) 4818 } 4819 } 4820 4821 if len(ws.canSend) != 0 { 4822 panic("should be empty") 4823 } 4824 for _, q := range ws.sq { 4825 if n := ws.streamWritableBytes(q); n > 0 { 4826 ws.canSend = append(ws.canSend, q) 4827 } 4828 } 4829 if len(ws.canSend) == 0 { 4830 return 4831 } 4832 defer ws.zeroCanSend() 4833 4834 q := ws.canSend[0] 4835 4836 return ws.takeFrom(q.streamID(), q) 4837 } 4838 4839 // zeroCanSend is defered from take. 4840 func (ws *http2writeScheduler) zeroCanSend() { 4841 for i := range ws.canSend { 4842 ws.canSend[i] = nil 4843 } 4844 ws.canSend = ws.canSend[:0] 4845 } 4846 4847 // streamWritableBytes returns the number of DATA bytes we could write 4848 // from the given queue's stream, if this stream/queue were 4849 // selected. It is an error to call this if q's head isn't a 4850 // *writeData. 4851 func (ws *http2writeScheduler) streamWritableBytes(q *http2writeQueue) int32 { 4852 wm := q.head() 4853 ret := wm.stream.flow.available() 4854 if ret == 0 { 4855 return 0 4856 } 4857 if int32(ws.maxFrameSize) < ret { 4858 ret = int32(ws.maxFrameSize) 4859 } 4860 if ret == 0 { 4861 panic("internal error: ws.maxFrameSize not initialized or invalid") 4862 } 4863 wd := wm.write.(*http2writeData) 4864 if len(wd.p) < int(ret) { 4865 ret = int32(len(wd.p)) 4866 } 4867 return ret 4868 } 4869 4870 func (ws *http2writeScheduler) takeFrom(id uint32, q *http2writeQueue) (wm http2frameWriteMsg, ok bool) { 4871 wm = q.head() 4872 4873 if wd, ok := wm.write.(*http2writeData); ok && len(wd.p) > 0 { 4874 allowed := wm.stream.flow.available() 4875 if allowed == 0 { 4876 4877 return http2frameWriteMsg{}, false 4878 } 4879 if int32(ws.maxFrameSize) < allowed { 4880 allowed = int32(ws.maxFrameSize) 4881 } 4882 4883 if len(wd.p) > int(allowed) { 4884 wm.stream.flow.take(allowed) 4885 chunk := wd.p[:allowed] 4886 wd.p = wd.p[allowed:] 4887 4888 return http2frameWriteMsg{ 4889 stream: wm.stream, 4890 write: &http2writeData{ 4891 streamID: wd.streamID, 4892 p: chunk, 4893 4894 endStream: false, 4895 }, 4896 4897 done: nil, 4898 }, true 4899 } 4900 wm.stream.flow.take(int32(len(wd.p))) 4901 } 4902 4903 q.shift() 4904 if q.empty() { 4905 ws.putEmptyQueue(q) 4906 delete(ws.sq, id) 4907 } 4908 return wm, true 4909 } 4910 4911 func (ws *http2writeScheduler) forgetStream(id uint32) { 4912 q, ok := ws.sq[id] 4913 if !ok { 4914 return 4915 } 4916 delete(ws.sq, id) 4917 4918 for i := range q.s { 4919 q.s[i] = http2frameWriteMsg{} 4920 } 4921 q.s = q.s[:0] 4922 ws.putEmptyQueue(q) 4923 } 4924 4925 type http2writeQueue struct { 4926 s []http2frameWriteMsg 4927 } 4928 4929 // streamID returns the stream ID for a non-empty stream-specific queue. 4930 func (q *http2writeQueue) streamID() uint32 { return q.s[0].stream.id } 4931 4932 func (q *http2writeQueue) empty() bool { return len(q.s) == 0 } 4933 4934 func (q *http2writeQueue) push(wm http2frameWriteMsg) { 4935 q.s = append(q.s, wm) 4936 } 4937 4938 // head returns the next item that would be removed by shift. 4939 func (q *http2writeQueue) head() http2frameWriteMsg { 4940 if len(q.s) == 0 { 4941 panic("invalid use of queue") 4942 } 4943 return q.s[0] 4944 } 4945 4946 func (q *http2writeQueue) shift() http2frameWriteMsg { 4947 if len(q.s) == 0 { 4948 panic("invalid use of queue") 4949 } 4950 wm := q.s[0] 4951 4952 copy(q.s, q.s[1:]) 4953 q.s[len(q.s)-1] = http2frameWriteMsg{} 4954 q.s = q.s[:len(q.s)-1] 4955 return wm 4956 } 4957 4958 func (q *http2writeQueue) firstIsNoCost() bool { 4959 if df, ok := q.s[0].write.(*http2writeData); ok { 4960 return len(df.p) == 0 4961 } 4962 return true 4963 }