func (r *requestInfo) complete(response *http.Response, err error) {
	if err != nil {
		r.ResponseErr = err
		return
	}
	r.ResponseStatus = response.Status
	r.ResponseHeaders = response.Header
}
complete adds information about the response to the requestInfo
package transport
import (
	"fmt"
	"net/http"
	"strings"
	"time"
	"github.com/golang/glog"
	utilnet "k8s.io/apimachinery/pkg/util/net"
)
func HTTPWrappersForConfig(config *Config, rt http.RoundTripper) (http.RoundTripper, error) {
	if config.WrapTransport != nil {
		rt = config.WrapTransport(rt)
	}
	rt = DebugWrappers(rt)
	switch {
	case config.HasBasicAuth() && config.HasTokenAuth():
		return nil, fmt.Errorf("username/password or bearer token may be set, but not both")
	case config.HasTokenAuth():
		rt = NewBearerAuthRoundTripper(config.BearerToken, rt)
	case config.HasBasicAuth():
		rt = NewBasicAuthRoundTripper(config.Username, config.Password, rt)
	}
	if len(config.UserAgent) > 0 {
		rt = NewUserAgentRoundTripper(config.UserAgent, rt)
	}
	if len(config.Impersonate.UserName) > 0 ||
		len(config.Impersonate.Groups) > 0 ||
		len(config.Impersonate.Extra) > 0 {
		rt = NewImpersonatingRoundTripper(config.Impersonate, rt)
	}
	return rt, nil
}
func DebugWrappers(rt http.RoundTripper) http.RoundTripper {
	switch {
	case bool(glog.V(9)):
		rt = newDebuggingRoundTripper(rt, debugCurlCommand, debugURLTiming, debugResponseHeaders)
	case bool(glog.V(8)):
		rt = newDebuggingRoundTripper(rt, debugJustURL, debugRequestHeaders, debugResponseStatus, debugResponseHeaders)
	case bool(glog.V(7)):
		rt = newDebuggingRoundTripper(rt, debugJustURL, debugRequestHeaders, debugResponseStatus)
	case bool(glog.V(6)):
		rt = newDebuggingRoundTripper(rt, debugURLTiming)
	}
	return rt
}
type requestCanceler interface {
	CancelRequest(*http.Request)
}
type authProxyRoundTripper struct {
	username string
	groups   []string
	extra    map[string][]string
	rt http.RoundTripper
}
func NewAuthProxyRoundTripper(username string, groups []string, extra map[string][]string, rt http.RoundTripper) http.RoundTripper {
	return &authProxyRoundTripper{
		username: username,
		groups:   groups,
		extra:    extra,
		rt:       rt,
	}
}
func (rt *authProxyRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
	req = utilnet.CloneRequest(req)
	SetAuthProxyHeaders(req, rt.username, rt.groups, rt.extra)
	return rt.rt.RoundTrip(req)
}
func SetAuthProxyHeaders(req *http.Request, username string, groups []string, extra map[string][]string) {
	req.Header.Del("X-Remote-User")
	req.Header.Del("X-Remote-Group")
	for key := range req.Header {
		if strings.HasPrefix(strings.ToLower(key), strings.ToLower("X-Remote-Extra-")) {
			req.Header.Del(key)
		}
	}
	req.Header.Set("X-Remote-User", username)
	for _, group := range groups {
		req.Header.Add("X-Remote-Group", group)
	}
	for key, values := range extra {
		for _, value := range values {
			req.Header.Add("X-Remote-Extra-"+key, value)
		}
	}
}
func (rt *authProxyRoundTripper) CancelRequest(req *http.Request) {
	if canceler, ok := rt.rt.(requestCanceler); ok {
		canceler.CancelRequest(req)
	} else {
		glog.Errorf("CancelRequest not implemented")
	}
}
func (rt *authProxyRoundTripper) WrappedRoundTripper() http.RoundTripper { return rt.rt }
type userAgentRoundTripper struct {
	agent string
	rt    http.RoundTripper
}
func NewUserAgentRoundTripper(agent string, rt http.RoundTripper) http.RoundTripper {
	return &userAgentRoundTripper{agent, rt}
}
func (rt *userAgentRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
	if len(req.Header.Get("User-Agent")) != 0 {
		return rt.rt.RoundTrip(req)
	}
	req = utilnet.CloneRequest(req)
	req.Header.Set("User-Agent", rt.agent)
	return rt.rt.RoundTrip(req)
}
func (rt *userAgentRoundTripper) CancelRequest(req *http.Request) {
	if canceler, ok := rt.rt.(requestCanceler); ok {
		canceler.CancelRequest(req)
	} else {
		glog.Errorf("CancelRequest not implemented")
	}
}
func (rt *userAgentRoundTripper) WrappedRoundTripper() http.RoundTripper { return rt.rt }
type basicAuthRoundTripper struct {
	username string
	password string
	rt       http.RoundTripper
}
func NewBasicAuthRoundTripper(username, password string, rt http.RoundTripper) http.RoundTripper {
	return &basicAuthRoundTripper{username, password, rt}
}
func (rt *basicAuthRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
	if len(req.Header.Get("Authorization")) != 0 {
		return rt.rt.RoundTrip(req)
	}
	req = utilnet.CloneRequest(req)
	req.SetBasicAuth(rt.username, rt.password)
	return rt.rt.RoundTrip(req)
}
func (rt *basicAuthRoundTripper) CancelRequest(req *http.Request) {
	if canceler, ok := rt.rt.(requestCanceler); ok {
		canceler.CancelRequest(req)
	} else {
		glog.Errorf("CancelRequest not implemented")
	}
}
func (rt *basicAuthRoundTripper) WrappedRoundTripper() http.RoundTripper { return rt.rt }
const (
	ImpersonateUserHeader = "Impersonate-User"
	ImpersonateGroupHeader = "Impersonate-Group"
	ImpersonateUserExtraHeaderPrefix = "Impersonate-Extra-"
)
type impersonatingRoundTripper struct {
	impersonate ImpersonationConfig
	delegate    http.RoundTripper
}
func NewImpersonatingRoundTripper(impersonate ImpersonationConfig, delegate http.RoundTripper) http.RoundTripper {
	return &impersonatingRoundTripper{impersonate, delegate}
}
func (rt *impersonatingRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
	if len(req.Header.Get(ImpersonateUserHeader)) != 0 {
		return rt.delegate.RoundTrip(req)
	}
	req = utilnet.CloneRequest(req)
	req.Header.Set(ImpersonateUserHeader, rt.impersonate.UserName)
	for _, group := range rt.impersonate.Groups {
		req.Header.Add(ImpersonateGroupHeader, group)
	}
	for k, vv := range rt.impersonate.Extra {
		for _, v := range vv {
			req.Header.Add(ImpersonateUserExtraHeaderPrefix+k, v)
		}
	}
	return rt.delegate.RoundTrip(req)
}
func (rt *impersonatingRoundTripper) CancelRequest(req *http.Request) {
	if canceler, ok := rt.delegate.(requestCanceler); ok {
		canceler.CancelRequest(req)
	} else {
		glog.Errorf("CancelRequest not implemented")
	}
}
func (rt *impersonatingRoundTripper) WrappedRoundTripper() http.RoundTripper { return rt.delegate }
type bearerAuthRoundTripper struct {
	bearer string
	rt     http.RoundTripper
}
func NewBearerAuthRoundTripper(bearer string, rt http.RoundTripper) http.RoundTripper {
	return &bearerAuthRoundTripper{bearer, rt}
}
func (rt *bearerAuthRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
	if len(req.Header.Get("Authorization")) != 0 {
		return rt.rt.RoundTrip(req)
	}
	req = utilnet.CloneRequest(req)
	req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", rt.bearer))
	return rt.rt.RoundTrip(req)
}
func (rt *bearerAuthRoundTripper) CancelRequest(req *http.Request) {
	if canceler, ok := rt.rt.(requestCanceler); ok {
		canceler.CancelRequest(req)
	} else {
		glog.Errorf("CancelRequest not implemented")
	}
}
func (rt *bearerAuthRoundTripper) WrappedRoundTripper() http.RoundTripper { return rt.rt }
type requestInfo struct {
	RequestHeaders http.Header
	RequestVerb    string
	RequestURL     string
	ResponseStatus  string
	ResponseHeaders http.Header
	ResponseErr     error
	Duration time.Duration
}
func newRequestInfo(req *http.Request) *requestInfo {
	return &requestInfo{
		RequestURL:     req.URL.String(),
		RequestVerb:    req.Method,
		RequestHeaders: req.Header,
	}
}