fix nil pointer error in roundtripper

This commit is contained in:
Alisdair MacLeod
2026-02-12 15:19:19 +00:00
parent db5e26db94
commit 41a5509ce0
2 changed files with 75 additions and 5 deletions

View File

@@ -106,15 +106,21 @@ func (f roundTripperFunc) RoundTrip(r *http.Request) (*http.Response, error) {
func (m *Metrics) RoundTripper(next http.RoundTripper) http.RoundTripper {
return roundTripperFunc(func(req *http.Request) (*http.Response, error) {
start := time.Now()
res, err := next.RoundTrip(req)
duration := time.Since(start)
labels := prometheus.Labels{
"method": req.Method,
"host": req.Host,
"path": req.URL.Path,
// Fill potentially empty labels with default values to avoid cardinality issues.
"path": "/",
"status": "0",
"size": "0",
}
if req.URL != nil {
labels["path"] = req.URL.Path
}
start := time.Now()
res, err := next.RoundTrip(req)
duration := time.Since(start)
// Not all labels will be available if there was an error.
if res != nil {

View File

@@ -0,0 +1,64 @@
package metrics_test
import (
"net/http"
"net/url"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/netbirdio/netbird/proxy/internal/metrics"
"github.com/prometheus/client_golang/prometheus"
)
type testRoundTripper struct {
response *http.Response
err error
}
func (t *testRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
return t.response, t.err
}
func TestMetrics_RoundTripper(t *testing.T) {
testResponse := http.Response{
StatusCode: http.StatusOK,
Body: http.NoBody,
}
tests := map[string]struct {
roundTripper http.RoundTripper
request *http.Request
response *http.Response
err error
}{
"ok": {
roundTripper: &testRoundTripper{response: &testResponse},
request: &http.Request{Method: "GET", URL: &url.URL{Path: "/foo"}},
response: &testResponse,
},
"nil url": {
roundTripper: &testRoundTripper{response: &testResponse},
request: &http.Request{Method: "GET", URL: nil},
response: &testResponse,
},
"nil response": {
roundTripper: &testRoundTripper{response: nil},
request: &http.Request{Method: "GET", URL: &url.URL{Path: "/foo"}},
},
}
m := metrics.New(prometheus.NewRegistry())
for name, test := range tests {
t.Run(name, func(t *testing.T) {
rt := m.RoundTripper(test.roundTripper)
res, err := rt.RoundTrip(test.request)
if diff := cmp.Diff(test.err, err); diff != "" {
t.Errorf("Incorrect error (-want +got):\n%s", diff)
}
if diff := cmp.Diff(test.response, res); diff != "" {
t.Errorf("Incorrect response (-want +got):\n%s", diff)
}
})
}
}