sneak/integrate-di #17
@ -20,10 +20,10 @@ func (s *Handlers) handleHealthCheck() http.HandlerFunc {
|
|||||||
Status: "ok",
|
Status: "ok",
|
||||||
Now: time.Now().UTC().Format(time.RFC3339Nano),
|
Now: time.Now().UTC().Format(time.RFC3339Nano),
|
||||||
UptimeSeconds: int64(s.uptime().Seconds()),
|
UptimeSeconds: int64(s.uptime().Seconds()),
|
||||||
UptimeHuman: s.uptime().String(),
|
UptimeHuman: s.params.Server.uptime().String(),
|
||||||
Maintenance: s.maintenance(),
|
Maintenance: s.params.Server.MaintenanceMode(),
|
||||||
Appname: s.appname,
|
Appname: s.params.Globals.Appname,
|
||||||
Version: s.version,
|
Version: s.params.Globals.Version,
|
||||||
}
|
}
|
||||||
s.respondJSON(w, req, resp, 200)
|
s.respondJSON(w, req, resp, 200)
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,43 @@
|
|||||||
package server
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"git.eeqj.de/sneak/gohttpserver/internal/config"
|
||||||
|
"git.eeqj.de/sneak/gohttpserver/internal/globals"
|
||||||
|
"git.eeqj.de/sneak/gohttpserver/internal/logger"
|
||||||
basicauth "github.com/99designs/basicauth-go"
|
basicauth "github.com/99designs/basicauth-go"
|
||||||
"github.com/go-chi/chi/middleware"
|
"github.com/go-chi/chi/middleware"
|
||||||
"github.com/go-chi/cors"
|
"github.com/go-chi/cors"
|
||||||
|
"github.com/rs/zerolog"
|
||||||
metrics "github.com/slok/go-http-metrics/metrics/prometheus"
|
metrics "github.com/slok/go-http-metrics/metrics/prometheus"
|
||||||
ghmm "github.com/slok/go-http-metrics/middleware"
|
ghmm "github.com/slok/go-http-metrics/middleware"
|
||||||
"github.com/slok/go-http-metrics/middleware/std"
|
"github.com/slok/go-http-metrics/middleware/std"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
"go.uber.org/fx"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type MiddlewareParams struct {
|
||||||
|
fx.In
|
||||||
|
Logger logger.Logger
|
||||||
|
Globals globals.Globals
|
||||||
|
Config config.Config
|
||||||
|
}
|
||||||
|
|
||||||
|
type Middleware struct {
|
||||||
|
log *zerolog.Logger
|
||||||
|
params MiddlewareParams
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(lc fx.Lifecycle, params MiddlewareParams) (*Middleware, error) {
|
||||||
|
s := new(Middleware)
|
||||||
|
s.params = params
|
||||||
|
s.log = params.Logger.Get()
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
|
|
||||||
// the following is from
|
// the following is from
|
||||||
// https://learning-cloud-native-go.github.io/docs/a6.adding_zerolog_logger/
|
// https://learning-cloud-native-go.github.io/docs/a6.adding_zerolog_logger/
|
||||||
|
|
||||||
@ -45,7 +69,7 @@ func (lrw *loggingResponseWriter) WriteHeader(code int) {
|
|||||||
// type Middleware func(http.Handler) http.Handler
|
// type Middleware func(http.Handler) http.Handler
|
||||||
// this returns a Middleware that is designed to do every request through the
|
// this returns a Middleware that is designed to do every request through the
|
||||||
// mux, note the signature:
|
// mux, note the signature:
|
||||||
func (s *Server) LoggingMiddleware() func(http.Handler) http.Handler {
|
func (s *Middleware) LoggingMiddleware() func(http.Handler) http.Handler {
|
||||||
// FIXME this should use https://github.com/google/go-cloud/blob/master/server/requestlog/requestlog.go
|
// FIXME this should use https://github.com/google/go-cloud/blob/master/server/requestlog/requestlog.go
|
||||||
return func(next http.Handler) http.Handler {
|
return func(next http.Handler) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
@ -73,7 +97,7 @@ func (s *Server) LoggingMiddleware() func(http.Handler) http.Handler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) CORSMiddleware() func(http.Handler) http.Handler {
|
func (s *Middleware) CORSMiddleware() func(http.Handler) http.Handler {
|
||||||
return cors.Handler(cors.Options{
|
return cors.Handler(cors.Options{
|
||||||
// CHANGEME! these are defaults, change them to suit your needs or
|
// CHANGEME! these are defaults, change them to suit your needs or
|
||||||
// read from environment/viper.
|
// read from environment/viper.
|
||||||
@ -88,7 +112,7 @@ func (s *Server) CORSMiddleware() func(http.Handler) http.Handler {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) AuthMiddleware() func(http.Handler) http.Handler {
|
func (s *Middleware) AuthMiddleware() func(http.Handler) http.Handler {
|
||||||
return func(next http.Handler) http.Handler {
|
return func(next http.Handler) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
// CHANGEME you'll want to change this to do stuff.
|
// CHANGEME you'll want to change this to do stuff.
|
||||||
@ -98,7 +122,7 @@ func (s *Server) AuthMiddleware() func(http.Handler) http.Handler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) MetricsMiddleware() func(http.Handler) http.Handler {
|
func (s *Middleware) MetricsMiddleware() func(http.Handler) http.Handler {
|
||||||
mdlw := ghmm.New(ghmm.Config{
|
mdlw := ghmm.New(ghmm.Config{
|
||||||
Recorder: metrics.NewRecorder(metrics.Config{}),
|
Recorder: metrics.NewRecorder(metrics.Config{}),
|
||||||
})
|
})
|
||||||
@ -107,7 +131,7 @@ func (s *Server) MetricsMiddleware() func(http.Handler) http.Handler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) MetricsAuthMiddleware() func(http.Handler) http.Handler {
|
func (s *Middleware) MetricsAuthMiddleware() func(http.Handler) http.Handler {
|
||||||
return basicauth.New(
|
return basicauth.New(
|
||||||
"metrics",
|
"metrics",
|
||||||
map[string][]string{
|
map[string][]string{
|
@ -18,7 +18,7 @@ func (s *Server) serveUntilShutdown() {
|
|||||||
|
|
||||||
// add routes
|
// add routes
|
||||||
// this does any necessary setup in each handler
|
// this does any necessary setup in each handler
|
||||||
s.routes()
|
s.SetupRoutes()
|
||||||
|
|
||||||
s.log.Info().Str("listenaddr", listenAddr).Msg("http begin listen")
|
s.log.Info().Str("listenaddr", listenAddr).Msg("http begin listen")
|
||||||
if err := s.httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
if err := s.httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||||
|
@ -23,16 +23,16 @@ func (s *Server) SetupRoutes() {
|
|||||||
|
|
||||||
s.router.Use(middleware.Recoverer)
|
s.router.Use(middleware.Recoverer)
|
||||||
s.router.Use(middleware.RequestID)
|
s.router.Use(middleware.RequestID)
|
||||||
s.router.Use(s.LoggingMiddleware())
|
s.router.Use(s.mw.LoggingMiddleware())
|
||||||
|
|
||||||
// add metrics middleware only if we can serve them behind auth
|
// add metrics middleware only if we can serve them behind auth
|
||||||
if viper.GetString("METRICS_USERNAME") != "" {
|
if viper.GetString("METRICS_USERNAME") != "" {
|
||||||
s.router.Use(s.MetricsMiddleware())
|
s.router.Use(s.mw.MetricsMiddleware())
|
||||||
}
|
}
|
||||||
|
|
||||||
// set up CORS headers. you'll probably want to configure that
|
// set up CORS headers. you'll probably want to configure that
|
||||||
// in middlewares.go.
|
// in middlewares.go.
|
||||||
s.router.Use(s.CORSMiddleware())
|
s.router.Use(s.mw.CORSMiddleware())
|
||||||
|
|
||||||
// CHANGEME to suit your needs, or pull from config.
|
// CHANGEME to suit your needs, or pull from config.
|
||||||
// timeout for request context; your handlers must finish within
|
// timeout for request context; your handlers must finish within
|
||||||
@ -57,12 +57,12 @@ func (s *Server) SetupRoutes() {
|
|||||||
// complete docs: https://github.com/go-chi/chi
|
// complete docs: https://github.com/go-chi/chi
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
s.router.Get("/", s.handleIndex())
|
s.router.Get("/", s.h.handleIndex())
|
||||||
|
|
||||||
s.router.Mount("/s", http.StripPrefix("/s", http.FileServer(http.FS(static.Static))))
|
s.router.Mount("/s", http.StripPrefix("/s", http.FileServer(http.FS(static.Static))))
|
||||||
|
|
||||||
s.router.Route("/api/v1", func(r chi.Router) {
|
s.router.Route("/api/v1", func(r chi.Router) {
|
||||||
r.Get("/now", s.handleNow())
|
r.Get("/now", s.h.handleNow())
|
||||||
})
|
})
|
||||||
|
|
||||||
// if you want to use a general purpose middleware (http.Handler
|
// if you want to use a general purpose middleware (http.Handler
|
||||||
@ -71,25 +71,25 @@ func (s *Server) SetupRoutes() {
|
|||||||
authMiddleware := s.AuthMiddleware()
|
authMiddleware := s.AuthMiddleware()
|
||||||
s.router.Get(
|
s.router.Get(
|
||||||
"/login",
|
"/login",
|
||||||
authMiddleware(s.handleLogin()).ServeHTTP,
|
authMiddleware(s.h.handleLogin()).ServeHTTP,
|
||||||
)
|
)
|
||||||
|
|
||||||
// route that panics for testing
|
// route that panics for testing
|
||||||
// CHANGEME remove this
|
// CHANGEME remove this
|
||||||
s.router.Get(
|
s.router.Get(
|
||||||
"/panic",
|
"/panic",
|
||||||
s.handlePanic(),
|
s.h.handlePanic(),
|
||||||
)
|
)
|
||||||
|
|
||||||
s.router.Get(
|
s.router.Get(
|
||||||
"/.well-known/healthcheck.json",
|
"/.well-known/healthcheck.json",
|
||||||
s.handleHealthCheck(),
|
s.h.handleHealthCheck(),
|
||||||
)
|
)
|
||||||
|
|
||||||
// set up authenticated /metrics route:
|
// set up authenticated /metrics route:
|
||||||
if viper.GetString("METRICS_USERNAME") != "" {
|
if viper.GetString("METRICS_USERNAME") != "" {
|
||||||
s.router.Group(func(r chi.Router) {
|
s.router.Group(func(r chi.Router) {
|
||||||
r.Use(s.MetricsAuthMiddleware())
|
r.Use(s.mw.MetricsAuthMiddleware())
|
||||||
r.Get("/metrics", http.HandlerFunc(promhttp.Handler().ServeHTTP))
|
r.Get("/metrics", http.HandlerFunc(promhttp.Handler().ServeHTTP))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,9 @@ import (
|
|||||||
|
|
||||||
"git.eeqj.de/sneak/gohttpserver/internal/config"
|
"git.eeqj.de/sneak/gohttpserver/internal/config"
|
||||||
"git.eeqj.de/sneak/gohttpserver/internal/globals"
|
"git.eeqj.de/sneak/gohttpserver/internal/globals"
|
||||||
|
"git.eeqj.de/sneak/gohttpserver/internal/handlers"
|
||||||
"git.eeqj.de/sneak/gohttpserver/internal/logger"
|
"git.eeqj.de/sneak/gohttpserver/internal/logger"
|
||||||
|
"git.eeqj.de/sneak/gohttpserver/internal/middleware"
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"go.uber.org/fx"
|
"go.uber.org/fx"
|
||||||
@ -32,9 +34,11 @@ import (
|
|||||||
|
|
||||||
type ServerParams struct {
|
type ServerParams struct {
|
||||||
fx.In
|
fx.In
|
||||||
Logger logger.Logger
|
Logger logger.Logger
|
||||||
Globals globals.Globals
|
Globals globals.Globals
|
||||||
Config config.Config
|
Config config.Config
|
||||||
|
Middleware middleware.Middleware
|
||||||
|
Handlers handlers.Handlers
|
||||||
}
|
}
|
||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
@ -51,11 +55,15 @@ type Server struct {
|
|||||||
httpServer *http.Server
|
httpServer *http.Server
|
||||||
router *chi.Mux
|
router *chi.Mux
|
||||||
params ServerParams
|
params ServerParams
|
||||||
|
mw middleware.Middleware
|
||||||
|
h handlers.Handlers
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(lc fx.Lifecycle, params ServerParams) (*Server, error) {
|
func New(lc fx.Lifecycle, params ServerParams) (*Server, error) {
|
||||||
s := new(Server)
|
s := new(Server)
|
||||||
s.params = params
|
s.params = params
|
||||||
|
s.mw = params.Middleware
|
||||||
|
s.h = params.Handlers
|
||||||
s.log = params.Logger.Get()
|
s.log = params.Logger.Get()
|
||||||
|
|
||||||
lc.Append(fx.Hook{
|
lc.Append(fx.Hook{
|
||||||
|
Loading…
Reference in New Issue
Block a user