From ab1bab5ca26f3b8144b2af6f410fc05dfea34cde Mon Sep 17 00:00:00 2001 From: Mostafa Moradian Date: Sun, 24 Sep 2023 22:42:06 +0200 Subject: [PATCH] Fix bug in writing headers twice when serving metrics --- cmd/run.go | 9 ++++++++- metrics/utils.go | 19 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 metrics/utils.go diff --git a/cmd/run.go b/cmd/run.go index ea0bfaf3..810373f3 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -352,7 +352,14 @@ var runCmd = &cobra.Command{ span.RecordError(err) sentry.CaptureException(err) } - next.ServeHTTP(responseWriter, request) + // The WriteHeader method intentionally does nothing, to prevent a bug + // in the merging metrics that causes the headers to be written twice, + // which results in an error: "http: superfluous response.WriteHeader call". + next.ServeHTTP( + &metrics.HeaderBypassResponseWriter{ + ResponseWriter: responseWriter, + }, + request) } return http.HandlerFunc(handler) } diff --git a/metrics/utils.go b/metrics/utils.go new file mode 100644 index 00000000..8227c35b --- /dev/null +++ b/metrics/utils.go @@ -0,0 +1,19 @@ +package metrics + +import "net/http" + +// HeaderBypassResponseWriter implements the http.ResponseWriter interface +// and allows us to bypass the response header when writing to the response. +// This is useful for merging metrics from multiple sources. +type HeaderBypassResponseWriter struct { + http.ResponseWriter +} + +// WriteHeader intentionally does nothing, but is required to +// implement the http.ResponseWriter. +func (w *HeaderBypassResponseWriter) WriteHeader(code int) {} + +// Write writes the data to the response. +func (w *HeaderBypassResponseWriter) Write(data []byte) (int, error) { + return w.ResponseWriter.Write(data) +}