diff --git a/CHANGELOG.md b/CHANGELOG.md index 74d7a6d91d..eb71db7d43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ We use _breaking :warning:_ to mark changes that are not backward compatible (re ### Fixed - [#3204](https://github.com/thanos-io/thanos/pull/3204) Mixin: Use sidecar's metric timestamp for healthcheck. +- [#3922](https://github.com/thanos-io/thanos/pull/3922) Fix panic in http logging middleware. ### Changed diff --git a/pkg/logging/http.go b/pkg/logging/http.go index 305ca5a340..2e6d6a9d0d 100644 --- a/pkg/logging/http.go +++ b/pkg/logging/http.go @@ -5,8 +5,8 @@ package logging import ( "fmt" + "net" "sort" - "strings" "net/http" "time" @@ -39,7 +39,12 @@ func (m *HTTPServerMiddleware) HTTPMiddleware(name string, next http.Handler) ht return func(w http.ResponseWriter, r *http.Request) { wrapped := httputil.WrapResponseWriterWithStatus(w) start := time.Now() - port := strings.Split(r.Host, ":")[1] + _, port, err := net.SplitHostPort(r.Host) + if err != nil { + level.Error(m.logger).Log("msg", "failed to parse host port for http log decision", "err", err) + next.ServeHTTP(w, r) + return + } decision := m.opts.shouldLog(fmt.Sprintf("%s:%s", r.URL, port), nil) diff --git a/pkg/logging/http_test.go b/pkg/logging/http_test.go new file mode 100644 index 0000000000..73e7b0225d --- /dev/null +++ b/pkg/logging/http_test.go @@ -0,0 +1,37 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +package logging + +import ( + "io" + "io/ioutil" + "net/http" + "net/http/httptest" + "testing" + + "github.com/go-kit/kit/log" + "github.com/thanos-io/thanos/pkg/testutil" +) + +func TestHTTPServerMiddleware(t *testing.T) { + m := NewHTTPServerMiddleware(log.NewNopLogger()) + handler := func(w http.ResponseWriter, r *http.Request) { + _, err := io.WriteString(w, "Test Works") + if err != nil { + t.Log(err) + } + } + hm := m.HTTPMiddleware("test", http.HandlerFunc(handler)) + + req := httptest.NewRequest("GET", "http://example.com/foo", nil) + w := httptest.NewRecorder() + + hm(w, req) + + resp := w.Result() + body, _ := ioutil.ReadAll(resp.Body) + + testutil.Equals(t, 200, resp.StatusCode) + testutil.Equals(t, "Test Works", string(body)) +}