/
client.go
118 lines (105 loc) · 3.74 KB
/
client.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// Copyright 2015 tsuru authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package net
import (
"crypto/tls"
"fmt"
"net"
"net/http"
"net/url"
"time"
"github.com/tsuru/config"
)
func makeTimeoutHTTPClient(dialTimeout time.Duration, fullTimeout time.Duration, maxIdle int, followRedirects bool) *http.Client {
dialer := &net.Dialer{
Timeout: dialTimeout,
KeepAlive: 30 * time.Second,
}
client := &http.Client{
Transport: &http.Transport{
Dial: dialer.Dial,
DialContext: dialer.DialContext,
TLSHandshakeTimeout: dialTimeout,
MaxIdleConnsPerHost: maxIdle,
IdleConnTimeout: 15 * time.Second,
},
Timeout: fullTimeout,
}
if !followRedirects {
client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
}
}
return client
}
const (
StreamInactivityTimeout = time.Minute
)
var (
Dial15Full300Client = withOpenTracing(makeTimeoutHTTPClient(15*time.Second, 5*time.Minute, 5, true))
Dial15FullUnlimitedClient = withOpenTracing(makeTimeoutHTTPClient(15*time.Second, 0, 5, true))
Dial15Full300ClientNoKeepAlive = withOpenTracing(makeTimeoutHTTPClient(15*time.Second, 5*time.Minute, -1, true))
Dial15Full60ClientNoKeepAlive = withOpenTracing(makeTimeoutHTTPClient(15*time.Second, 1*time.Minute, -1, true))
Dial15Full60ClientNoKeepAliveNoRedirect = withOpenTracing(makeTimeoutHTTPClient(15*time.Second, 1*time.Minute, -1, false))
Dial15Full60ClientNoKeepAliveNoRedirectInsecure = insecure(withOpenTracing(makeTimeoutHTTPClient(15*time.Second, 1*time.Minute, -1, false)))
Dial15Full60ClientNoKeepAliveInsecure = insecure(withOpenTracing(makeTimeoutHTTPClient(15*time.Second, 1*time.Minute, -1, true)))
Dial15Full60ClientWithPool = withOpenTracing(makeTimeoutHTTPClient(15*time.Second, 1*time.Minute, 10, true))
Dial15Full300ClientWithPool = withOpenTracing(makeTimeoutHTTPClient(15*time.Second, 5*time.Minute, 10, true))
)
func insecure(client *http.Client) *http.Client {
httpTransport, ok := client.Transport.(*http.Transport)
if !ok {
opentracingTransport := client.Transport.(*AutoOpentracingTransport)
httpTransport = opentracingTransport.RoundTripper.(*http.Transport)
}
tlsConfig := httpTransport.TLSClientConfig
if tlsConfig == nil {
tlsConfig = &tls.Config{}
}
tlsConfig.InsecureSkipVerify = true
httpTransport.TLSClientConfig = tlsConfig
return client
}
func WithProxy(cli http.Client, proxyURL string) (*http.Client, error) {
newTransport, err := proxyTransport(proxyURL)
if err != nil {
return nil, err
}
baseTrans, _ := cli.Transport.(*http.Transport)
if baseTrans != nil {
newTransport.DialContext = baseTrans.DialContext
newTransport.TLSHandshakeTimeout = baseTrans.TLSHandshakeTimeout
newTransport.MaxIdleConnsPerHost = baseTrans.MaxIdleConnsPerHost
newTransport.TLSClientConfig = baseTrans.TLSClientConfig
}
cli.Transport = newTransport
return &cli, nil
}
func proxyTransport(proxyURL string) (*http.Transport, error) {
u, err := url.Parse(proxyURL)
if err != nil {
return nil, err
}
if u.Host == "" {
u = &url.URL{Host: proxyURL, Scheme: "http"}
}
return &http.Transport{
Proxy: http.ProxyURL(u),
}, nil
}
func WithProxyFromConfig(cli http.Client, dstHostOrURL string) (*http.Client, error) {
proxyURL, ok := proxyFromConfig(dstHostOrURL)
if !ok {
return &cli, nil
}
return WithProxy(cli, proxyURL)
}
func proxyFromConfig(dstHostOrURL string) (string, bool) {
host := URLToHost(dstHostOrURL)
proxyURL, err := config.GetString(fmt.Sprintf("proxy:%s", host))
if err != nil || proxyURL == "" {
return "", false
}
return proxyURL, true
}