All checks were successful
Build and Publish Docker Image / deploy (push) Successful in 1m41s
- Implement storage backend deletion, which automatically resets default storage settings and user-specific overrides when a backend is removed. - Add unit tests covering the delete action and its cleanup side effects. - Improve admin UI responsiveness, fixing table scrolling, flex wrapping, and text truncation for long storage backend names. - Update security documentation to clarify trusted proxy configurations and explain how trusted proxies are protected from automatic bans.
65 lines
1.4 KiB
Go
65 lines
1.4 KiB
Go
package middleware
|
|
|
|
import (
|
|
"log/slog"
|
|
"net/http"
|
|
"time"
|
|
|
|
"warpbox.dev/backend/libs/services"
|
|
)
|
|
|
|
type statusRecorder struct {
|
|
http.ResponseWriter
|
|
status int
|
|
bytes int
|
|
}
|
|
|
|
func (r *statusRecorder) WriteHeader(status int) {
|
|
r.status = status
|
|
r.ResponseWriter.WriteHeader(status)
|
|
}
|
|
|
|
func (r *statusRecorder) Write(data []byte) (int, error) {
|
|
if r.status == 0 {
|
|
r.status = http.StatusOK
|
|
}
|
|
n, err := r.ResponseWriter.Write(data)
|
|
r.bytes += n
|
|
return n, err
|
|
}
|
|
|
|
func Logger(logger *slog.Logger) Middleware {
|
|
return func(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
start := time.Now()
|
|
recorder := &statusRecorder{ResponseWriter: w}
|
|
|
|
next.ServeHTTP(recorder, r)
|
|
|
|
status := recorder.status
|
|
if status == 0 {
|
|
status = http.StatusOK
|
|
}
|
|
ip, ok := services.ClientIPFromContext(r)
|
|
if !ok {
|
|
ip = services.ClientIP(r.RemoteAddr, r.Header.Get("X-Forwarded-For"), r.Header.Get("X-Real-IP"), nil)
|
|
}
|
|
|
|
logger.Info("http request",
|
|
"source", "http",
|
|
"severity", "dev",
|
|
"code", status,
|
|
"method", r.Method,
|
|
"path", r.URL.Path,
|
|
"status", status,
|
|
"bytes", recorder.bytes,
|
|
"duration_ms", time.Since(start).Milliseconds(),
|
|
"request_id", RequestIDFromContext(r.Context()),
|
|
"ip", ip,
|
|
"remote_addr", r.RemoteAddr,
|
|
"user_agent", r.UserAgent(),
|
|
)
|
|
})
|
|
}
|
|
}
|