package web import ( "fmt" "net/http" "time" "github.com/sirupsen/logrus" ) type HttpContext struct { cfg *Configuration log *logrus.Logger mux *http.ServeMux } func NewHttpContext(cfg *Configuration) *HttpContext { logger := logrus.New() logger.SetFormatter(&logrus.TextFormatter{ DisableColors: true, DisableLevelTruncation: true, ForceQuote: true, FullTimestamp: true, FieldMap: logrus.FieldMap{ logrus.FieldKeyTime: "@timestamp", logrus.FieldKeyLevel: "@level", logrus.FieldKeyMsg: "@message", }, }) return &HttpContext{ cfg: cfg, log: logger, } } func (h *HttpContext) Router() *http.ServeMux { mux := http.NewServeMux() mux.Handle("/", h.buildHandlerFor(h.Default)) mux.Handle("/.well-known/", h.wellKnownMux()) mux.Handle("/authorize", h.buildHandlerFor(h.Authorize)) mux.Handle("/register", h.buildHandlerFor(h.Register)) mux.Handle("/revoke", h.buildHandlerFor(http.NotFound)) mux.Handle("/token", h.buildHandlerFor(h.Token)) mux.Handle("/userinfo", h.buildHandlerFor(http.NotFound)) return mux } func (h *HttpContext) buildHandlerFor(handler http.HandlerFunc) http.Handler { return h.withLogging(http.HandlerFunc(handler)) } func (h *HttpContext) wellKnownMux() *http.ServeMux { mux := http.NewServeMux() mux.Handle("/.well-known/jwks.json", h.buildHandlerFor(h.JsonWebKeySets)) mux.Handle("/.well-known/openid-configuration", h.buildHandlerFor(h.OpenIdConfiguration)) return mux } func (h *HttpContext) withLogging(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { start := time.Now() next.ServeHTTP(w, r) end := time.Now() duration := end.Sub(start) h.log.WithFields(logrus.Fields{ "method": r.Method, "path": r.URL.Path, "remote_addr": r.RemoteAddr, "user_agent": r.UserAgent(), "µs": duration.Microseconds(), }).Info(fmt.Sprintf("%v %v", r.Method, r.URL.Path)) }) }