Skip to content

Commit 8f5b893

Browse files
jlvoiseuxestolfo
andauthored
Retrieve APM Server info with a reverse proxy (#152)
* Implement reverse proxy * Update headers to allow for SSL redirection * Correct comment typo Co-authored-by: Emily S <emily.s@elastic.co> Co-authored-by: Emily S <emily.s@elastic.co>
1 parent ff09298 commit 8f5b893

File tree

1 file changed

+16
-39
lines changed

1 file changed

+16
-39
lines changed

apm-lambda-extension/extension/route_handlers.go

Lines changed: 16 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@
1818
package extension
1919

2020
import (
21-
"io"
2221
"io/ioutil"
2322
"net/http"
23+
"net/http/httputil"
24+
"net/url"
2425
)
2526

2627
type AgentData struct {
@@ -33,51 +34,27 @@ var AgentDoneSignal chan struct{}
3334
// URL: http://server/
3435
func handleInfoRequest(apmServerUrl string) func(w http.ResponseWriter, r *http.Request) {
3536
return func(w http.ResponseWriter, r *http.Request) {
36-
client := &http.Client{}
3737

38-
req, err := http.NewRequest(r.Method, apmServerUrl, nil)
38+
// Init reverse proxy
39+
parsedApmServerUrl, err := url.Parse(apmServerUrl)
3940
if err != nil {
40-
Log.Errorf("could not create request object for %s:%s: %v", r.Method, apmServerUrl, err)
41-
w.WriteHeader(http.StatusInternalServerError)
42-
return
43-
}
44-
45-
//forward every header received
46-
for name, values := range r.Header {
47-
// Loop over all values for the name.
48-
for _, value := range values {
49-
req.Header.Set(name, value)
50-
}
51-
}
52-
53-
// Send request to apm server
54-
serverResp, err := client.Do(req)
55-
if err != nil {
56-
Log.Errorf("error forwarding info request (`/`) to APM Server: %v", err)
41+
Log.Errorf("could not parse APM server URL: %v", err)
5742
return
5843
}
59-
defer serverResp.Body.Close()
44+
reverseProxy := httputil.NewSingleHostReverseProxy(parsedApmServerUrl)
6045

61-
// If WriteHeader is not called explicitly, the first call to Write
62-
// will trigger an implicit WriteHeader(http.StatusOK).
63-
if serverResp.StatusCode != 200 {
64-
w.WriteHeader(serverResp.StatusCode)
65-
}
46+
// Process request (the Golang doc suggests removing any pre-existing X-Forwarded-For header coming
47+
// from the client or an untrusted proxy to prevent IP spoofing : https://pkg.go.dev/net/http/httputil#ReverseProxy
48+
r.Header.Del("X-Forwarded-For")
6649

67-
// send every header received
68-
for name, values := range serverResp.Header {
69-
// Loop over all values for the name.
70-
for _, value := range values {
71-
w.Header().Add(name, value)
72-
}
73-
}
50+
// Update headers to allow for SSL redirection
51+
r.URL.Host = parsedApmServerUrl.Host
52+
r.URL.Scheme = parsedApmServerUrl.Scheme
53+
r.Header.Set("X-Forwarded-Host", r.Header.Get("Host"))
54+
r.Host = parsedApmServerUrl.Host
7455

75-
// copy body to request sent back to the agent
76-
_, err = io.Copy(w, serverResp.Body)
77-
if err != nil {
78-
Log.Errorf("could not read info request response to APM Server: %v", err)
79-
return
80-
}
56+
// Forward request to the APM server
57+
reverseProxy.ServeHTTP(w, r)
8158
}
8259
}
8360

0 commit comments

Comments
 (0)