package httpserver import ( "net" "net/http" "time" ) // the following is from // https://learning-cloud-native-go.github.io/docs/a6.adding_zerolog_logger/ func ipFromHostPort(hp string) string { h, _, err := net.SplitHostPort(hp) if err != nil { return "" } if len(h) > 0 && h[0] == '[' { return h[1 : len(h)-1] } return h } type loggingResponseWriter struct { http.ResponseWriter statusCode int } func NewLoggingResponseWriter(w http.ResponseWriter) *loggingResponseWriter { return &loggingResponseWriter{w, http.StatusOK} } func (lrw *loggingResponseWriter) WriteHeader(code int) { lrw.statusCode = code lrw.ResponseWriter.WriteHeader(code) } // type Middleware func(http.Handler) http.Handler // this returns a Middleware that is designed to do every request through the // mux, note the signature: func (s *server) LoggingMiddleware() func(http.Handler) http.Handler { // FIXME this should use https://github.com/google/go-cloud/blob/master/server/requestlog/requestlog.go return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { start := time.Now() lrw := NewLoggingResponseWriter(w) defer func() { latency := time.Since(start) s.log.Info(). Time("request_start", start). Str("method", r.Method). Str("url", r.URL.String()). Str("useragent", r.UserAgent()). Str("referer", r.Referer()). Str("proto", r.Proto). Str("remoteIP", ipFromHostPort(r.RemoteAddr)). Int("status", lrw.statusCode). Dur("latency", latency). Send() }() next.ServeHTTP(lrw, r) }) } } func (s *server) AuthMiddleware() func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // FIXME you'll want to change this to do stuff. s.log.Info().Msg("AUTH: before request") next.ServeHTTP(w, r) }) } }