// Return a new http.RoundTripper with the given interceptors and a custom http.RoundTripper
// to perform the actual HTTP request. Interceptors will be called in the order they are
// provided.
554889
func TransportWith(transport http.RoundTripper, interceptors ...Interceptor) http.RoundTripper {
	return &interceptorRoundTripper{
		interceptors: append([]Interceptor{}, interceptors...),
		transport:    transport,
	}
}
1070153
func NewBearerAuthRoundTripper(token Secret, rt http.RoundTripper) http.RoundTripper {
	return &bearerAuthRoundTripper{token, rt}
}
1128153
func TransportFor(config *Config) (http.RoundTripper, error) {
	cfg, err := config.TransportConfig()
	if err != nil {
		return nil, err
	}
	return transport.New(cfg)
}
152764
func WrapRoundTripper(f func(http.RoundTripper) http.RoundTripper) ConfigOpt {
	return func(c *Config) {
		if f != nil {
			if rt := f(c.client.Transport); rt != nil {
				c.client.Transport = rt
			}
		}
	}
}
752872
func (m *MockTransport) RoundTrip(req *http.Request) (*http.Response, error) {
	url := req.URL.String()

	method := req.Method
	if method == "" {
		// http.Request.Method is documented to default to GET:
		method = http.MethodGet
	}

	var (
		responder  Responder
		respKey    routeKey
		submatches []string
	)
	key := routeKey{
		Method: method,
	}
	for _, getResponder := range []func(routeKey) (Responder, routeKey, []string){
		m.responderForKey,       // Exact match
		m.regexpResponderForKey, // Regexp match
	} {
		// try and get a responder that matches the method and URL with
		// query params untouched: http://z.tld/path?q...
		key.URL = url
		responder, respKey, submatches = getResponder(key)
		if responder != nil {
			break
		}

		// if we weren't able to find a responder, try with the URL *and*
		// sorted query params
		query := sortedQuery(req.URL.Query())
		if query != "" {
			// Replace unsorted query params by sorted ones:
			//   http://z.tld/path?sorted_q...
			key.URL = strings.Replace(url, req.URL.RawQuery, query, 1)
			responder, respKey, submatches = getResponder(key)
			if responder != nil {
				break
			}
		}

		// if we weren't able to find a responder, try without any query params
		strippedURL := *req.URL
		strippedURL.RawQuery = ""
		strippedURL.Fragment = ""

		// go1.6 does not handle URL.ForceQuery, so in case it is set in go>1.6,
		// remove the "?" manually if present.
		surl := strings.TrimSuffix(strippedURL.String(), "?")

		hasQueryString := url != surl

		// if the URL contains a querystring then we strip off the
		// querystring and try again: http://z.tld/path
		if hasQueryString {
			key.URL = surl
			responder, respKey, submatches = getResponder(key)
			if responder != nil {
				break
			}
		}

		// if we weren't able to find a responder for the full URL, try with
		// the path part only
		pathAlone := req.URL.Path

		// First with unsorted querystring: /path?q...
		if hasQueryString {
			key.URL = pathAlone + strings.TrimPrefix(url, surl) // concat after-path part
			responder, respKey, submatches = getResponder(key)
			if responder != nil {
				break
			}

			// Then with sorted querystring: /path?sorted_q...
			key.URL = pathAlone + "?" + sortedQuery(req.URL.Query())
			if req.URL.Fragment != "" {
				key.URL += "#" + req.URL.Fragment
			}
			responder, respKey, submatches = getResponder(key)
			if responder != nil {
				break
			}
		}

		// Then using path alone: /path
		key.URL = pathAlone
		responder, respKey, submatches = getResponder(key)
		if responder != nil {
			break
		}
	}

	m.mu.Lock()
	// if we found a responder, call it
	if responder != nil {
		m.callCountInfo[key]++
		if key != respKey {
			m.callCountInfo[respKey]++
		}
		m.totalCallCount++
	} else {
		// we didn't find a responder, so fire the 'no responder' responder
		if m.noResponder != nil {
			m.callCountInfo[noResponder]++
			m.totalCallCount++
			responder = m.noResponder
		}
	}
	m.mu.Unlock()

	if responder == nil {
		return ConnectionFailure(req)
	}
	return runCancelable(responder, setSubmatches(req, submatches))
}
631261
func NewHTTPTransport(r http.RoundTripper, scheme, addr string) Transport {
	return httpTransport{
		RoundTripper: r,
		scheme:       scheme,
		addr:         addr,
	}
}
220351
func (t *transport) RoundTrip(req *http.Request) (*http.Response, error) {
	req2 := cloneRequest(req)
	for _, modifier := range t.Modifiers {
		if err := modifier.ModifyRequest(req2); err != nil {
			return nil, err
		}
	}

	t.setModReq(req, req2)
	res, err := t.base().RoundTrip(req2)
	if err != nil {
		t.setModReq(req, nil)
		return nil, err
	}
	res.Body = &onEOFReader{
		rc: res.Body,
		fn: func() { t.setModReq(req, nil) },
	}
	return res, nil
}
1105529
func NewForwarder(f *Forwarder) *Forwarder {
	f.rewriter = &headerRewriter{}
	if f.RoundTripper == nil {
		f.RoundTripper = http.DefaultTransport
	}

	return f
}
1001087
func Wrappers(fns ...WrapperFunc) WrapperFunc {
	if len(fns) == 0 {
		return nil
	}
	// optimize the common case of wrapping a possibly nil transport wrapper
	// with an additional wrapper
	if len(fns) == 2 && fns[0] == nil {
		return fns[1]
	}
	return func(rt http.RoundTripper) http.RoundTripper {
		base := rt
		for _, fn := range fns {
			if fn != nil {
				base = fn(base)
			}
		}
		return base
	}
}
1196362
func (t *UnauthenticatedRateLimitedTransport) RoundTrip(req *http.Request) (*http.Response, error) {
	if t.ClientID == "" {
		return nil, errors.New("t.ClientID is empty")
	}
	if t.ClientSecret == "" {
		return nil, errors.New("t.ClientSecret is empty")
	}

	// To set extra querystring params, we must make a copy of the Request so
	// that we don't modify the Request we were given. This is required by the
	// specification of http.RoundTripper.
	//
	// Since we are going to modify only req.URL here, we only need a deep copy
	// of req.URL.
	req2 := new(http.Request)
	*req2 = *req
	req2.URL = new(url.URL)
	*req2.URL = *req.URL

	q := req2.URL.Query()
	q.Set("client_id", t.ClientID)
	q.Set("client_secret", t.ClientSecret)
	req2.URL.RawQuery = q.Encode()

	// Make the HTTP request.
	return t.transport().RoundTrip(req2)
}
1011180
func NewRoundTripperFromConfig(cfg HTTPClientConfig, name string) (http.RoundTripper, error) {
	newRT := func(tlsConfig *tls.Config) (http.RoundTripper, error) {
		// The only timeout we care about is the configured scrape timeout.
		// It is applied on request. So we leave out any timings here.
		var rt http.RoundTripper = &http.Transport{
			Proxy:               http.ProxyURL(cfg.ProxyURL.URL),
			MaxIdleConns:        20000,
			MaxIdleConnsPerHost: 1000, // see https://github.com/golang/go/issues/13801
			DisableKeepAlives:   false,
			TLSClientConfig:     tlsConfig,
			DisableCompression:  true,
			// 5 minutes is typically above the maximum sane scrape interval. So we can
			// use keepalive for all configurations.
			IdleConnTimeout:       5 * time.Minute,
			TLSHandshakeTimeout:   10 * time.Second,
			ExpectContinueTimeout: 1 * time.Second,
			DialContext: conntrack.NewDialContextFunc(
				conntrack.DialWithTracing(),
				conntrack.DialWithName(name),
			),
		}

		// If a bearer token is provided, create a round tripper that will set the
		// Authorization header correctly on each request.
		if len(cfg.BearerToken) > 0 {
			rt = NewBearerAuthRoundTripper(cfg.BearerToken, rt)
		} else if len(cfg.BearerTokenFile) > 0 {
			rt = NewBearerAuthFileRoundTripper(cfg.BearerTokenFile, rt)
		}

		if cfg.BasicAuth != nil {
			rt = NewBasicAuthRoundTripper(cfg.BasicAuth.Username, cfg.BasicAuth.Password, cfg.BasicAuth.PasswordFile, rt)
		}
		// Return a new configured RoundTripper.
		return rt, nil
	}

	tlsConfig, err := NewTLSConfig(&cfg.TLSConfig)
	if err != nil {
		return nil, err
	}

	if len(cfg.TLSConfig.CAFile) == 0 {
		// No need for a RoundTripper that reloads the CA file automatically.
		return newRT(tlsConfig)
	}

	return newTLSRoundTripper(tlsConfig, cfg.TLSConfig.CAFile, newRT)
}
1356967
func (l *HttpLocation) RoundTrip(req request.Request) (*http.Response, error) {
	// Get options and transport as one single read transaction.
	// Options and transport may change if someone calls SetOptions
	o, tr := l.GetOptionsAndTransport()
	originalRequest := req.GetHttpRequest()

	//  Check request size first, if that exceeds the limit, we don't bother reading the request.

	if l.isRequestOverLimit(req) {
		return nil, errors.FromStatus(http.StatusRequestEntityTooLarge)
	}

	// Read the body while keeping this location's limits in mind. This reader controls the maximum bytes
	// to read into memory and disk. This reader returns an error if the total request size exceeds the
	// prefefined MaxSizeBytes. This can occur if we got chunked request, in this case ContentLength would be set to -1
	// and the reader would be unbounded bufio in the http.Server
	body, err := netutils.NewBodyBufferWithOptions(originalRequest.Body, netutils.BodyBufferOptions{
		MemBufferBytes: o.Limits.MaxMemBodyBytes,
		MaxSizeBytes:   o.Limits.MaxBodyBytes,
	})
	if err != nil {
		return nil, err
	}
	if body == nil {
		return nil, fmt.Errorf("Empty body")
	}

	// Set request body to buffered reader that can replay the read and execute Seek
	req.SetBody(body)
	// Note that we don't change the original request Body as it's handled by the http server
	defer body.Close()

	for {
		_, err := req.GetBody().Seek(0, 0)
		if err != nil {
			return nil, err
		}

		endpoint, err := l.loadBalancer.NextEndpoint(req)
		if err != nil {
			log.Errorf("Load Balancer failure: %s", err)
			return nil, err
		}

		// Adds headers, changes urls. Note that we rewrite request each time we proxy it to the
		// endpoint, so that each try gets a fresh start
		req.SetHttpRequest(l.copyRequest(originalRequest, req.GetBody(), endpoint))
		// In case if error is not nil, we allow load balancer to choose the next endpoint
		// e.g. to do request failover. Nil error means that we got proxied the request successfully.
		response, err := l.proxyToEndpoint(tr, &o, endpoint, req)
		if o.FailoverPredicate(req) {
			continue
		} else {
			return response, err
		}
	}
	log.Errorf("All endpoints failed!")
	return nil, fmt.Errorf("All endpoints failed")
}
662595
func (a AWSSigningTransport) RoundTrip(req *http.Request) (*http.Response, error) {
	return a.HTTPClient.Do(awsauth.Sign4(req, a.Credentials))
}
756666
func (t *xrayTransport) RoundTrip(req *http.Request) (*http.Response, error) {
	s := ContextSegment(req.Context())
	if s == nil {
		return t.wrapped.RoundTrip(req)
	}

	sub := s.NewSubsegment(req.URL.Host)
	defer sub.Close()

	sub.RecordRequest(req, "remote")

	resp, err := t.wrapped.RoundTrip(req)

	if err != nil {
		sub.RecordError(err)
	} else {
		sub.RecordResponse(resp)
	}

	return resp, err
}
1173540
func (roundTripper UnixRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
	var conn net.Conn
	var err error
	if roundTripper.useTls {

		conn, err = tls.Dial("unix", roundTripper.path, roundTripper.tlsConfig)
		if err != nil {
			return nil, err
		}
		if conn == nil {
			return nil, errors.New("net/http: Transport.DialTLS returned (nil, nil)")
		}
		if tc, ok := conn.(*tls.Conn); ok {
			// Handshake here, in case DialTLS didn't. TLSNextProto below
			// depends on it for knowing the connection state.
			if err := tc.Handshake(); err != nil {
				go conn.Close()
				return nil, err
			}
		}
	} else {
		conn, err = net.Dial("unix", roundTripper.path)
		if err != nil {
			return nil, err
		}
	}

	socketClientConn := httputil.NewClientConn(conn, nil)
	defer socketClientConn.Close()

	newReq, err := roundTripper.rewriteRequest(req)
	if err != nil {
		return nil, err
	}

	return socketClientConn.Do(newReq)
}
384718
func (t *transport) RoundTrip(req *http.Request) (resp *http.Response, err error) {
	req.Header.Set("User-Agent", t.useragent)
	return t.RoundTripper.RoundTrip(req)
}
207398
func (t *transport) RoundTrip(req *http.Request) (res *http.Response, err error) {
	start := time.Now()
	rtrip := t.transport
	eng := t.eng

	if rtrip == nil {
		rtrip = http.DefaultTransport
	}

	if tags, ok := req.Context().Value(contextKeyReqTags).([]stats.Tag); ok {
		eng = eng.WithTags(tags...)
	}

	if req.Body == nil {
		req.Body = &nullBody{}
	}

	m := &metrics{}

	req.Body = &requestBody{
		eng:     eng,
		req:     req,
		metrics: m,
		body:    req.Body,
		op:      "write",
	}

	res, err = rtrip.RoundTrip(req)
	// safe guard, the transport should have done it already
	req.Body.Close() // nolint

	if err != nil {
		m.observeError(time.Now().Sub(start))
		eng.ReportAt(start, m)
	} else {
		res.Body = &responseBody{
			eng:     eng,
			res:     res,
			metrics: m,
			body:    res.Body,
			op:      "read",
			start:   start,
		}
	}

	return
}