github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/net/http2/transport.go (about)

     1  // Copyright 2015 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Transport code.
     6  
     7  package http2
     8  
     9  import (
    10  	"bufio"
    11  	"bytes"
    12  	"compress/gzip"
    13  	"crypto/tls"
    14  	"errors"
    15  	"fmt"
    16  	"io"
    17  	"io/ioutil"
    18  	"log"
    19  	"net"
    20  	"net/http"
    21  	"sort"
    22  	"strconv"
    23  	"strings"
    24  	"sync"
    25  
    26  	"golang.org/x/net/http2/hpack"
    27  )
    28  
    29  const (
    30  	// transportDefaultConnFlow is how many connection-level flow control
    31  	// tokens we give the server at start-up, past the default 64k.
    32  	transportDefaultConnFlow = 1 << 30
    33  
    34  	// transportDefaultStreamFlow is how many stream-level flow
    35  	// control tokens we announce to the peer, and how many bytes
    36  	// we buffer per stream.
    37  	transportDefaultStreamFlow = 4 << 20
    38  
    39  	// transportDefaultStreamMinRefresh is the minimum number of bytes we'll send
    40  	// a stream-level WINDOW_UPDATE for at a time.
    41  	transportDefaultStreamMinRefresh = 4 << 10
    42  
    43  	defaultUserAgent = "Go-http-client/2.0"
    44  )
    45  
    46  // Transport is an HTTP/2 Transport.
    47  //
    48  // A Transport internally caches connections to servers. It is safe
    49  // for concurrent use by multiple goroutines.
    50  type Transport struct {
    51  	// DialTLS specifies an optional dial function for creating
    52  	// TLS connections for requests.
    53  	//
    54  	// If DialTLS is nil, tls.Dial is used.
    55  	//
    56  	// If the returned net.Conn has a ConnectionState method like tls.Conn,
    57  	// it will be used to set http.Response.TLS.
    58  	DialTLS func(network, addr string, cfg *tls.Config) (net.Conn, error)
    59  
    60  	// TLSClientConfig specifies the TLS configuration to use with
    61  	// tls.Client. If nil, the default configuration is used.
    62  	TLSClientConfig *tls.Config
    63  
    64  	// ConnPool optionally specifies an alternate connection pool to use.
    65  	// If nil, the default is used.
    66  	ConnPool ClientConnPool
    67  
    68  	// DisableCompression, if true, prevents the Transport from
    69  	// requesting compression with an "Accept-Encoding: gzip"
    70  	// request header when the Request contains no existing
    71  	// Accept-Encoding value. If the Transport requests gzip on
    72  	// its own and gets a gzipped response, it's transparently
    73  	// decoded in the Response.Body. However, if the user
    74  	// explicitly requested gzip it is not automatically
    75  	// uncompressed.
    76  	DisableCompression bool
    77  
    78  	connPoolOnce  sync.Once
    79  	connPoolOrDef ClientConnPool // non-nil version of ConnPool
    80  }
    81  
    82  func (t *Transport) disableCompression() bool {
    83  	if t.DisableCompression {
    84  		return true
    85  	}
    86  	// TODO: also disable if this transport is somehow linked to an http1 Transport
    87  	// and it's configured there?
    88  	return false
    89  }
    90  
    91  var errTransportVersion = errors.New("http2: ConfigureTransport is only supported starting at Go 1.6")
    92  
    93  // ConfigureTransport configures a net/http HTTP/1 Transport to use HTTP/2.
    94  // It requires Go 1.6 or later and returns an error if the net/http package is too old
    95  // or if t1 has already been HTTP/2-enabled.
    96  func ConfigureTransport(t1 *http.Transport) error {
    97  	return configureTransport(t1) // in configure_transport.go (go1.6) or go15.go
    98  }
    99  
   100  func (t *Transport) connPool() ClientConnPool {
   101  	t.connPoolOnce.Do(t.initConnPool)
   102  	return t.connPoolOrDef
   103  }
   104  
   105  func (t *Transport) initConnPool() {
   106  	if t.ConnPool != nil {
   107  		t.connPoolOrDef = t.ConnPool
   108  	} else {
   109  		t.connPoolOrDef = &clientConnPool{t: t}
   110  	}
   111  }
   112  
   113  // ClientConn is the state of a single HTTP/2 client connection to an
   114  // HTTP/2 server.
   115  type ClientConn struct {
   116  	t        *Transport
   117  	tconn    net.Conn             // usually *tls.Conn, except specialized impls
   118  	tlsState *tls.ConnectionState // nil only for specialized impls
   119  
   120  	// readLoop goroutine fields:
   121  	readerDone chan struct{} // closed on error
   122  	readerErr  error         // set before readerDone is closed
   123  
   124  	mu           sync.Mutex // guards following
   125  	cond         *sync.Cond // hold mu; broadcast on flow/closed changes
   126  	flow         flow       // our conn-level flow control quota (cs.flow is per stream)
   127  	inflow       flow       // peer's conn-level flow control
   128  	closed       bool
   129  	goAway       *GoAwayFrame             // if non-nil, the GoAwayFrame we received
   130  	streams      map[uint32]*clientStream // client-initiated
   131  	nextStreamID uint32
   132  	bw           *bufio.Writer
   133  	br           *bufio.Reader
   134  	fr           *Framer
   135  	// Settings from peer:
   136  	maxFrameSize         uint32
   137  	maxConcurrentStreams uint32
   138  	initialWindowSize    uint32
   139  	hbuf                 bytes.Buffer // HPACK encoder writes into this
   140  	henc                 *hpack.Encoder
   141  	freeBuf              [][]byte
   142  
   143  	wmu  sync.Mutex // held while writing; acquire AFTER wmu if holding both
   144  	werr error      // first write error that has occurred
   145  }
   146  
   147  // clientStream is the state for a single HTTP/2 stream. One of these
   148  // is created for each Transport.RoundTrip call.
   149  type clientStream struct {
   150  	cc            *ClientConn
   151  	req           *http.Request
   152  	ID            uint32
   153  	resc          chan resAndError
   154  	bufPipe       pipe // buffered pipe with the flow-controlled response payload
   155  	requestedGzip bool
   156  
   157  	flow        flow  // guarded by cc.mu
   158  	inflow      flow  // guarded by cc.mu
   159  	bytesRemain int64 // -1 means unknown; owned by transportResponseBody.Read
   160  	readErr     error // sticky read error; owned by transportResponseBody.Read
   161  	stopReqBody bool  // stop writing req body; guarded by cc.mu
   162  
   163  	peerReset chan struct{} // closed on peer reset
   164  	resetErr  error         // populated before peerReset is closed
   165  
   166  	done chan struct{} // closed when stream remove from cc.streams map; close calls guarded by cc.mu
   167  
   168  	// owned by clientConnReadLoop:
   169  	headersDone  bool // got HEADERS w/ END_HEADERS
   170  	trailersDone bool // got second HEADERS frame w/ END_HEADERS
   171  
   172  	trailer    http.Header // accumulated trailers
   173  	resTrailer http.Header // client's Response.Trailer
   174  }
   175  
   176  // awaitRequestCancel runs in its own goroutine and waits for the user
   177  // to either cancel a RoundTrip request (using the provided
   178  // Request.Cancel channel), or for the request to be done (any way it
   179  // might be removed from the cc.streams map: peer reset, successful
   180  // completion, TCP connection breakage, etc)
   181  func (cs *clientStream) awaitRequestCancel(cancel <-chan struct{}) {
   182  	if cancel == nil {
   183  		return
   184  	}
   185  	select {
   186  	case <-cancel:
   187  		cs.bufPipe.CloseWithError(errRequestCanceled)
   188  		cs.cc.writeStreamReset(cs.ID, ErrCodeCancel, nil)
   189  	case <-cs.done:
   190  	}
   191  }
   192  
   193  // checkReset reports any error sent in a RST_STREAM frame by the
   194  // server.
   195  func (cs *clientStream) checkReset() error {
   196  	select {
   197  	case <-cs.peerReset:
   198  		return cs.resetErr
   199  	default:
   200  		return nil
   201  	}
   202  }
   203  
   204  func (cs *clientStream) abortRequestBodyWrite() {
   205  	cc := cs.cc
   206  	cc.mu.Lock()
   207  	cs.stopReqBody = true
   208  	cc.cond.Broadcast()
   209  	cc.mu.Unlock()
   210  }
   211  
   212  type stickyErrWriter struct {
   213  	w   io.Writer
   214  	err *error
   215  }
   216  
   217  func (sew stickyErrWriter) Write(p []byte) (n int, err error) {
   218  	if *sew.err != nil {
   219  		return 0, *sew.err
   220  	}
   221  	n, err = sew.w.Write(p)
   222  	*sew.err = err
   223  	return
   224  }
   225  
   226  var ErrNoCachedConn = errors.New("http2: no cached connection was available")
   227  
   228  // RoundTripOpt are options for the Transport.RoundTripOpt method.
   229  type RoundTripOpt struct {
   230  	// OnlyCachedConn controls whether RoundTripOpt may
   231  	// create a new TCP connection. If set true and
   232  	// no cached connection is available, RoundTripOpt
   233  	// will return ErrNoCachedConn.
   234  	OnlyCachedConn bool
   235  }
   236  
   237  func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
   238  	return t.RoundTripOpt(req, RoundTripOpt{})
   239  }
   240  
   241  // authorityAddr returns a given authority (a host/IP, or host:port / ip:port)
   242  // and returns a host:port. The port 443 is added if needed.
   243  func authorityAddr(authority string) (addr string) {
   244  	if _, _, err := net.SplitHostPort(authority); err == nil {
   245  		return authority
   246  	}
   247  	return net.JoinHostPort(authority, "443")
   248  }
   249  
   250  // RoundTripOpt is like RoundTrip, but takes options.
   251  func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Response, error) {
   252  	if req.URL.Scheme != "https" {
   253  		return nil, errors.New("http2: unsupported scheme")
   254  	}
   255  
   256  	addr := authorityAddr(req.URL.Host)
   257  	for {
   258  		cc, err := t.connPool().GetClientConn(req, addr)
   259  		if err != nil {
   260  			t.vlogf("failed to get client conn: %v", err)
   261  			return nil, err
   262  		}
   263  		res, err := cc.RoundTrip(req)
   264  		if shouldRetryRequest(req, err) {
   265  			continue
   266  		}
   267  		if err != nil {
   268  			t.vlogf("RoundTrip failure: %v", err)
   269  			return nil, err
   270  		}
   271  		return res, nil
   272  	}
   273  }
   274  
   275  // CloseIdleConnections closes any connections which were previously
   276  // connected from previous requests but are now sitting idle.
   277  // It does not interrupt any connections currently in use.
   278  func (t *Transport) CloseIdleConnections() {
   279  	if cp, ok := t.connPool().(*clientConnPool); ok {
   280  		cp.closeIdleConnections()
   281  	}
   282  }
   283  
   284  var (
   285  	errClientConnClosed   = errors.New("http2: client conn is closed")
   286  	errClientConnUnusable = errors.New("http2: client conn not usable")
   287  )
   288  
   289  func shouldRetryRequest(req *http.Request, err error) bool {
   290  	// TODO: retry GET requests (no bodies) more aggressively, if shutdown
   291  	// before response.
   292  	return err == errClientConnUnusable
   293  }
   294  
   295  func (t *Transport) dialClientConn(addr string) (*ClientConn, error) {
   296  	host, _, err := net.SplitHostPort(addr)
   297  	if err != nil {
   298  		return nil, err
   299  	}
   300  	tconn, err := t.dialTLS()("tcp", addr, t.newTLSConfig(host))
   301  	if err != nil {
   302  		return nil, err
   303  	}
   304  	return t.NewClientConn(tconn)
   305  }
   306  
   307  func (t *Transport) newTLSConfig(host string) *tls.Config {
   308  	cfg := new(tls.Config)
   309  	if t.TLSClientConfig != nil {
   310  		*cfg = *t.TLSClientConfig
   311  	}
   312  	cfg.NextProtos = []string{NextProtoTLS} // TODO: don't override if already in list
   313  	cfg.ServerName = host
   314  	return cfg
   315  }
   316  
   317  func (t *Transport) dialTLS() func(string, string, *tls.Config) (net.Conn, error) {
   318  	if t.DialTLS != nil {
   319  		return t.DialTLS
   320  	}
   321  	return t.dialTLSDefault
   322  }
   323  
   324  func (t *Transport) dialTLSDefault(network, addr string, cfg *tls.Config) (net.Conn, error) {
   325  	cn, err := tls.Dial(network, addr, cfg)
   326  	if err != nil {
   327  		return nil, err
   328  	}
   329  	if err := cn.Handshake(); err != nil {
   330  		return nil, err
   331  	}
   332  	if !cfg.InsecureSkipVerify {
   333  		if err := cn.VerifyHostname(cfg.ServerName); err != nil {
   334  			return nil, err
   335  		}
   336  	}
   337  	state := cn.ConnectionState()
   338  	if p := state.NegotiatedProtocol; p != NextProtoTLS {
   339  		return nil, fmt.Errorf("http2: unexpected ALPN protocol %q; want %q", p, NextProtoTLS)
   340  	}
   341  	if !state.NegotiatedProtocolIsMutual {
   342  		return nil, errors.New("http2: could not negotiate protocol mutually")
   343  	}
   344  	return cn, nil
   345  }
   346  
   347  func (t *Transport) NewClientConn(c net.Conn) (*ClientConn, error) {
   348  	if VerboseLogs {
   349  		t.vlogf("creating client conn to %v", c.RemoteAddr())
   350  	}
   351  	if _, err := c.Write(clientPreface); err != nil {
   352  		t.vlogf("client preface write error: %v", err)
   353  		return nil, err
   354  	}
   355  
   356  	cc := &ClientConn{
   357  		t:                    t,
   358  		tconn:                c,
   359  		readerDone:           make(chan struct{}),
   360  		nextStreamID:         1,
   361  		maxFrameSize:         16 << 10, // spec default
   362  		initialWindowSize:    65535,    // spec default
   363  		maxConcurrentStreams: 1000,     // "infinite", per spec. 1000 seems good enough.
   364  		streams:              make(map[uint32]*clientStream),
   365  	}
   366  	cc.cond = sync.NewCond(&cc.mu)
   367  	cc.flow.add(int32(initialWindowSize))
   368  
   369  	// TODO: adjust this writer size to account for frame size +
   370  	// MTU + crypto/tls record padding.
   371  	cc.bw = bufio.NewWriter(stickyErrWriter{c, &cc.werr})
   372  	cc.br = bufio.NewReader(c)
   373  	cc.fr = NewFramer(cc.bw, cc.br)
   374  	cc.henc = hpack.NewEncoder(&cc.hbuf)
   375  
   376  	type connectionStater interface {
   377  		ConnectionState() tls.ConnectionState
   378  	}
   379  	if cs, ok := c.(connectionStater); ok {
   380  		state := cs.ConnectionState()
   381  		cc.tlsState = &state
   382  	}
   383  
   384  	cc.fr.WriteSettings(
   385  		Setting{ID: SettingEnablePush, Val: 0},
   386  		Setting{ID: SettingInitialWindowSize, Val: transportDefaultStreamFlow},
   387  	)
   388  	cc.fr.WriteWindowUpdate(0, transportDefaultConnFlow)
   389  	cc.inflow.add(transportDefaultConnFlow + initialWindowSize)
   390  	cc.bw.Flush()
   391  	if cc.werr != nil {
   392  		return nil, cc.werr
   393  	}
   394  
   395  	// Read the obligatory SETTINGS frame
   396  	f, err := cc.fr.ReadFrame()
   397  	if err != nil {
   398  		return nil, err
   399  	}
   400  	sf, ok := f.(*SettingsFrame)
   401  	if !ok {
   402  		return nil, fmt.Errorf("expected settings frame, got: %T", f)
   403  	}
   404  	cc.fr.WriteSettingsAck()
   405  	cc.bw.Flush()
   406  
   407  	sf.ForeachSetting(func(s Setting) error {
   408  		switch s.ID {
   409  		case SettingMaxFrameSize:
   410  			cc.maxFrameSize = s.Val
   411  		case SettingMaxConcurrentStreams:
   412  			cc.maxConcurrentStreams = s.Val
   413  		case SettingInitialWindowSize:
   414  			cc.initialWindowSize = s.Val
   415  		default:
   416  			// TODO(bradfitz): handle more
   417  			t.vlogf("Unhandled Setting: %v", s)
   418  		}
   419  		return nil
   420  	})
   421  
   422  	go cc.readLoop()
   423  	return cc, nil
   424  }
   425  
   426  func (cc *ClientConn) setGoAway(f *GoAwayFrame) {
   427  	cc.mu.Lock()
   428  	defer cc.mu.Unlock()
   429  	cc.goAway = f
   430  }
   431  
   432  func (cc *ClientConn) CanTakeNewRequest() bool {
   433  	cc.mu.Lock()
   434  	defer cc.mu.Unlock()
   435  	return cc.canTakeNewRequestLocked()
   436  }
   437  
   438  func (cc *ClientConn) canTakeNewRequestLocked() bool {
   439  	return cc.goAway == nil &&
   440  		int64(len(cc.streams)+1) < int64(cc.maxConcurrentStreams) &&
   441  		cc.nextStreamID < 2147483647
   442  }
   443  
   444  func (cc *ClientConn) closeIfIdle() {
   445  	cc.mu.Lock()
   446  	if len(cc.streams) > 0 {
   447  		cc.mu.Unlock()
   448  		return
   449  	}
   450  	cc.closed = true
   451  	// TODO: do clients send GOAWAY too? maybe? Just Close:
   452  	cc.mu.Unlock()
   453  
   454  	cc.tconn.Close()
   455  }
   456  
   457  const maxAllocFrameSize = 512 << 10
   458  
   459  // frameBuffer returns a scratch buffer suitable for writing DATA frames.
   460  // They're capped at the min of the peer's max frame size or 512KB
   461  // (kinda arbitrarily), but definitely capped so we don't allocate 4GB
   462  // bufers.
   463  func (cc *ClientConn) frameScratchBuffer() []byte {
   464  	cc.mu.Lock()
   465  	size := cc.maxFrameSize
   466  	if size > maxAllocFrameSize {
   467  		size = maxAllocFrameSize
   468  	}
   469  	for i, buf := range cc.freeBuf {
   470  		if len(buf) >= int(size) {
   471  			cc.freeBuf[i] = nil
   472  			cc.mu.Unlock()
   473  			return buf[:size]
   474  		}
   475  	}
   476  	cc.mu.Unlock()
   477  	return make([]byte, size)
   478  }
   479  
   480  func (cc *ClientConn) putFrameScratchBuffer(buf []byte) {
   481  	cc.mu.Lock()
   482  	defer cc.mu.Unlock()
   483  	const maxBufs = 4 // arbitrary; 4 concurrent requests per conn? investigate.
   484  	if len(cc.freeBuf) < maxBufs {
   485  		cc.freeBuf = append(cc.freeBuf, buf)
   486  		return
   487  	}
   488  	for i, old := range cc.freeBuf {
   489  		if old == nil {
   490  			cc.freeBuf[i] = buf
   491  			return
   492  		}
   493  	}
   494  	// forget about it.
   495  }
   496  
   497  // errRequestCanceled is a copy of net/http's errRequestCanceled because it's not
   498  // exported. At least they'll be DeepEqual for h1-vs-h2 comparisons tests.
   499  var errRequestCanceled = errors.New("net/http: request canceled")
   500  
   501  func commaSeparatedTrailers(req *http.Request) (string, error) {
   502  	keys := make([]string, 0, len(req.Trailer))
   503  	for k := range req.Trailer {
   504  		k = http.CanonicalHeaderKey(k)
   505  		switch k {
   506  		case "Transfer-Encoding", "Trailer", "Content-Length":
   507  			return "", &badStringError{"invalid Trailer key", k}
   508  		}
   509  		keys = append(keys, k)
   510  	}
   511  	if len(keys) > 0 {
   512  		sort.Strings(keys)
   513  		// TODO: could do better allocation-wise here, but trailers are rare,
   514  		// so being lazy for now.
   515  		return strings.Join(keys, ","), nil
   516  	}
   517  	return "", nil
   518  }
   519  
   520  func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) {
   521  	trailers, err := commaSeparatedTrailers(req)
   522  	if err != nil {
   523  		return nil, err
   524  	}
   525  	hasTrailers := trailers != ""
   526  
   527  	cc.mu.Lock()
   528  	if cc.closed || !cc.canTakeNewRequestLocked() {
   529  		cc.mu.Unlock()
   530  		return nil, errClientConnUnusable
   531  	}
   532  
   533  	cs := cc.newStream()
   534  	cs.req = req
   535  	hasBody := req.Body != nil
   536  
   537  	// TODO(bradfitz): this is a copy of the logic in net/http. Unify somewhere?
   538  	if !cc.t.disableCompression() &&
   539  		req.Header.Get("Accept-Encoding") == "" &&
   540  		req.Header.Get("Range") == "" &&
   541  		req.Method != "HEAD" {
   542  		// Request gzip only, not deflate. Deflate is ambiguous and
   543  		// not as universally supported anyway.
   544  		// See: http://www.gzip.org/zlib/zlib_faq.html#faq38
   545  		//
   546  		// Note that we don't request this for HEAD requests,
   547  		// due to a bug in nginx:
   548  		//   http://trac.nginx.org/nginx/ticket/358
   549  		//   https://golang.org/issue/5522
   550  		//
   551  		// We don't request gzip if the request is for a range, since
   552  		// auto-decoding a portion of a gzipped document will just fail
   553  		// anyway. See https://golang.org/issue/8923
   554  		cs.requestedGzip = true
   555  	}
   556  
   557  	// we send: HEADERS{1}, CONTINUATION{0,} + DATA{0,} (DATA is
   558  	// sent by writeRequestBody below, along with any Trailers,
   559  	// again in form HEADERS{1}, CONTINUATION{0,})
   560  	hdrs := cc.encodeHeaders(req, cs.requestedGzip, trailers)
   561  	cc.wmu.Lock()
   562  	endStream := !hasBody && !hasTrailers
   563  	werr := cc.writeHeaders(cs.ID, endStream, hdrs)
   564  	cc.wmu.Unlock()
   565  	cc.mu.Unlock()
   566  
   567  	if werr != nil {
   568  		if hasBody {
   569  			req.Body.Close() // per RoundTripper contract
   570  		}
   571  		cc.forgetStreamID(cs.ID)
   572  		// Don't bother sending a RST_STREAM (our write already failed;
   573  		// no need to keep writing)
   574  		return nil, werr
   575  	}
   576  
   577  	var bodyCopyErrc chan error // result of body copy
   578  	if hasBody {
   579  		bodyCopyErrc = make(chan error, 1)
   580  		go func() {
   581  			bodyCopyErrc <- cs.writeRequestBody(req.Body)
   582  		}()
   583  	}
   584  
   585  	readLoopResCh := cs.resc
   586  	requestCanceledCh := requestCancel(req)
   587  	requestCanceled := false
   588  	for {
   589  		select {
   590  		case re := <-readLoopResCh:
   591  			res := re.res
   592  			if re.err != nil || res.StatusCode > 299 {
   593  				// On error or status code 3xx, 4xx, 5xx, etc abort any
   594  				// ongoing write, assuming that the server doesn't care
   595  				// about our request body. If the server replied with 1xx or
   596  				// 2xx, however, then assume the server DOES potentially
   597  				// want our body (e.g. full-duplex streaming:
   598  				// golang.org/issue/13444). If it turns out the server
   599  				// doesn't, they'll RST_STREAM us soon enough.  This is a
   600  				// heuristic to avoid adding knobs to Transport.  Hopefully
   601  				// we can keep it.
   602  				cs.abortRequestBodyWrite()
   603  			}
   604  			if re.err != nil {
   605  				cc.forgetStreamID(cs.ID)
   606  				return nil, re.err
   607  			}
   608  			res.Request = req
   609  			res.TLS = cc.tlsState
   610  			return res, nil
   611  		case <-requestCanceledCh:
   612  			cc.forgetStreamID(cs.ID)
   613  			cs.abortRequestBodyWrite()
   614  			if !hasBody {
   615  				cc.writeStreamReset(cs.ID, ErrCodeCancel, nil)
   616  				return nil, errRequestCanceled
   617  			}
   618  			// If we have a body, wait for the body write to be
   619  			// finished before sending the RST_STREAM frame.
   620  			requestCanceled = true
   621  			requestCanceledCh = nil // to prevent spins
   622  			readLoopResCh = nil     // ignore responses at this point
   623  		case <-cs.peerReset:
   624  			if requestCanceled {
   625  				// They hung up on us first. No need to write a RST_STREAM.
   626  				// But prioritize the request canceled error value, since
   627  				// it's likely related. (same spirit as http1 code)
   628  				return nil, errRequestCanceled
   629  			}
   630  			// processResetStream already removed the
   631  			// stream from the streams map; no need for
   632  			// forgetStreamID.
   633  			return nil, cs.resetErr
   634  		case err := <-bodyCopyErrc:
   635  			if requestCanceled {
   636  				cc.writeStreamReset(cs.ID, ErrCodeCancel, nil)
   637  				return nil, errRequestCanceled
   638  			}
   639  			if err != nil {
   640  				return nil, err
   641  			}
   642  		}
   643  	}
   644  }
   645  
   646  // requires cc.wmu be held
   647  func (cc *ClientConn) writeHeaders(streamID uint32, endStream bool, hdrs []byte) error {
   648  	first := true // first frame written (HEADERS is first, then CONTINUATION)
   649  	frameSize := int(cc.maxFrameSize)
   650  	for len(hdrs) > 0 && cc.werr == nil {
   651  		chunk := hdrs
   652  		if len(chunk) > frameSize {
   653  			chunk = chunk[:frameSize]
   654  		}
   655  		hdrs = hdrs[len(chunk):]
   656  		endHeaders := len(hdrs) == 0
   657  		if first {
   658  			cc.fr.WriteHeaders(HeadersFrameParam{
   659  				StreamID:      streamID,
   660  				BlockFragment: chunk,
   661  				EndStream:     endStream,
   662  				EndHeaders:    endHeaders,
   663  			})
   664  			first = false
   665  		} else {
   666  			cc.fr.WriteContinuation(streamID, endHeaders, chunk)
   667  		}
   668  	}
   669  	// TODO(bradfitz): this Flush could potentially block (as
   670  	// could the WriteHeaders call(s) above), which means they
   671  	// wouldn't respond to Request.Cancel being readable. That's
   672  	// rare, but this should probably be in a goroutine.
   673  	cc.bw.Flush()
   674  	return cc.werr
   675  }
   676  
   677  // errAbortReqBodyWrite is an internal error value.
   678  // It doesn't escape to callers.
   679  var errAbortReqBodyWrite = errors.New("http2: aborting request body write")
   680  
   681  func (cs *clientStream) writeRequestBody(body io.ReadCloser) (err error) {
   682  	cc := cs.cc
   683  	sentEnd := false // whether we sent the final DATA frame w/ END_STREAM
   684  	buf := cc.frameScratchBuffer()
   685  	defer cc.putFrameScratchBuffer(buf)
   686  
   687  	defer func() {
   688  		// TODO: write h12Compare test showing whether
   689  		// Request.Body is closed by the Transport,
   690  		// and in multiple cases: server replies <=299 and >299
   691  		// while still writing request body
   692  		cerr := body.Close()
   693  		if err == nil {
   694  			err = cerr
   695  		}
   696  	}()
   697  
   698  	req := cs.req
   699  	hasTrailers := req.Trailer != nil
   700  
   701  	var sawEOF bool
   702  	for !sawEOF {
   703  		n, err := body.Read(buf)
   704  		if err == io.EOF {
   705  			sawEOF = true
   706  			err = nil
   707  		} else if err != nil {
   708  			return err
   709  		}
   710  
   711  		remain := buf[:n]
   712  		for len(remain) > 0 && err == nil {
   713  			var allowed int32
   714  			allowed, err = cs.awaitFlowControl(len(remain))
   715  			if err != nil {
   716  				return err
   717  			}
   718  			cc.wmu.Lock()
   719  			data := remain[:allowed]
   720  			remain = remain[allowed:]
   721  			sentEnd = sawEOF && len(remain) == 0 && !hasTrailers
   722  			err = cc.fr.WriteData(cs.ID, sentEnd, data)
   723  			if err == nil {
   724  				// TODO(bradfitz): this flush is for latency, not bandwidth.
   725  				// Most requests won't need this. Make this opt-in or opt-out?
   726  				// Use some heuristic on the body type? Nagel-like timers?
   727  				// Based on 'n'? Only last chunk of this for loop, unless flow control
   728  				// tokens are low? For now, always:
   729  				err = cc.bw.Flush()
   730  			}
   731  			cc.wmu.Unlock()
   732  		}
   733  		if err != nil {
   734  			return err
   735  		}
   736  	}
   737  
   738  	cc.wmu.Lock()
   739  	if !sentEnd {
   740  		var trls []byte
   741  		if hasTrailers {
   742  			cc.mu.Lock()
   743  			trls = cc.encodeTrailers(req)
   744  			cc.mu.Unlock()
   745  		}
   746  
   747  		// Avoid forgetting to send an END_STREAM if the encoded
   748  		// trailers are 0 bytes. Both results produce and END_STREAM.
   749  		if len(trls) > 0 {
   750  			err = cc.writeHeaders(cs.ID, true, trls)
   751  		} else {
   752  			err = cc.fr.WriteData(cs.ID, true, nil)
   753  		}
   754  	}
   755  	if ferr := cc.bw.Flush(); ferr != nil && err == nil {
   756  		err = ferr
   757  	}
   758  	cc.wmu.Unlock()
   759  
   760  	return err
   761  }
   762  
   763  // awaitFlowControl waits for [1, min(maxBytes, cc.cs.maxFrameSize)] flow
   764  // control tokens from the server.
   765  // It returns either the non-zero number of tokens taken or an error
   766  // if the stream is dead.
   767  func (cs *clientStream) awaitFlowControl(maxBytes int) (taken int32, err error) {
   768  	cc := cs.cc
   769  	cc.mu.Lock()
   770  	defer cc.mu.Unlock()
   771  	for {
   772  		if cc.closed {
   773  			return 0, errClientConnClosed
   774  		}
   775  		if cs.stopReqBody {
   776  			return 0, errAbortReqBodyWrite
   777  		}
   778  		if err := cs.checkReset(); err != nil {
   779  			return 0, err
   780  		}
   781  		if a := cs.flow.available(); a > 0 {
   782  			take := a
   783  			if int(take) > maxBytes {
   784  
   785  				take = int32(maxBytes) // can't truncate int; take is int32
   786  			}
   787  			if take > int32(cc.maxFrameSize) {
   788  				take = int32(cc.maxFrameSize)
   789  			}
   790  			cs.flow.take(take)
   791  			return take, nil
   792  		}
   793  		cc.cond.Wait()
   794  	}
   795  }
   796  
   797  type badStringError struct {
   798  	what string
   799  	str  string
   800  }
   801  
   802  func (e *badStringError) Error() string { return fmt.Sprintf("%s %q", e.what, e.str) }
   803  
   804  // requires cc.mu be held.
   805  func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trailers string) []byte {
   806  	cc.hbuf.Reset()
   807  
   808  	// TODO(bradfitz): figure out :authority-vs-Host stuff between http2 and Go
   809  	host := req.Host
   810  	if host == "" {
   811  		host = req.URL.Host
   812  	}
   813  
   814  	// 8.1.2.3 Request Pseudo-Header Fields
   815  	// The :path pseudo-header field includes the path and query parts of the
   816  	// target URI (the path-absolute production and optionally a '?' character
   817  	// followed by the query production (see Sections 3.3 and 3.4 of
   818  	// [RFC3986]).
   819  	cc.writeHeader(":authority", host) // probably not right for all sites
   820  	cc.writeHeader(":method", req.Method)
   821  	if req.Method != "CONNECT" {
   822  		cc.writeHeader(":path", req.URL.RequestURI())
   823  		cc.writeHeader(":scheme", "https")
   824  	}
   825  	if trailers != "" {
   826  		cc.writeHeader("trailer", trailers)
   827  	}
   828  
   829  	var didUA bool
   830  	for k, vv := range req.Header {
   831  		lowKey := strings.ToLower(k)
   832  		if lowKey == "host" {
   833  			continue
   834  		}
   835  		if lowKey == "user-agent" {
   836  			// Match Go's http1 behavior: at most one
   837  			// User-Agent.  If set to nil or empty string,
   838  			// then omit it.  Otherwise if not mentioned,
   839  			// include the default (below).
   840  			didUA = true
   841  			if len(vv) < 1 {
   842  				continue
   843  			}
   844  			vv = vv[:1]
   845  			if vv[0] == "" {
   846  				continue
   847  			}
   848  		}
   849  		for _, v := range vv {
   850  			cc.writeHeader(lowKey, v)
   851  		}
   852  	}
   853  	if addGzipHeader {
   854  		cc.writeHeader("accept-encoding", "gzip")
   855  	}
   856  	if !didUA {
   857  		cc.writeHeader("user-agent", defaultUserAgent)
   858  	}
   859  	return cc.hbuf.Bytes()
   860  }
   861  
   862  // requires cc.mu be held.
   863  func (cc *ClientConn) encodeTrailers(req *http.Request) []byte {
   864  	cc.hbuf.Reset()
   865  	for k, vv := range req.Trailer {
   866  		// Transfer-Encoding, etc.. have already been filter at the
   867  		// start of RoundTrip
   868  		lowKey := strings.ToLower(k)
   869  		for _, v := range vv {
   870  			cc.writeHeader(lowKey, v)
   871  		}
   872  	}
   873  	return cc.hbuf.Bytes()
   874  }
   875  
   876  func (cc *ClientConn) writeHeader(name, value string) {
   877  	cc.henc.WriteField(hpack.HeaderField{Name: name, Value: value})
   878  }
   879  
   880  type resAndError struct {
   881  	res *http.Response
   882  	err error
   883  }
   884  
   885  // requires cc.mu be held.
   886  func (cc *ClientConn) newStream() *clientStream {
   887  	cs := &clientStream{
   888  		cc:        cc,
   889  		ID:        cc.nextStreamID,
   890  		resc:      make(chan resAndError, 1),
   891  		peerReset: make(chan struct{}),
   892  		done:      make(chan struct{}),
   893  	}
   894  	cs.flow.add(int32(cc.initialWindowSize))
   895  	cs.flow.setConnFlow(&cc.flow)
   896  	cs.inflow.add(transportDefaultStreamFlow)
   897  	cs.inflow.setConnFlow(&cc.inflow)
   898  	cc.nextStreamID += 2
   899  	cc.streams[cs.ID] = cs
   900  	return cs
   901  }
   902  
   903  func (cc *ClientConn) forgetStreamID(id uint32) {
   904  	cc.streamByID(id, true)
   905  }
   906  
   907  func (cc *ClientConn) streamByID(id uint32, andRemove bool) *clientStream {
   908  	cc.mu.Lock()
   909  	defer cc.mu.Unlock()
   910  	cs := cc.streams[id]
   911  	if andRemove && cs != nil {
   912  		delete(cc.streams, id)
   913  		close(cs.done)
   914  	}
   915  	return cs
   916  }
   917  
   918  // clientConnReadLoop is the state owned by the clientConn's frame-reading readLoop.
   919  type clientConnReadLoop struct {
   920  	cc        *ClientConn
   921  	activeRes map[uint32]*clientStream // keyed by streamID
   922  
   923  	hdec *hpack.Decoder
   924  
   925  	// Fields reset on each HEADERS:
   926  	nextRes      *http.Response
   927  	sawRegHeader bool  // saw non-pseudo header
   928  	reqMalformed error // non-nil once known to be malformed
   929  }
   930  
   931  // readLoop runs in its own goroutine and reads and dispatches frames.
   932  func (cc *ClientConn) readLoop() {
   933  	rl := &clientConnReadLoop{
   934  		cc:        cc,
   935  		activeRes: make(map[uint32]*clientStream),
   936  	}
   937  	// TODO: figure out henc size
   938  	rl.hdec = hpack.NewDecoder(initialHeaderTableSize, rl.onNewHeaderField)
   939  
   940  	defer rl.cleanup()
   941  	cc.readerErr = rl.run()
   942  	if ce, ok := cc.readerErr.(ConnectionError); ok {
   943  		cc.wmu.Lock()
   944  		cc.fr.WriteGoAway(0, ErrCode(ce), nil)
   945  		cc.wmu.Unlock()
   946  	}
   947  }
   948  
   949  func (rl *clientConnReadLoop) cleanup() {
   950  	cc := rl.cc
   951  	defer cc.tconn.Close()
   952  	defer cc.t.connPool().MarkDead(cc)
   953  	defer close(cc.readerDone)
   954  
   955  	// Close any response bodies if the server closes prematurely.
   956  	// TODO: also do this if we've written the headers but not
   957  	// gotten a response yet.
   958  	err := cc.readerErr
   959  	if err == io.EOF {
   960  		err = io.ErrUnexpectedEOF
   961  	}
   962  	cc.mu.Lock()
   963  	for _, cs := range rl.activeRes {
   964  		cs.bufPipe.CloseWithError(err)
   965  	}
   966  	for _, cs := range cc.streams {
   967  		select {
   968  		case cs.resc <- resAndError{err: err}:
   969  		default:
   970  		}
   971  		close(cs.done)
   972  	}
   973  	cc.closed = true
   974  	cc.cond.Broadcast()
   975  	cc.mu.Unlock()
   976  }
   977  
   978  func (rl *clientConnReadLoop) run() error {
   979  	cc := rl.cc
   980  	for {
   981  		f, err := cc.fr.ReadFrame()
   982  		if err != nil {
   983  			cc.vlogf("Transport readFrame error: (%T) %v", err, err)
   984  		}
   985  		if se, ok := err.(StreamError); ok {
   986  			// TODO: deal with stream errors from the framer.
   987  			return se
   988  		} else if err != nil {
   989  			return err
   990  		}
   991  		cc.vlogf("Transport received %v: %#v", f.Header(), f)
   992  
   993  		switch f := f.(type) {
   994  		case *HeadersFrame:
   995  			err = rl.processHeaders(f)
   996  		case *ContinuationFrame:
   997  			err = rl.processContinuation(f)
   998  		case *DataFrame:
   999  			err = rl.processData(f)
  1000  		case *GoAwayFrame:
  1001  			err = rl.processGoAway(f)
  1002  		case *RSTStreamFrame:
  1003  			err = rl.processResetStream(f)
  1004  		case *SettingsFrame:
  1005  			err = rl.processSettings(f)
  1006  		case *PushPromiseFrame:
  1007  			err = rl.processPushPromise(f)
  1008  		case *WindowUpdateFrame:
  1009  			err = rl.processWindowUpdate(f)
  1010  		case *PingFrame:
  1011  			err = rl.processPing(f)
  1012  		default:
  1013  			cc.logf("Transport: unhandled response frame type %T", f)
  1014  		}
  1015  		if err != nil {
  1016  			return err
  1017  		}
  1018  	}
  1019  }
  1020  
  1021  func (rl *clientConnReadLoop) processHeaders(f *HeadersFrame) error {
  1022  	rl.sawRegHeader = false
  1023  	rl.reqMalformed = nil
  1024  	rl.nextRes = &http.Response{
  1025  		Proto:      "HTTP/2.0",
  1026  		ProtoMajor: 2,
  1027  		Header:     make(http.Header),
  1028  	}
  1029  	return rl.processHeaderBlockFragment(f.HeaderBlockFragment(), f.StreamID, f.HeadersEnded(), f.StreamEnded())
  1030  }
  1031  
  1032  func (rl *clientConnReadLoop) processContinuation(f *ContinuationFrame) error {
  1033  	return rl.processHeaderBlockFragment(f.HeaderBlockFragment(), f.StreamID, f.HeadersEnded(), f.StreamEnded())
  1034  }
  1035  
  1036  func (rl *clientConnReadLoop) processHeaderBlockFragment(frag []byte, streamID uint32, headersEnded, streamEnded bool) error {
  1037  	cc := rl.cc
  1038  	cs := cc.streamByID(streamID, streamEnded)
  1039  	if cs == nil {
  1040  		// We'd get here if we canceled a request while the
  1041  		// server was mid-way through replying with its
  1042  		// headers. (The case of a CONTINUATION arriving
  1043  		// without HEADERS would be rejected earlier by the
  1044  		// Framer). So if this was just something we canceled,
  1045  		// ignore it.
  1046  		return nil
  1047  	}
  1048  	if cs.headersDone {
  1049  		rl.hdec.SetEmitFunc(cs.onNewTrailerField)
  1050  	} else {
  1051  		rl.hdec.SetEmitFunc(rl.onNewHeaderField)
  1052  	}
  1053  	_, err := rl.hdec.Write(frag)
  1054  	if err != nil {
  1055  		return ConnectionError(ErrCodeCompression)
  1056  	}
  1057  	if err := rl.hdec.Close(); err != nil {
  1058  		return ConnectionError(ErrCodeCompression)
  1059  	}
  1060  	if !headersEnded {
  1061  		return nil
  1062  	}
  1063  
  1064  	if !cs.headersDone {
  1065  		cs.headersDone = true
  1066  	} else {
  1067  		// We're dealing with trailers. (and specifically the
  1068  		// final frame of headers)
  1069  		if cs.trailersDone {
  1070  			// Too many HEADERS frames for this stream.
  1071  			return ConnectionError(ErrCodeProtocol)
  1072  		}
  1073  		cs.trailersDone = true
  1074  		if !streamEnded {
  1075  			// We expect that any header block fragment
  1076  			// frame for trailers with END_HEADERS also
  1077  			// has END_STREAM.
  1078  			return ConnectionError(ErrCodeProtocol)
  1079  		}
  1080  		rl.endStream(cs)
  1081  		return nil
  1082  	}
  1083  
  1084  	if rl.reqMalformed != nil {
  1085  		cs.resc <- resAndError{err: rl.reqMalformed}
  1086  		rl.cc.writeStreamReset(cs.ID, ErrCodeProtocol, rl.reqMalformed)
  1087  		return nil
  1088  	}
  1089  
  1090  	res := rl.nextRes
  1091  
  1092  	if !streamEnded || cs.req.Method == "HEAD" {
  1093  		res.ContentLength = -1
  1094  		if clens := res.Header["Content-Length"]; len(clens) == 1 {
  1095  			if clen64, err := strconv.ParseInt(clens[0], 10, 64); err == nil {
  1096  				res.ContentLength = clen64
  1097  			} else {
  1098  				// TODO: care? unlike http/1, it won't mess up our framing, so it's
  1099  				// more safe smuggling-wise to ignore.
  1100  			}
  1101  		} else if len(clens) > 1 {
  1102  			// TODO: care? unlike http/1, it won't mess up our framing, so it's
  1103  			// more safe smuggling-wise to ignore.
  1104  		}
  1105  	}
  1106  
  1107  	if streamEnded {
  1108  		res.Body = noBody
  1109  	} else {
  1110  		buf := new(bytes.Buffer) // TODO(bradfitz): recycle this garbage
  1111  		cs.bufPipe = pipe{b: buf}
  1112  		cs.bytesRemain = res.ContentLength
  1113  		res.Body = transportResponseBody{cs}
  1114  		go cs.awaitRequestCancel(requestCancel(cs.req))
  1115  
  1116  		if cs.requestedGzip && res.Header.Get("Content-Encoding") == "gzip" {
  1117  			res.Header.Del("Content-Encoding")
  1118  			res.Header.Del("Content-Length")
  1119  			res.ContentLength = -1
  1120  			res.Body = &gzipReader{body: res.Body}
  1121  		}
  1122  	}
  1123  
  1124  	cs.resTrailer = res.Trailer
  1125  	rl.activeRes[cs.ID] = cs
  1126  	cs.resc <- resAndError{res: res}
  1127  	rl.nextRes = nil // unused now; will be reset next HEADERS frame
  1128  	return nil
  1129  }
  1130  
  1131  // transportResponseBody is the concrete type of Transport.RoundTrip's
  1132  // Response.Body. It is an io.ReadCloser. On Read, it reads from cs.body.
  1133  // On Close it sends RST_STREAM if EOF wasn't already seen.
  1134  type transportResponseBody struct {
  1135  	cs *clientStream
  1136  }
  1137  
  1138  func (b transportResponseBody) Read(p []byte) (n int, err error) {
  1139  	cs := b.cs
  1140  	cc := cs.cc
  1141  
  1142  	if cs.readErr != nil {
  1143  		return 0, cs.readErr
  1144  	}
  1145  	n, err = b.cs.bufPipe.Read(p)
  1146  	if cs.bytesRemain != -1 {
  1147  		if int64(n) > cs.bytesRemain {
  1148  			n = int(cs.bytesRemain)
  1149  			if err == nil {
  1150  				err = errors.New("net/http: server replied with more than declared Content-Length; truncated")
  1151  				cc.writeStreamReset(cs.ID, ErrCodeProtocol, err)
  1152  			}
  1153  			cs.readErr = err
  1154  			return int(cs.bytesRemain), err
  1155  		}
  1156  		cs.bytesRemain -= int64(n)
  1157  		if err == io.EOF && cs.bytesRemain > 0 {
  1158  			err = io.ErrUnexpectedEOF
  1159  			cs.readErr = err
  1160  			return n, err
  1161  		}
  1162  	}
  1163  	if n == 0 {
  1164  		// No flow control tokens to send back.
  1165  		return
  1166  	}
  1167  
  1168  	cc.mu.Lock()
  1169  	defer cc.mu.Unlock()
  1170  
  1171  	var connAdd, streamAdd int32
  1172  	// Check the conn-level first, before the stream-level.
  1173  	if v := cc.inflow.available(); v < transportDefaultConnFlow/2 {
  1174  		connAdd = transportDefaultConnFlow - v
  1175  		cc.inflow.add(connAdd)
  1176  	}
  1177  	if err == nil { // No need to refresh if the stream is over or failed.
  1178  		if v := cs.inflow.available(); v < transportDefaultStreamFlow-transportDefaultStreamMinRefresh {
  1179  			streamAdd = transportDefaultStreamFlow - v
  1180  			cs.inflow.add(streamAdd)
  1181  		}
  1182  	}
  1183  	if connAdd != 0 || streamAdd != 0 {
  1184  		cc.wmu.Lock()
  1185  		defer cc.wmu.Unlock()
  1186  		if connAdd != 0 {
  1187  			cc.fr.WriteWindowUpdate(0, mustUint31(connAdd))
  1188  		}
  1189  		if streamAdd != 0 {
  1190  			cc.fr.WriteWindowUpdate(cs.ID, mustUint31(streamAdd))
  1191  		}
  1192  		cc.bw.Flush()
  1193  	}
  1194  	return
  1195  }
  1196  
  1197  var errClosedResponseBody = errors.New("http2: response body closed")
  1198  
  1199  func (b transportResponseBody) Close() error {
  1200  	cs := b.cs
  1201  	if cs.bufPipe.Err() != io.EOF {
  1202  		// TODO: write test for this
  1203  		cs.cc.writeStreamReset(cs.ID, ErrCodeCancel, nil)
  1204  	}
  1205  	cs.bufPipe.BreakWithError(errClosedResponseBody)
  1206  	return nil
  1207  }
  1208  
  1209  func (rl *clientConnReadLoop) processData(f *DataFrame) error {
  1210  	cc := rl.cc
  1211  	cs := cc.streamByID(f.StreamID, f.StreamEnded())
  1212  	if cs == nil {
  1213  		return nil
  1214  	}
  1215  	data := f.Data()
  1216  	if VerboseLogs {
  1217  		rl.cc.logf("DATA: %q", data)
  1218  	}
  1219  
  1220  	// Check connection-level flow control.
  1221  	cc.mu.Lock()
  1222  	if cs.inflow.available() >= int32(len(data)) {
  1223  		cs.inflow.take(int32(len(data)))
  1224  	} else {
  1225  		cc.mu.Unlock()
  1226  		return ConnectionError(ErrCodeFlowControl)
  1227  	}
  1228  	cc.mu.Unlock()
  1229  
  1230  	if _, err := cs.bufPipe.Write(data); err != nil {
  1231  		return err
  1232  	}
  1233  
  1234  	if f.StreamEnded() {
  1235  		rl.endStream(cs)
  1236  	}
  1237  	return nil
  1238  }
  1239  
  1240  func (rl *clientConnReadLoop) endStream(cs *clientStream) {
  1241  	// TODO: check that any declared content-length matches, like
  1242  	// server.go's (*stream).endStream method.
  1243  	cs.bufPipe.closeWithErrorAndCode(io.EOF, cs.copyTrailers)
  1244  	delete(rl.activeRes, cs.ID)
  1245  }
  1246  
  1247  func (cs *clientStream) copyTrailers() {
  1248  	for k, vv := range cs.trailer {
  1249  		cs.resTrailer[k] = vv
  1250  	}
  1251  }
  1252  
  1253  func (rl *clientConnReadLoop) processGoAway(f *GoAwayFrame) error {
  1254  	cc := rl.cc
  1255  	cc.t.connPool().MarkDead(cc)
  1256  	if f.ErrCode != 0 {
  1257  		// TODO: deal with GOAWAY more. particularly the error code
  1258  		cc.vlogf("transport got GOAWAY with error code = %v", f.ErrCode)
  1259  	}
  1260  	cc.setGoAway(f)
  1261  	return nil
  1262  }
  1263  
  1264  func (rl *clientConnReadLoop) processSettings(f *SettingsFrame) error {
  1265  	cc := rl.cc
  1266  	cc.mu.Lock()
  1267  	defer cc.mu.Unlock()
  1268  	return f.ForeachSetting(func(s Setting) error {
  1269  		switch s.ID {
  1270  		case SettingMaxFrameSize:
  1271  			cc.maxFrameSize = s.Val
  1272  		case SettingMaxConcurrentStreams:
  1273  			cc.maxConcurrentStreams = s.Val
  1274  		case SettingInitialWindowSize:
  1275  			// TODO: error if this is too large.
  1276  
  1277  			// TODO: adjust flow control of still-open
  1278  			// frames by the difference of the old initial
  1279  			// window size and this one.
  1280  			cc.initialWindowSize = s.Val
  1281  		default:
  1282  			// TODO(bradfitz): handle more settings?
  1283  			cc.vlogf("Unhandled Setting: %v", s)
  1284  		}
  1285  		return nil
  1286  	})
  1287  }
  1288  
  1289  func (rl *clientConnReadLoop) processWindowUpdate(f *WindowUpdateFrame) error {
  1290  	cc := rl.cc
  1291  	cs := cc.streamByID(f.StreamID, false)
  1292  	if f.StreamID != 0 && cs == nil {
  1293  		return nil
  1294  	}
  1295  
  1296  	cc.mu.Lock()
  1297  	defer cc.mu.Unlock()
  1298  
  1299  	fl := &cc.flow
  1300  	if cs != nil {
  1301  		fl = &cs.flow
  1302  	}
  1303  	if !fl.add(int32(f.Increment)) {
  1304  		return ConnectionError(ErrCodeFlowControl)
  1305  	}
  1306  	cc.cond.Broadcast()
  1307  	return nil
  1308  }
  1309  
  1310  func (rl *clientConnReadLoop) processResetStream(f *RSTStreamFrame) error {
  1311  	cs := rl.cc.streamByID(f.StreamID, true)
  1312  	if cs == nil {
  1313  		// TODO: return error if server tries to RST_STEAM an idle stream
  1314  		return nil
  1315  	}
  1316  	select {
  1317  	case <-cs.peerReset:
  1318  		// Already reset.
  1319  		// This is the only goroutine
  1320  		// which closes this, so there
  1321  		// isn't a race.
  1322  	default:
  1323  		err := StreamError{cs.ID, f.ErrCode}
  1324  		cs.resetErr = err
  1325  		close(cs.peerReset)
  1326  		cs.bufPipe.CloseWithError(err)
  1327  		cs.cc.cond.Broadcast() // wake up checkReset via clientStream.awaitFlowControl
  1328  	}
  1329  	delete(rl.activeRes, cs.ID)
  1330  	return nil
  1331  }
  1332  
  1333  func (rl *clientConnReadLoop) processPing(f *PingFrame) error {
  1334  	if f.IsAck() {
  1335  		// 6.7 PING: " An endpoint MUST NOT respond to PING frames
  1336  		// containing this flag."
  1337  		return nil
  1338  	}
  1339  	cc := rl.cc
  1340  	cc.wmu.Lock()
  1341  	defer cc.wmu.Unlock()
  1342  	if err := cc.fr.WritePing(true, f.Data); err != nil {
  1343  		return err
  1344  	}
  1345  	return cc.bw.Flush()
  1346  }
  1347  
  1348  func (rl *clientConnReadLoop) processPushPromise(f *PushPromiseFrame) error {
  1349  	// We told the peer we don't want them.
  1350  	// Spec says:
  1351  	// "PUSH_PROMISE MUST NOT be sent if the SETTINGS_ENABLE_PUSH
  1352  	// setting of the peer endpoint is set to 0. An endpoint that
  1353  	// has set this setting and has received acknowledgement MUST
  1354  	// treat the receipt of a PUSH_PROMISE frame as a connection
  1355  	// error (Section 5.4.1) of type PROTOCOL_ERROR."
  1356  	return ConnectionError(ErrCodeProtocol)
  1357  }
  1358  
  1359  func (cc *ClientConn) writeStreamReset(streamID uint32, code ErrCode, err error) {
  1360  	// TODO: do something with err? send it as a debug frame to the peer?
  1361  	// But that's only in GOAWAY. Invent a new frame type? Is there one already?
  1362  	cc.wmu.Lock()
  1363  	cc.fr.WriteRSTStream(streamID, code)
  1364  	cc.bw.Flush()
  1365  	cc.wmu.Unlock()
  1366  }
  1367  
  1368  // onNewHeaderField runs on the readLoop goroutine whenever a new
  1369  // hpack header field is decoded.
  1370  func (rl *clientConnReadLoop) onNewHeaderField(f hpack.HeaderField) {
  1371  	cc := rl.cc
  1372  	if VerboseLogs {
  1373  		cc.logf("Header field: %+v", f)
  1374  	}
  1375  	// TODO: enforce max header list size like server.
  1376  	isPseudo := strings.HasPrefix(f.Name, ":")
  1377  	if isPseudo {
  1378  		if rl.sawRegHeader {
  1379  			rl.reqMalformed = errors.New("http2: invalid pseudo header after regular header")
  1380  			return
  1381  		}
  1382  		switch f.Name {
  1383  		case ":status":
  1384  			code, err := strconv.Atoi(f.Value)
  1385  			if err != nil {
  1386  				rl.reqMalformed = errors.New("http2: invalid :status")
  1387  				return
  1388  			}
  1389  			rl.nextRes.Status = f.Value + " " + http.StatusText(code)
  1390  			rl.nextRes.StatusCode = code
  1391  		default:
  1392  			// "Endpoints MUST NOT generate pseudo-header
  1393  			// fields other than those defined in this
  1394  			// document."
  1395  			rl.reqMalformed = fmt.Errorf("http2: unknown response pseudo header %q", f.Name)
  1396  		}
  1397  	} else {
  1398  		rl.sawRegHeader = true
  1399  		key := http.CanonicalHeaderKey(f.Name)
  1400  		if key == "Trailer" {
  1401  			t := rl.nextRes.Trailer
  1402  			if t == nil {
  1403  				t = make(http.Header)
  1404  				rl.nextRes.Trailer = t
  1405  			}
  1406  			foreachHeaderElement(f.Value, func(v string) {
  1407  				t[http.CanonicalHeaderKey(v)] = nil
  1408  			})
  1409  		} else {
  1410  			rl.nextRes.Header.Add(key, f.Value)
  1411  		}
  1412  	}
  1413  }
  1414  
  1415  func (cs *clientStream) onNewTrailerField(f hpack.HeaderField) {
  1416  	isPseudo := strings.HasPrefix(f.Name, ":")
  1417  	if isPseudo {
  1418  		// TODO: Bogus. report an error later when we close their body.
  1419  		// drop for now.
  1420  		return
  1421  	}
  1422  	key := http.CanonicalHeaderKey(f.Name)
  1423  	if _, ok := cs.resTrailer[key]; ok {
  1424  		if cs.trailer == nil {
  1425  			cs.trailer = make(http.Header)
  1426  		}
  1427  		const tooBig = 1000 // TODO: arbitrary; use max header list size limits
  1428  		if cur := cs.trailer[key]; len(cur) < tooBig {
  1429  			cs.trailer[key] = append(cur, f.Value)
  1430  		}
  1431  	}
  1432  }
  1433  
  1434  func (cc *ClientConn) logf(format string, args ...interface{}) {
  1435  	cc.t.logf(format, args...)
  1436  }
  1437  
  1438  func (cc *ClientConn) vlogf(format string, args ...interface{}) {
  1439  	cc.t.vlogf(format, args...)
  1440  }
  1441  
  1442  func (t *Transport) vlogf(format string, args ...interface{}) {
  1443  	if VerboseLogs {
  1444  		t.logf(format, args...)
  1445  	}
  1446  }
  1447  
  1448  func (t *Transport) logf(format string, args ...interface{}) {
  1449  	log.Printf(format, args...)
  1450  }
  1451  
  1452  var noBody io.ReadCloser = ioutil.NopCloser(bytes.NewReader(nil))
  1453  
  1454  func strSliceContains(ss []string, s string) bool {
  1455  	for _, v := range ss {
  1456  		if v == s {
  1457  			return true
  1458  		}
  1459  	}
  1460  	return false
  1461  }
  1462  
  1463  type erringRoundTripper struct{ err error }
  1464  
  1465  func (rt erringRoundTripper) RoundTrip(*http.Request) (*http.Response, error) { return nil, rt.err }
  1466  
  1467  // gzipReader wraps a response body so it can lazily
  1468  // call gzip.NewReader on the first call to Read
  1469  type gzipReader struct {
  1470  	body io.ReadCloser // underlying Response.Body
  1471  	zr   io.Reader     // lazily-initialized gzip reader
  1472  }
  1473  
  1474  func (gz *gzipReader) Read(p []byte) (n int, err error) {
  1475  	if gz.zr == nil {
  1476  		gz.zr, err = gzip.NewReader(gz.body)
  1477  		if err != nil {
  1478  			return 0, err
  1479  		}
  1480  	}
  1481  	return gz.zr.Read(p)
  1482  }
  1483  
  1484  func (gz *gzipReader) Close() error {
  1485  	return gz.body.Close()
  1486  }