]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/golang.org/x/net/http2/configure_transport.go
Merge pull request #27 from terraform-providers/go-modules-2019-02-22
[github/fretlink/terraform-provider-statuscake.git] / vendor / golang.org / x / net / http2 / configure_transport.go
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 // +build go1.6
6
7 package http2
8
9 import (
10 "crypto/tls"
11 "fmt"
12 "net/http"
13 )
14
15 func configureTransport(t1 *http.Transport) (*Transport, error) {
16 connPool := new(clientConnPool)
17 t2 := &Transport{
18 ConnPool: noDialClientConnPool{connPool},
19 t1: t1,
20 }
21 connPool.t = t2
22 if err := registerHTTPSProtocol(t1, noDialH2RoundTripper{t2}); err != nil {
23 return nil, err
24 }
25 if t1.TLSClientConfig == nil {
26 t1.TLSClientConfig = new(tls.Config)
27 }
28 if !strSliceContains(t1.TLSClientConfig.NextProtos, "h2") {
29 t1.TLSClientConfig.NextProtos = append([]string{"h2"}, t1.TLSClientConfig.NextProtos...)
30 }
31 if !strSliceContains(t1.TLSClientConfig.NextProtos, "http/1.1") {
32 t1.TLSClientConfig.NextProtos = append(t1.TLSClientConfig.NextProtos, "http/1.1")
33 }
34 upgradeFn := func(authority string, c *tls.Conn) http.RoundTripper {
35 addr := authorityAddr("https", authority)
36 if used, err := connPool.addConnIfNeeded(addr, t2, c); err != nil {
37 go c.Close()
38 return erringRoundTripper{err}
39 } else if !used {
40 // Turns out we don't need this c.
41 // For example, two goroutines made requests to the same host
42 // at the same time, both kicking off TCP dials. (since protocol
43 // was unknown)
44 go c.Close()
45 }
46 return t2
47 }
48 if m := t1.TLSNextProto; len(m) == 0 {
49 t1.TLSNextProto = map[string]func(string, *tls.Conn) http.RoundTripper{
50 "h2": upgradeFn,
51 }
52 } else {
53 m["h2"] = upgradeFn
54 }
55 return t2, nil
56 }
57
58 // registerHTTPSProtocol calls Transport.RegisterProtocol but
59 // converting panics into errors.
60 func registerHTTPSProtocol(t *http.Transport, rt http.RoundTripper) (err error) {
61 defer func() {
62 if e := recover(); e != nil {
63 err = fmt.Errorf("%v", e)
64 }
65 }()
66 t.RegisterProtocol("https", rt)
67 return nil
68 }
69
70 // noDialH2RoundTripper is a RoundTripper which only tries to complete the request
71 // if there's already has a cached connection to the host.
72 type noDialH2RoundTripper struct{ t *Transport }
73
74 func (rt noDialH2RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
75 res, err := rt.t.RoundTrip(req)
76 if err == ErrNoCachedConn {
77 return nil, http.ErrSkipAltProtocol
78 }
79 return res, err
80 }