From 91ffa4e99b00c157aba9fd311654fe17ed237e24 Mon Sep 17 00:00:00 2001 From: Mechiel Lukkien Date: Wed, 5 Jul 2023 12:54:24 +0200 Subject: [PATCH] fix progress reporting during import through the accounts web page the import was still processed, but the SSE connection to fetch progress did not work since adding the loggingWriter. found while working on other functionality that uses SSE. --- http/account.go | 2 +- http/web.go | 19 +++++++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/http/account.go b/http/account.go index 145f19e..251f219 100644 --- a/http/account.go +++ b/http/account.go @@ -129,7 +129,7 @@ func accountHandle(w http.ResponseWriter, r *http.Request) { flusher, ok := w.(http.Flusher) if !ok { log.Error("internal error: ResponseWriter not a http.Flusher") - http.Error(w, "500 - internal error - cannot sync to http connection", 500) + http.Error(w, "500 - internal error - cannot access underlying connection", 500) return } diff --git a/http/web.go b/http/web.go index b75dd0d..feee6f8 100644 --- a/http/web.go +++ b/http/web.go @@ -67,9 +67,14 @@ var ( // todo: automatic gzip on responses, if client supports it, content is not already compressed. in case of static file only if it isn't too large. skip for certain response content-types (image/*, video/*), or file extensions if there is no identifying content-type. if cpu load isn't too high. if first N kb look compressible and come in quickly enough after first byte (e.g. within 100ms). always flush after 100ms to prevent stalled real-time connections. +type responseWriterFlusher interface { + http.ResponseWriter + http.Flusher +} + // http.ResponseWriter that writes access log and tracks metrics at end of response. type loggingWriter struct { - W http.ResponseWriter // Calls are forwarded. + W responseWriterFlusher // Calls are forwarded. Start time.Time R *http.Request WebsocketRequest bool // Whether request from was websocket. @@ -84,6 +89,10 @@ type loggingWriter struct { SizeFromClient, SizeToClient int64 // Websocket data. } +func (w *loggingWriter) Flush() { + w.W.Flush() +} + func (w *loggingWriter) Header() http.Header { return w.W.Header() } @@ -277,8 +286,14 @@ func (s *serve) ServeHTTP(xw http.ResponseWriter, r *http.Request) { ctx := context.WithValue(r.Context(), mlog.CidKey, mox.Cid()) r = r.WithContext(ctx) + wf, ok := xw.(responseWriterFlusher) + if !ok { + http.Error(xw, "500 - internal server error - cannot access underlying connection"+recvid(r), http.StatusInternalServerError) + return + } + nw := &loggingWriter{ - W: xw, + W: wf, Start: now, R: r, }