package web import ( "net/http" "github.com/rs/zerolog/log" ) // Handler is a function type that handles an HTTP request in Inbucket. type Handler func(http.ResponseWriter, *http.Request, *Context) error // ServeHTTP builds the context and passes onto the real handler. func (h Handler) ServeHTTP(w http.ResponseWriter, req *http.Request) { // Create the context. ctx, err := NewContext(req) if err != nil { log.Error().Str("module", "web").Err(err).Msg("HTTP failed to create context") http.Error(w, err.Error(), http.StatusInternalServerError) return } defer ctx.Close() // Run the handler, grab the error, and report it. err = h(w, req, ctx) if err != nil { log.Error().Str("module", "web").Str("path", req.RequestURI).Err(err). Msg("Error handling request") http.Error(w, err.Error(), http.StatusInternalServerError) return } } // noMatchHandler creates a handler to log requests that Gorilla mux is unable to route, // returning specified statusCode to the client. func noMatchHandler(statusCode int, message string) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { log.Warn().Str("module", "web").Str("remote", req.RemoteAddr).Str("proto", req.Proto). Str("method", req.Method).Str("path", req.RequestURI).Msg(message) w.WriteHeader(statusCode) }) } // requestLoggingWrapper returns middleware that logs client requests. func requestLoggingWrapper(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { log.Debug().Str("module", "web").Str("remote", req.RemoteAddr).Str("proto", req.Proto). Str("method", req.Method).Str("path", req.RequestURI).Msg("Request") next.ServeHTTP(w, req) }) }