From f7d0950ca1f6542c114789271f95761911daf1e5 Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Thu, 14 Nov 2019 10:49:21 +0100 Subject: [PATCH] *: write and flush header on log handlers Explicitly write and flush the headers in the various services LogHandlers. Currently the 200 response and the other headers will be automatically written by the golang http implementation only when we send something in the body. But if there's nothing to send (no logs yet written) the client will never receive the headers and cannot know if the request was successful. --- internal/services/executor/api.go | 7 +++++++ internal/services/gateway/api/run.go | 10 ++++++++++ internal/services/runservice/api/api.go | 16 +++++++++++++--- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/internal/services/executor/api.go b/internal/services/executor/api.go index 8ed4864..76a89cc 100644 --- a/internal/services/executor/api.go +++ b/internal/services/executor/api.go @@ -137,10 +137,17 @@ func (h *logsHandler) readLogs(taskID string, setup bool, step int, logPath stri w.Header().Set("Content-Length", strconv.FormatInt(fi.Size(), 10)) } + // write and flush the headers so the client will receive the response + // header also if there're currently no lines to send + w.WriteHeader(http.StatusOK) var flusher http.Flusher if fl, ok := w.(http.Flusher); ok { flusher = fl } + if flusher != nil { + flusher.Flush() + } + stop := false flushstop := false for { diff --git a/internal/services/gateway/api/run.go b/internal/services/gateway/api/run.go index 0bcb874..d735b17 100644 --- a/internal/services/gateway/api/run.go +++ b/internal/services/gateway/api/run.go @@ -451,8 +451,18 @@ func (h *LogsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } + // write and flush the headers so the client will receive the response + // header also if there're currently no lines to send w.Header().Set("Cache-Control", "no-cache") w.Header().Set("Connection", "keep-alive") + w.WriteHeader(http.StatusOK) + var flusher http.Flusher + if fl, ok := w.(http.Flusher); ok { + flusher = fl + } + if flusher != nil { + flusher.Flush() + } defer resp.Body.Close() if err := sendLogs(w, resp.Body); err != nil { diff --git a/internal/services/runservice/api/api.go b/internal/services/runservice/api/api.go index a125788..90d8f99 100644 --- a/internal/services/runservice/api/api.go +++ b/internal/services/runservice/api/api.go @@ -275,13 +275,23 @@ func (h *LogsHandler) readTaskLogs(ctx context.Context, runID, taskID string, se return errors.Errorf("received http status: %d", req.StatusCode), true } + // write and flush the headers so the client will receive the response + // header also if there're currently no lines to send + w.Header().Set("Cache-Control", "no-cache") + w.Header().Set("Connection", "keep-alive") + w.WriteHeader(http.StatusOK) + var flusher http.Flusher + if fl, ok := w.(http.Flusher); ok { + flusher = fl + } + if flusher != nil { + flusher.Flush() + } + return sendLogs(w, req.Body), false } func sendLogs(w http.ResponseWriter, r io.Reader) error { - w.Header().Set("Cache-Control", "no-cache") - w.Header().Set("Connection", "keep-alive") - buf := make([]byte, 406) var flusher http.Flusher