mirror of
https://github.com/netbirdio/netbird.git
synced 2026-04-18 16:26:38 +00:00
fix nil pointer error in roundtripper
This commit is contained in:
@@ -106,15 +106,21 @@ func (f roundTripperFunc) RoundTrip(r *http.Request) (*http.Response, error) {
|
|||||||
|
|
||||||
func (m *Metrics) RoundTripper(next http.RoundTripper) http.RoundTripper {
|
func (m *Metrics) RoundTripper(next http.RoundTripper) http.RoundTripper {
|
||||||
return roundTripperFunc(func(req *http.Request) (*http.Response, error) {
|
return roundTripperFunc(func(req *http.Request) (*http.Response, error) {
|
||||||
start := time.Now()
|
|
||||||
res, err := next.RoundTrip(req)
|
|
||||||
duration := time.Since(start)
|
|
||||||
|
|
||||||
labels := prometheus.Labels{
|
labels := prometheus.Labels{
|
||||||
"method": req.Method,
|
"method": req.Method,
|
||||||
"host": req.Host,
|
"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.
|
// Not all labels will be available if there was an error.
|
||||||
if res != nil {
|
if res != nil {
|
||||||
|
|||||||
64
proxy/internal/metrics/metrics_test.go
Normal file
64
proxy/internal/metrics/metrics_test.go
Normal 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)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user