From 8224204c9ff84c4f23401af45e41e62cd75ddaae Mon Sep 17 00:00:00 2001 From: Christopher Petito <47751006+krissetto@users.noreply.github.com> Date: Mon, 15 Apr 2024 09:46:08 +0000 Subject: [PATCH] Write headers manually for streaming response writers before calling Flush() Signed-off-by: Christopher Petito <47751006+krissetto@users.noreply.github.com> --- api/server/httputils/write_log_stream.go | 8 +++++++- daemon/stats.go | 7 +++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/api/server/httputils/write_log_stream.go b/api/server/httputils/write_log_stream.go index 8faacc029e..c7e2d0a8a4 100644 --- a/api/server/httputils/write_log_stream.go +++ b/api/server/httputils/write_log_stream.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "io" + "net/http" "net/url" "sort" @@ -17,9 +18,14 @@ import ( // WriteLogStream writes an encoded byte stream of log messages from the // messages channel, multiplexing them with a stdcopy.Writer if mux is true func WriteLogStream(_ context.Context, w io.Writer, msgs <-chan *backend.LogMessage, config *container.LogsOptions, mux bool) { + // Used before the Flush(), so we don't set the header twice because of the otel wrapper + // see here: https://github.com/moby/moby/issues/47448 + if rw, ok := w.(http.ResponseWriter); ok { + rw.WriteHeader(http.StatusOK) + } + wf := ioutils.NewWriteFlusher(w) defer wf.Close() - wf.Flush() outStream := io.Writer(wf) diff --git a/daemon/stats.go b/daemon/stats.go index 5dcd6121d4..daf6b2dce2 100644 --- a/daemon/stats.go +++ b/daemon/stats.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "errors" + "net/http" "runtime" "time" @@ -46,6 +47,12 @@ func (daemon *Daemon) ContainerStats(ctx context.Context, prefixOrName string, c outStream := config.OutStream if config.Stream { + // Used before the Flush(), so we don't set the header twice because of the otel wrapper + // see here: https://github.com/moby/moby/issues/47448 + if rw, ok := outStream.(http.ResponseWriter); ok { + rw.WriteHeader(http.StatusOK) + } + wf := ioutils.NewWriteFlusher(outStream) defer wf.Close() wf.Flush()