func()

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
}