Beispiel #1
0
// 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
}
Beispiel #2
0
// 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
}
Beispiel #3
0
// 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
}
Beispiel #5
0
// 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)
	}
}
Beispiel #6
0
// 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
}
Beispiel #7
0
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
}
Beispiel #8
0
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
}
Beispiel #9
0
// 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
}
Beispiel #10
0
// 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
}
Beispiel #11
0
// 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
}
Beispiel #12
0
// 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
}
Beispiel #13
0
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,
	}
}
Beispiel #14
0
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
}
Beispiel #16
0
// 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() {