62 lines
1.4 KiB
Go
62 lines
1.4 KiB
Go
package app
|
|
|
|
import (
|
|
"context"
|
|
"log"
|
|
"net/http"
|
|
"time"
|
|
)
|
|
|
|
type ctxKey string
|
|
|
|
const userKey ctxKey = "user"
|
|
|
|
func (a *App) withAuth(next func(http.ResponseWriter, *http.Request, User)) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
var u User
|
|
if a.cfg.DevMode {
|
|
u = User{Username: a.cfg.DemoUser, Email: a.cfg.DemoEmail}
|
|
} else {
|
|
u = User{Username: r.Header.Get(a.cfg.AuthHeaderUser), Email: r.Header.Get(a.cfg.AuthHeaderEmail)}
|
|
if u.Username == "" {
|
|
http.Error(w, "missing authenticated user header", http.StatusUnauthorized)
|
|
return
|
|
}
|
|
}
|
|
next(w, r.WithContext(context.WithValue(r.Context(), userKey, u)), u)
|
|
}
|
|
}
|
|
|
|
func loggingMiddleware(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
start := time.Now()
|
|
lrw := &logResponseWriter{ResponseWriter: w, status: http.StatusOK}
|
|
next.ServeHTTP(lrw, r)
|
|
log.Printf("method=%s path=%s status=%d bytes=%d dur_ms=%d remote=%s ua=%q",
|
|
r.Method,
|
|
r.URL.Path,
|
|
lrw.status,
|
|
lrw.bytes,
|
|
time.Since(start).Milliseconds(),
|
|
r.RemoteAddr,
|
|
r.UserAgent(),
|
|
)
|
|
})
|
|
}
|
|
|
|
type logResponseWriter struct {
|
|
http.ResponseWriter
|
|
status int
|
|
bytes int
|
|
}
|
|
|
|
func (l *logResponseWriter) WriteHeader(statusCode int) {
|
|
l.status = statusCode
|
|
l.ResponseWriter.WriteHeader(statusCode)
|
|
}
|
|
|
|
func (l *logResponseWriter) Write(b []byte) (int, error) {
|
|
n, err := l.ResponseWriter.Write(b)
|
|
l.bytes += n
|
|
return n, err
|
|
}
|