Files
comicverse/lib/middleware/dev.go
Gustavo L de Mello (Guz) 218b991caa refactor(lib): move app routing to lib package
These packages and functions under lib will one day be part of it's
dedicated library/framework, so separating them here helps for the
future.
2024-10-23 19:06:03 -03:00

80 lines
1.8 KiB
Go

package middleware
import (
"log/slog"
"math/rand"
"net/http"
)
func DevMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Cache-Control", "no-store")
next.ServeHTTP(w, r)
})
}
type LoggerMiddleware struct {
log *slog.Logger
}
type loggerReponse struct {
http.ResponseWriter
status int
}
func (lr *loggerReponse) WriteHeader(s int) {
lr.status = s
lr.ResponseWriter.WriteHeader(s)
}
func NewLoggerMiddleware(l *slog.Logger) *LoggerMiddleware {
l = l.WithGroup("logger_middleware")
return &LoggerMiddleware{l}
}
func (l *LoggerMiddleware) Wrap(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
id := randHash(5)
l.log.Info("NEW REQUEST",
slog.String("id", id),
slog.String("status", "xxx"),
slog.String("method", r.Method),
slog.String("path", r.URL.Path),
)
lw := &loggerReponse{w, http.StatusOK}
next.ServeHTTP(lw, r)
if lw.status >= 400 {
l.log.Warn("ERR REQUEST",
slog.String("id", id),
slog.Int("status", lw.status),
slog.String("method", r.Method),
slog.String("path", r.URL.Path),
)
return
}
l.log.Info("END REQUEST",
slog.String("id", id),
slog.Int("status", lw.status),
slog.String("method", r.Method),
slog.String("path", r.URL.Path),
)
})
}
const HASH_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
// This is not the most performant function, as a TODO we could
// improve based on this Stackoberflow thread:
// https://stackoverflow.com/questions/22892120/how-to-generate-a-random-string-of-a-fixed-length-in-go
func randHash(n int) string {
b := make([]byte, n)
for i := range b {
b[i] = HASH_CHARS[rand.Int63()%int64(len(HASH_CHARS))]
}
return string(b)
}