From 4b9698b1b7cb4bfa4d056e69740005498b0d855b Mon Sep 17 00:00:00 2001 From: Egutierrez Date: Sat, 9 May 2026 15:00:49 +0200 Subject: [PATCH] fix(http_logger): preservar Hijack y Flush para WebSocket y SSE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit El responseWriter del logger middleware envolvia http.ResponseWriter sin implementar http.Hijacker ni http.Flusher. Esto rompia el upgrade WebSocket (501 Not Implemented) y el flush de SSE. Anade Hijack() y Flush() que delegan al writer subyacente. Detectado via e2e tests de apps/kanban que arrancaban el binario real y dialeaban /api/chat/ws — el upgrade fallaba con 501 hasta este fix. Co-Authored-By: Claude Opus 4.7 (1M context) --- functions/infra/http_logger_middleware.go | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/functions/infra/http_logger_middleware.go b/functions/infra/http_logger_middleware.go index 8ab8e243..fc4bb48a 100644 --- a/functions/infra/http_logger_middleware.go +++ b/functions/infra/http_logger_middleware.go @@ -1,13 +1,17 @@ package infra import ( + "bufio" "fmt" "io" + "net" "net/http" "time" ) // responseWriter captura el status code escrito al ResponseWriter. +// Implementa http.Hijacker y http.Flusher delegando al writer subyacente +// para preservar WebSocket upgrade y SSE. type responseWriter struct { http.ResponseWriter status int @@ -18,6 +22,23 @@ func (rw *responseWriter) WriteHeader(status int) { rw.ResponseWriter.WriteHeader(status) } +// Hijack delega en el ResponseWriter subyacente si lo soporta. Necesario +// para que WebSocket Upgrade funcione a traves del logger middleware. +func (rw *responseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { + if h, ok := rw.ResponseWriter.(http.Hijacker); ok { + return h.Hijack() + } + return nil, nil, http.ErrNotSupported +} + +// Flush delega en el ResponseWriter subyacente si lo soporta. Necesario +// para SSE y respuestas streaming. +func (rw *responseWriter) Flush() { + if f, ok := rw.ResponseWriter.(http.Flusher); ok { + f.Flush() + } +} + // HTTPLoggerMiddleware retorna un Middleware que loguea metodo, path, status y duracion de cada request. // El formato de cada linea es: METHOD /path STATUS DURACIONms func HTTPLoggerMiddleware(logger io.Writer) Middleware {