forked from
tangled.org/core
Monorepo for Tangled — https://tangled.org
1package knotserver
2
3import (
4 "log/slog"
5 "net/http"
6 "time"
7)
8
9func (h *Knot) RequestLogger(next http.Handler) http.Handler {
10 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
11 start := time.Now()
12
13 next.ServeHTTP(w, r)
14
15 // Build query params as slog.Attrs for the group
16 queryParams := r.URL.Query()
17 queryAttrs := make([]any, 0, len(queryParams))
18 for key, values := range queryParams {
19 if len(values) == 1 {
20 queryAttrs = append(queryAttrs, slog.String(key, values[0]))
21 } else {
22 queryAttrs = append(queryAttrs, slog.Any(key, values))
23 }
24 }
25
26 h.l.LogAttrs(r.Context(), slog.LevelInfo, "",
27 slog.Group("request",
28 slog.String("method", r.Method),
29 slog.String("path", r.URL.Path),
30 slog.Group("query", queryAttrs...),
31 slog.Duration("duration", time.Since(start)),
32 ),
33 )
34 })
35}
36
37func (h *Knot) CORS(next http.Handler) http.Handler {
38 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
39 // Set CORS headers
40 w.Header().Set("Access-Control-Allow-Origin", "*")
41 w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
42 w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
43 w.Header().Set("Access-Control-Max-Age", "86400")
44
45 // Handle preflight requests
46 if r.Method == "OPTIONS" {
47 w.WriteHeader(http.StatusOK)
48 return
49 }
50
51 next.ServeHTTP(w, r)
52 })
53}