in handler/proxy_client.go [89:161]
func (p *ProxyClient) Do(req *http.Request) (*http.Response, error) {
proxyURL := *req.URL
if p.HostOverride != "" {
proxyURL.Host = p.HostOverride
} else {
proxyURL.Host = req.Host
}
proxyURL.Scheme = "https"
if log.GetLevel() == log.DebugLevel {
initialReqDump, err := httputil.DumpRequest(req, true)
if err != nil {
log.WithError(err).Error("unable to dump request")
}
log.WithField("request", string(initialReqDump)).Debug("Initial request dump:")
}
proxyReq, err := http.NewRequest(req.Method, proxyURL.String(), req.Body)
if err != nil {
return nil, err
}
var service *endpoints.ResolvedEndpoint
if p.SigningNameOverride != "" && p.RegionOverride != "" {
service = &endpoints.ResolvedEndpoint{URL: fmt.Sprintf("https://%s", proxyURL.Host), SigningMethod: "v4", SigningRegion: p.RegionOverride, SigningName: p.SigningNameOverride}
} else {
service = determineAWSServiceFromHost(req.Host)
}
if service == nil {
return nil, fmt.Errorf("unable to determine service from host: %s", req.Host)
}
if err := p.sign(proxyReq, service); err != nil {
return nil, err
}
// Remove any headers specified
for _, header := range p.StripRequestHeaders {
log.WithField("StripHeader", string(header)).Debug("Stripping Header:")
req.Header.Del(header)
}
// Add origin headers after request is signed (no overwrite)
copyHeaderWithoutOverwrite(proxyReq.Header, req.Header)
if log.GetLevel() == log.DebugLevel {
proxyReqDump, err := httputil.DumpRequest(proxyReq, true)
if err != nil {
log.WithError(err).Error("unable to dump request")
}
log.WithField("request", string(proxyReqDump)).Debug("proxying request")
}
resp, err := p.Client.Do(proxyReq)
if err != nil {
return nil, err
}
if (p.LogFailedRequest || log.GetLevel() == log.DebugLevel) && resp.StatusCode >= 400 {
b, _ := ioutil.ReadAll(resp.Body)
log.WithField("request", fmt.Sprintf("%s %s", proxyReq.Method, proxyReq.URL)).
WithField("status_code", resp.StatusCode).
WithField("message", string(b)).
Error("error proxying request")
// Need to "reset" the response body because we consumed the stream above, otherwise caller will
// get empty body.
resp.Body = ioutil.NopCloser(bytes.NewBuffer(b))
}
return resp, nil
}