client.go
func (c *Client) Do(req *Request, resp *Response) error {
	uri := req.URI()
	host := uri.Host()

	isTLS := false
	scheme := uri.Scheme()
	if bytes.Equal(scheme, strHTTPS) {
		isTLS = true
	} else if !bytes.Equal(scheme, strHTTP) {
		return fmt.Errorf("unsupported protocol %q. http and https are supported", scheme)
	}

	startCleaner := false

	c.mLock.Lock()
	m := c.m
	if isTLS {
		m = c.ms
	}
	if m == nil {
		m = make(map[string]*HostClient)
		if isTLS {
			c.ms = m
		} else {
			c.m = m
		}
	}
	hc := m[string(host)]
	if hc == nil {
		hc = &HostClient{
			Addr:                          addMissingPort(string(host), isTLS),
			Name:                          c.Name,
			NoDefaultUserAgentHeader:      c.NoDefaultUserAgentHeader,
			Dial:                          c.Dial,
			DialDualStack:                 c.DialDualStack,
			IsTLS:                         isTLS,
			TLSConfig:                     c.TLSConfig,
			MaxConns:                      c.MaxConnsPerHost,
			MaxIdleConnDuration:           c.MaxIdleConnDuration,
			MaxIdemponentCallAttempts:     c.MaxIdemponentCallAttempts,
			ReadBufferSize:                c.ReadBufferSize,
			WriteBufferSize:               c.WriteBufferSize,
			ReadTimeout:                   c.ReadTimeout,
			WriteTimeout:                  c.WriteTimeout,
			MaxResponseBodySize:           c.MaxResponseBodySize,
			DisableHeaderNamesNormalizing: c.DisableHeaderNamesNormalizing,
		}
		m[string(host)] = hc
		if len(m) == 1 {
			startCleaner = true
		}
	}
	c.mLock.Unlock()

	if startCleaner {
		go c.mCleaner(m)
	}

	return hc.Do(req, resp)
}
func (c *Client) Do(req *Request, resp *Response) error {
	uri := req.URI()
	host := uri.Host()

	isTLS := false
	scheme := uri.Scheme()
	if bytes.Equal(scheme, strHTTPS) {
		isTLS = true
	} else if !bytes.Equal(scheme, strHTTP) {
		return fmt.Errorf("unsupported protocol %q. http and https are supported", scheme)
	}

	startCleaner := false

	c.mLock.Lock()
	m := c.m
	if isTLS {
		m = c.ms
	}
	if m == nil {
		m = make(map[string]*HostClient)
		if isTLS {
			c.ms = m
		} else {
			c.m = m
		}
	}
	hc := m[string(host)]
	if hc == nil {
		hc = &HostClient{
			Addr:                          addMissingPort(string(host), isTLS),
			Name:                          c.Name,
			NoDefaultUserAgentHeader:      c.NoDefaultUserAgentHeader,
			Dial:                          c.Dial,
			DialDualStack:                 c.DialDualStack,
			IsTLS:                         isTLS,
			TLSConfig:                     c.TLSConfig,
			MaxConns:                      c.MaxConnsPerHost,
			MaxIdleConnDuration:           c.MaxIdleConnDuration,
			MaxIdemponentCallAttempts:     c.MaxIdemponentCallAttempts,
			ReadBufferSize:                c.ReadBufferSize,
			WriteBufferSize:               c.WriteBufferSize,
			ReadTimeout:                   c.ReadTimeout,
			WriteTimeout:                  c.WriteTimeout,
			MaxResponseBodySize:           c.MaxResponseBodySize,
			DisableHeaderNamesNormalizing: c.DisableHeaderNamesNormalizing,
		}
		m[string(host)] = hc
		if len(m) == 1 {
			startCleaner = true
		}
	}
	c.mLock.Unlock()

	if startCleaner {
		go c.mCleaner(m)
	}

	return hc.Do(req, resp)
}
func ( c * Client ) Do ( req * Request , resp * Response ) error { uri := req . URI ( ) host := uri . Host ( ) isTLS := false scheme := uri . Scheme ( ) if bytes . Equal ( scheme , strHTTPS ) { isTLS = true } else if ! bytes . Equal ( scheme , strHTTP ) { return fmt . Errorf ( " " , scheme ) } startCleaner := false c . mLock . Lock ( ) m := c . m if isTLS { m = c . ms } if m == nil { m = make ( map [ string ] * HostClient ) if isTLS { c . ms = m } else { c . m = m } } hc := m [ string ( host ) ] if hc == nil { hc = & HostClient { Addr : addMissingPort ( string ( host ) , isTLS ) , Name : c . Name , NoDefaultUserAgentHeader : c . NoDefaultUserAgentHeader , Dial : c . Dial , DialDualStack : c . DialDualStack , IsTLS : isTLS , TLSConfig : c . TLSConfig , MaxConns : c . MaxConnsPerHost , MaxIdleConnDuration : c . MaxIdleConnDuration , MaxIdemponentCallAttempts : c . MaxIdemponentCallAttempts , ReadBufferSize : c . ReadBufferSize , WriteBufferSize : c . WriteBufferSize , ReadTimeout : c . ReadTimeout , WriteTimeout : c . WriteTimeout , MaxResponseBodySize : c . MaxResponseBodySize , DisableHeaderNamesNormalizing : c . DisableHeaderNamesNormalizing , } m [ string ( host ) ] = hc if len ( m ) == 1 { startCleaner = true } } c . mLock . Unlock ( ) if startCleaner { go c . mCleaner ( m ) } return hc . Do ( req , resp ) }
// Do performs the given http request and fills the given http response.
//
// Request must contain at least non-zero RequestURI with full url (including
// scheme and host) or non-zero Host header + RequestURI.
//
// Client determines the server to be requested in the following order:
//
//   - from RequestURI if it contains full url with scheme and host;
//   - from Host header otherwise.
//
// Response is ignored if resp is nil.
//
// The function doesn't follow redirects. Use Get* for following redirects.
//
// ErrNoFreeConns is returned if all Client.MaxConnsPerHost connections
// to the requested host are busy.
//
// It is recommended obtaining req and resp via AcquireRequest
// and AcquireResponse in performance-critical code.
Do performs the given http request and fills the given http response . Request must contain at least non - zero RequestURI with full url ( including scheme and host ) or non - zero Host header + RequestURI . Client determines the server to be requested in the following order : - from RequestURI if it contains full url with scheme and host ; - from Host header otherwise . Response is ignored if resp is nil . The function doesn t follow redirects . Use Get * for following redirects . ErrNoFreeConns is returned if all Client . MaxConnsPerHost connections to the requested host are busy . It is recommended obtaining req and resp via AcquireRequest and AcquireResponse in performance - critical code .