in apmproxy/receiver.go [77:123]
func (c *Client) handleInfoRequest() (func(w http.ResponseWriter, r *http.Request), error) {
// Init reverse proxy
parsedApmServerURL, err := url.Parse(c.serverURL)
if err != nil {
return nil, fmt.Errorf("could not parse APM server URL: %w", err)
}
reverseProxy := httputil.NewSingleHostReverseProxy(parsedApmServerURL)
reverseProxy.Transport = c.client.Transport.(*http.Transport).Clone()
reverseProxy.ErrorHandler = func(w http.ResponseWriter, _ *http.Request, err error) {
// Don't update the status of the transport as it is possible that the extension
// is frozen while processing the request and context is canceled due to timeout.
c.logger.Errorf("Error querying version from the APM server: %v", err)
// Server is unreachable, return StatusBadGateway (default behavior) to avoid
// returning a Status OK.
w.WriteHeader(http.StatusBadGateway)
}
return func(w http.ResponseWriter, r *http.Request) {
c.logger.Debug("Handling APM server Info Request")
// Process request (the Golang doc suggests removing any pre-existing X-Forwarded-For header coming
// from the client or an untrusted proxy to prevent IP spoofing : https://pkg.go.dev/net/http/httputil#ReverseProxy
r.Header.Del("X-Forwarded-For")
// Update headers to allow for SSL redirection
r.URL.Host = parsedApmServerURL.Host
r.URL.Scheme = parsedApmServerURL.Scheme
r.Header.Set("X-Forwarded-Host", r.Header.Get("Host"))
reqAgent := r.UserAgent()
r.Header.Set("User-Agent", version.UserAgent+" "+reqAgent)
r.Host = parsedApmServerURL.Host
// Override authorization header sent by the APM agents
if c.ServerAPIKey != "" {
r.Header.Add("Authorization", "ApiKey "+c.ServerAPIKey)
} else if c.ServerSecretToken != "" {
r.Header.Add("Authorization", "Bearer "+c.ServerSecretToken)
}
// Forward request to the APM server
reverseProxy.ServeHTTP(w, r)
}, nil
}