fix(http_logger): preservar Hijack y Flush para WebSocket y SSE
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) <noreply@anthropic.com>
This commit is contained in:
@@ -1,13 +1,17 @@
|
|||||||
package infra
|
package infra
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// responseWriter captura el status code escrito al ResponseWriter.
|
// 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 {
|
type responseWriter struct {
|
||||||
http.ResponseWriter
|
http.ResponseWriter
|
||||||
status int
|
status int
|
||||||
@@ -18,6 +22,23 @@ func (rw *responseWriter) WriteHeader(status int) {
|
|||||||
rw.ResponseWriter.WriteHeader(status)
|
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.
|
// HTTPLoggerMiddleware retorna un Middleware que loguea metodo, path, status y duracion de cada request.
|
||||||
// El formato de cada linea es: METHOD /path STATUS DURACIONms
|
// El formato de cada linea es: METHOD /path STATUS DURACIONms
|
||||||
func HTTPLoggerMiddleware(logger io.Writer) Middleware {
|
func HTTPLoggerMiddleware(logger io.Writer) Middleware {
|
||||||
|
|||||||
Reference in New Issue
Block a user