Files
mediamtx/internal/protocols/httpp/handler_logger.go
T
JulienCossecandGitHub 184899dfab fix: avoid buffering HTTP response body in loggerWriter (#5552)
loggerWriter was shadow-copying every response byte into a bytes.Buffer
to report the body size, causing the entire response to be accumulated
in memory for the lifetime of each request. Replace the buffer with a
plain int counter since dump() only ever reported the byte count anyway.
2026-03-07 18:36:10 +01:00

62 lines
1.2 KiB
Go

package httpp
import (
"bytes"
"fmt"
"net/http"
"net/http/httputil"
"github.com/bluenviron/mediamtx/internal/logger"
)
type loggerWriter struct {
w http.ResponseWriter
status int
size int
}
func (w *loggerWriter) Header() http.Header {
return w.w.Header()
}
func (w *loggerWriter) Write(b []byte) (int, error) {
if w.status == 0 {
w.status = http.StatusOK
}
w.size += len(b)
return w.w.Write(b)
}
func (w *loggerWriter) WriteHeader(statusCode int) {
w.status = statusCode
w.w.WriteHeader(statusCode)
}
func (w *loggerWriter) dump() string {
var buf bytes.Buffer
fmt.Fprintf(&buf, "%s %d %s\n", "HTTP/1.1", w.status, http.StatusText(w.status))
w.w.Header().Write(&buf) //nolint:errcheck
buf.Write([]byte("\n"))
if w.size > 0 {
fmt.Fprintf(&buf, "(body of %d bytes)", w.size)
}
return buf.String()
}
// log requests and responses.
type handlerLogger struct {
h http.Handler
log logger.Writer
}
func (h *handlerLogger) ServeHTTP(w http.ResponseWriter, r *http.Request) {
byts, _ := httputil.DumpRequest(r, true)
h.log.Log(logger.Debug, "[conn %v] [c->s] %s", r.RemoteAddr, string(byts))
logw := &loggerWriter{w: w}
h.h.ServeHTTP(logw, r)
h.log.Log(logger.Debug, "[conn %v] [s->c] %s", r.RemoteAddr, logw.dump())
}