safing-portbase/api/middleware.go
2020-06-05 13:02:19 +02:00

52 lines
1.3 KiB
Go

package api
import (
"context"
"net/http"
"github.com/safing/portbase/log"
)
// Middleware is a function that can be added as a middleware to the API endpoint.
type Middleware func(next http.Handler) http.Handler
type mwHandler struct {
handlers []Middleware
final http.Handler
}
func (mwh *mwHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
handlerLock.RLock()
defer handlerLock.RUnlock()
// final handler
handler := mwh.final
// build middleware chain
// loop in reverse to build the handler chain in the correct order
for i := len(mwh.handlers) - 1; i >= 0; i-- {
handler = mwh.handlers[i](handler)
}
// start
handler.ServeHTTP(w, r)
}
// ModuleWorker is an http middleware that wraps the request in a module worker.
func ModuleWorker(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_ = module.RunWorker("http request", func(_ context.Context) error {
next.ServeHTTP(w, r)
return nil
})
})
}
// LogTracer is an http middleware that attaches a log tracer to the request context.
func LogTracer(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx, tracer := log.AddTracer(r.Context())
next.ServeHTTP(w, r.WithContext(ctx))
tracer.Submit()
})
}