// Creates a new HTTP connection pool using the given address and pool parameters. // // 'addr' is a net.Dial()-style 'host:port' destination for making the TCP connection for // HTTP/HTTPS traffic. It will be used as the hostname by default for virtual hosting // and SSL certificate validation; if you'd like to use a different hostname, // set params.HostHeader. func NewSimplePool(addr string, params ConnectionParams) *SimplePool { pool := &SimplePool{ addr: addr, params: params, client: new(http.Client), } // setup HTTP transport transport := new(http.Transport) transport.ResponseHeaderTimeout = params.ResponseTimeout transport.MaxIdleConnsPerHost = params.MaxIdle transport.Proxy = http.ProxyFromEnvironment if params.Dial == nil { // dialTimeout could only be used in none proxy requests since it talks directly // to pool.addr if getenvEitherCase("HTTP_PROXY") == "" { transport.Dial = pool.dialTimeout } } else { transport.Dial = params.Dial } pool.transport = transport pool.client.Transport = transport if params.UseSSL && params.SkipVerifySSL { transport.TLSClientConfig = &tls.Config{ InsecureSkipVerify: true, } } return pool }
// ConfigureTransport configures the specified Transport according to the // specified proto and addr. // If the proto is unix (using a unix socket to communicate) or npipe the // compression is disabled. func ConfigureTransport(tr *http.Transport, proto, addr string) error { switch proto { case "unix": // No need for compression in local communications. tr.DisableCompression = true tr.Dial = func(_, _ string) (net.Conn, error) { return net.DialTimeout(proto, addr, defaultTimeout) } case "npipe": // No need for compression in local communications. tr.DisableCompression = true tr.Dial = func(_, _ string) (net.Conn, error) { return DialPipe(addr, defaultTimeout) } default: tr.Proxy = http.ProxyFromEnvironment dialer, err := DialerFromEnvironment(&net.Dialer{ Timeout: defaultTimeout, }) if err != nil { return err } tr.Dial = dialer.Dial } return nil }
// ConfigureTCPTransport configures the specified Transport according to the // specified proto and addr. // If the proto is unix (using a unix socket to communicate) the compression // is disabled. func ConfigureTCPTransport(tr *http.Transport, proto, addr string) { // Why 32? See https://github.com/docker/docker/pull/8035. timeout := 32 * time.Second if proto == "unix" { // No need for compression in local communications. tr.DisableCompression = true tr.Dial = func(_, _ string) (net.Conn, error) { return net.DialTimeout(proto, addr, timeout) } } else { tr.Proxy = http.ProxyFromEnvironment tr.Dial = (&net.Dialer{Timeout: timeout}).Dial } }
func NewProxyAuthTransport(rawTransport *http.Transport, customHeaders http.Header) (*ProxyAuthTransport, error) { dialFn := rawTransport.Dial if dialFn == nil { dialFn = net.Dial } tr := &ProxyAuthTransport{Dial: dialFn, CustomHeaders: customHeaders} proxyUrlFn := rawTransport.Proxy if proxyUrlFn != nil { wrappedDialFn := tr.wrapTransportDial() rawTransport.Dial = wrappedDialFn proxyUrl, err := proxyUrlFn(nil) if err != nil { return nil, err } if proxyUrl.Scheme != "http" { return nil, fmt.Errorf("Only HTTP proxy supported, for SOCKS use http.Transport with custom dialers & upstreamproxy.NewProxyDialFunc") } if proxyUrl.User != nil { tr.Username = proxyUrl.User.Username() tr.Password, _ = proxyUrl.User.Password() } // strip username and password from the proxyURL because // we do not want the wrapped transport to handle authentication proxyUrl.User = nil rawTransport.Proxy = http.ProxyURL(proxyUrl) } tr.Transport = rawTransport return tr, nil }
// installHTTPDialShim patches the default HTTP transport so // that it fails when an attempt is made to dial a non-local // host. func installHTTPDialShim(t *http.Transport) { t.Dial = func(network, addr string) (net.Conn, error) { if !OutgoingAccessAllowed && !isLocalAddr(addr) { return nil, fmt.Errorf("access to address %q not allowed", addr) } return net.Dial(network, addr) } }
// Creates a new HTTP connection pool using the given address and pool parameters. // // 'addr' is a net.Dial()-style 'host:port' destination for making the TCP connection for // HTTP/HTTPS traffic. It will be used as the hostname by default for virtual hosting // and SSL certificate validation; if you'd like to use a different hostname, // set params.HostHeader. func NewSimplePool(addr string, params ConnectionParams) *SimplePool { pool := &SimplePool{ addr: addr, params: params, client: new(http.Client), } // It's desirable to enforce the timeout at the client-level since it // includes the connection time, redirects and the time to finish reading // the full response. Unlike ResponseHeaderTimeout supported by // `http.Transport` which merely accounts for the timeout to receive the // first response header byte. It ignores the time to send the request or // the time to read the full response. pool.client.Timeout = params.ResponseTimeout // setup HTTP transport transport := new(http.Transport) transport.ResponseHeaderTimeout = params.ResponseTimeout transport.MaxIdleConnsPerHost = params.MaxIdle if params.Proxy != nil { transport.Proxy = params.Proxy } else { transport.Proxy = http.ProxyFromEnvironment } if params.Dial == nil { // dialTimeout could only be used in none proxy requests since it talks directly // to pool.addr if getenvEitherCase("HTTP_PROXY") == "" && params.Proxy == nil { transport.Dial = pool.dialTimeout } } else { transport.Dial = params.Dial } pool.transport = transport pool.client.Transport = transport if params.UseSSL && params.SkipVerifySSL { transport.TLSClientConfig = &tls.Config{ InsecureSkipVerify: true, } } return pool }
func configureTransport(tr *http.Transport, proto, addr string) *http.Transport { if tr == nil { tr = &http.Transport{} } if proto == "unix" { // No need for compression in local communications. tr.DisableCompression = true tr.Dial = func(_, _ string) (net.Conn, error) { return net.Dial(proto, addr) } } else { tr.Proxy = http.ProxyFromEnvironment tr.Dial = (&net.Dialer{}).Dial } return tr }
func NewClient(e *Env, config *ClientConfig, needCookie bool) *Client { var jar *cookiejar.Jar if needCookie && (config == nil || config.UseCookies) && e.GetTorMode().UseCookies() { jar, _ = cookiejar.New(nil) } var timeout time.Duration // from http.DefaultTransport; // // TODO: change this back (see comment below) to allow // shared Transport after we switch to go1.7 xprt := http.Transport{ Proxy: http.ProxyFromEnvironment, Dial: (&net.Dialer{ Timeout: 30 * time.Second, KeepAlive: 30 * time.Second, }).Dial, TLSHandshakeTimeout: 10 * time.Second, ExpectContinueTimeout: 1 * time.Second, } // This disables HTTP/2. There's a bug introduced between (go1.6, go1.6.3] // that makes client.Get hang on certain HTTP/2 servers. See CORE-3441 for // details. // // TODO: remove this after the bug is fixed. xprt.TLSNextProto = make( map[string]func(authority string, c *tls.Conn) http.RoundTripper) if (config != nil && config.RootCAs != nil) || e.GetTorMode().Enabled() { if config != nil && config.RootCAs != nil { xprt.TLSClientConfig = &tls.Config{RootCAs: config.RootCAs} } if e.GetTorMode().Enabled() { dialSocksProxy := socks.DialSocksProxy(socks.SOCKS5, e.GetTorProxy()) xprt.Dial = dialSocksProxy } else { xprt.Proxy = http.ProxyFromEnvironment } } if config == nil || config.Timeout == 0 { timeout = HTTPDefaultTimeout } else { timeout = config.Timeout } ret := &Client{ cli: &http.Client{Timeout: timeout}, config: config, } if jar != nil { ret.cli.Jar = jar } ret.cli.Transport = &xprt return ret }
// SetTransportDefaults applies the defaults from http.DefaultTransport // for the Proxy, Dial, and TLSHandshakeTimeout fields if unset func SetTransportDefaults(t *http.Transport) *http.Transport { if t.Proxy == nil { t.Proxy = defaultTransport.Proxy } if t.Dial == nil { t.Dial = defaultTransport.Dial } if t.TLSHandshakeTimeout == 0 { t.TLSHandshakeTimeout = defaultTransport.TLSHandshakeTimeout } return t }
// defaultTransport creates a new http.Transport with Docker's // default transport configuration. func defaultTransport(proto, addr string) *http.Transport { tr := new(http.Transport) // Why 32? See https://github.com/docker/docker/pull/8035. timeout := 32 * time.Second if proto == "unix" { // No need for compression in local communications. tr.DisableCompression = true tr.Dial = func(_, _ string) (net.Conn, error) { return net.DialTimeout(proto, addr, timeout) } } else if proto == "npipe" { tr.Dial = func(_, _ string) (net.Conn, error) { return DialPipe(addr, timeout) } } else { tr.Proxy = http.ProxyFromEnvironment tr.Dial = (&net.Dialer{Timeout: timeout}).Dial } return tr }
// SetOldTransportDefaults applies the defaults from http.DefaultTransport // for the Proxy, Dial, and TLSHandshakeTimeout fields if unset func SetOldTransportDefaults(t *http.Transport) *http.Transport { if t.Proxy == nil || isDefault(t.Proxy) { // http.ProxyFromEnvironment doesn't respect CIDRs and that makes it impossible to exclude things like pod and service IPs from proxy settings // ProxierWithNoProxyCIDR allows CIDR rules in NO_PROXY t.Proxy = NewProxierWithNoProxyCIDR(http.ProxyFromEnvironment) } if t.Dial == nil { t.Dial = defaultTransport.Dial } if t.TLSHandshakeTimeout == 0 { t.TLSHandshakeTimeout = defaultTransport.TLSHandshakeTimeout } return t }
// ConfigureTransport configures the specified Transport according to the // specified proto and addr. // If the proto is unix (using a unix socket to communicate) or npipe the // compression is disabled. func ConfigureTransport(tr *http.Transport, proto, addr string) error { switch proto { case "unix": return configureUnixTransport(tr, proto, addr) case "npipe": return configureNpipeTransport(tr, proto, addr) default: tr.Proxy = http.ProxyFromEnvironment dialer, err := DialerFromEnvironment(&net.Dialer{ Timeout: defaultTimeout, }) if err != nil { return err } tr.Dial = dialer.Dial } return nil }
func newHttpClient(config *Config) *http.Client { transport := new(http.Transport) if defaultTransport, ok := http.DefaultTransport.(*http.Transport); ok { transport.Proxy = defaultTransport.Proxy transport.Dial = defaultTransport.Dial transport.TLSHandshakeTimeout = defaultTransport.TLSHandshakeTimeout } if config.ProxyHost != "" { host := config.ProxyHost if config.ProxyPort > 0 { host += ":" + strconv.Itoa(config.ProxyPort) } proxyUrl, err := url.Parse(util.HostToURL(host, "http")) if err != nil { panic(err) } transport.Proxy = http.ProxyURL(proxyUrl) } /* if c.ConnectionTimeout > 0 { transport.TLSHandshakeTimeout = c.ConnectionTimeout } */ if config.MaxConnections > 0 { transport.MaxIdleConnsPerHost = config.MaxConnections } return &http.Client{ Transport: transport, Timeout: config.Timeout, } }
func NewClient(e *Env, config *ClientConfig, needCookie bool) *Client { var jar *cookiejar.Jar if needCookie && (config == nil || config.UseCookies) && e.GetTorMode().UseCookies() { jar, _ = cookiejar.New(nil) } var xprt *http.Transport var timeout time.Duration if (config != nil && config.RootCAs != nil) || e.GetTorMode().Enabled() { xprt = &http.Transport{} if config != nil && config.RootCAs != nil { xprt.TLSClientConfig = &tls.Config{RootCAs: config.RootCAs} } if e.GetTorMode().Enabled() { dialSocksProxy := socks.DialSocksProxy(socks.SOCKS5, e.GetTorProxy()) xprt.Dial = dialSocksProxy } else { xprt.Proxy = http.ProxyFromEnvironment } } if config == nil || config.Timeout == 0 { timeout = HTTPDefaultTimeout } else { timeout = config.Timeout } ret := &Client{ cli: &http.Client{Timeout: timeout}, config: config, } if jar != nil { ret.cli.Jar = jar } if xprt != nil { ret.cli.Transport = xprt } return ret }
func NewProxyAuthTransport(rawTransport *http.Transport) (*ProxyAuthTransport, error) { dialFn := rawTransport.Dial if dialFn == nil { dialFn = net.Dial } tr := &ProxyAuthTransport{Dial: dialFn} proxyUrlFn := rawTransport.Proxy if proxyUrlFn != nil { wrappedDialFn := tr.wrapTransportDial() proxyUrl, err := proxyUrlFn(nil) if err != nil { return nil, err } if proxyUrl.Scheme != "http" { return nil, fmt.Errorf("Only HTTP proxy supported, for SOCKS use http.Transport with custom dialers & upstreamproxy.NewProxyDialFunc") } tr.Username = proxyUrl.User.Username() tr.Password, _ = proxyUrl.User.Password() rawTransport.Dial = wrappedDialFn } tr.Transport = rawTransport return tr, nil }
// Initialise the http.Transport for pre go1.7 func (ci *ConfigInfo) initTransport(t *http.Transport) { t.Dial = func(network, address string) (net.Conn, error) { return dialTimeout(network, address, ci.ConnectTimeout, ci.Timeout) } }
BeforeEach(func() { port = "443" ua = "https://github.com/IBM-Bluemix/golang-openssl-wrapper" /* Fetch a single 8 character string in plaintext format */ requestContent = strings.Join([]string{ fmt.Sprintf("GET %s HTTP/1.1", resource), fmt.Sprintf("User-Agent: %s", ua), fmt.Sprintf("Host: %s", host), "Accept: */*", "\r\n", }, "\r\n") dest = host + ":" + port t = NewHTTPSTransport(nil) Expect(t).NotTo(BeNil()) conn, err := t.Dial("tcp", dest) Expect(err).NotTo(HaveOccurred()) h = conn.(HTTPSConn) }) Context("Using a bogus hostname and/or IP address", func() { var ip string JustBeforeEach(func() { /* Be sure your internal DNS isn't actually the SOA for ".bogus" */ host = "bogushost.bogus" dest = host + ":" + port /* Change this to an IP which cannot be resolved, which may depend on your specific network configuration */ ip = "10.100.10.100" }) It("Errors when the hostname is unresolveable", func() {