Lots more changes
This commit is contained in:
@@ -107,6 +107,53 @@ func RateLimitMiddleware(limiter *RateLimiter, trustProxyHeaders bool, trustedPr
|
||||
}
|
||||
}
|
||||
|
||||
func AccessLogMiddleware(logger *log.Logger, trustProxyHeaders bool, trustedProxies []netip.Prefix) func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
if logger == nil {
|
||||
return next
|
||||
}
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if !shouldLogAccessRequest(r.Method, r.URL.Path) {
|
||||
next.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
start := time.Now()
|
||||
recorder := &accessLogResponseWriter{ResponseWriter: w}
|
||||
next.ServeHTTP(recorder, r)
|
||||
|
||||
status := recorder.status
|
||||
if status == 0 {
|
||||
status = http.StatusOK
|
||||
}
|
||||
clientIP := "-"
|
||||
if ip, ok := extractClientIP(r, trustProxyHeaders, trustedProxies); ok {
|
||||
clientIP = ip.String()
|
||||
}
|
||||
logger.Printf(
|
||||
"method=%s path=%s status=%d bytes=%d duration_ms=%d ip=%s ua=%q",
|
||||
r.Method,
|
||||
r.URL.RequestURI(),
|
||||
status,
|
||||
recorder.bytes,
|
||||
time.Since(start).Milliseconds(),
|
||||
clientIP,
|
||||
r.UserAgent(),
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func shouldLogAccessRequest(method string, path string) bool {
|
||||
if method == http.MethodPost && path == "/api/scratch" {
|
||||
return true
|
||||
}
|
||||
if method == http.MethodGet && strings.HasPrefix(path, "/api/raw/") && len(path) > len("/api/raw/") {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func Chain(handler http.Handler, middlewares ...func(http.Handler) http.Handler) http.Handler {
|
||||
wrapped := handler
|
||||
for i := len(middlewares) - 1; i >= 0; i-- {
|
||||
@@ -115,6 +162,26 @@ func Chain(handler http.Handler, middlewares ...func(http.Handler) http.Handler)
|
||||
return wrapped
|
||||
}
|
||||
|
||||
type accessLogResponseWriter struct {
|
||||
http.ResponseWriter
|
||||
status int
|
||||
bytes int
|
||||
}
|
||||
|
||||
func (w *accessLogResponseWriter) WriteHeader(statusCode int) {
|
||||
w.status = statusCode
|
||||
w.ResponseWriter.WriteHeader(statusCode)
|
||||
}
|
||||
|
||||
func (w *accessLogResponseWriter) Write(p []byte) (int, error) {
|
||||
if w.status == 0 {
|
||||
w.status = http.StatusOK
|
||||
}
|
||||
n, err := w.ResponseWriter.Write(p)
|
||||
w.bytes += n
|
||||
return n, err
|
||||
}
|
||||
|
||||
func extractClientIP(r *http.Request, trustProxyHeaders bool, trustedProxies []netip.Prefix) (netip.Addr, bool) {
|
||||
remoteIP, ok := remoteIPFromRequest(r)
|
||||
if !ok {
|
||||
|
||||
Reference in New Issue
Block a user