96 lines
2.2 KiB
Go
96 lines
2.2 KiB
Go
package server
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"sync"
|
|
"time"
|
|
|
|
"git.1in9.net/raider/wroofauth/internal/logger"
|
|
"github.com/go-chi/chi/v5"
|
|
"github.com/go-chi/chi/v5/middleware"
|
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
|
"github.com/spf13/viper"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
var (
|
|
server *http.Server
|
|
)
|
|
|
|
func startHttpServer(wg *sync.WaitGroup, r *chi.Mux) *http.Server {
|
|
wg.Add(1)
|
|
|
|
srv := &http.Server{
|
|
Handler: r,
|
|
Addr: viper.GetString("http.listen"),
|
|
WriteTimeout: 15 * time.Second,
|
|
ReadTimeout: 15 * time.Second,
|
|
}
|
|
|
|
go func() {
|
|
defer wg.Done()
|
|
|
|
logger.Logger.Info("http server started", zap.String("listen", srv.Addr))
|
|
// Ignore ServerClosed Error
|
|
if err := srv.ListenAndServe(); err != http.ErrServerClosed {
|
|
logger.Logger.Fatal("http server error", zap.Error(err))
|
|
}
|
|
|
|
logger.Logger.Info("http server stopped")
|
|
}()
|
|
|
|
return srv
|
|
}
|
|
|
|
func Shutdown(ctx context.Context) {
|
|
if server == nil {
|
|
return
|
|
}
|
|
|
|
if err := server.Shutdown(ctx); err != nil {
|
|
logger.Logger.Panic("failed to gracefully stop http server", zap.Error(err))
|
|
}
|
|
}
|
|
|
|
func Serve() {
|
|
r := chi.NewRouter()
|
|
|
|
r.Use(middleware.RequestID)
|
|
r.Use(func(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
wrappedResponse := middleware.NewWrapResponseWriter(w, r.ProtoMajor)
|
|
latencyStart := time.Now()
|
|
|
|
defer func() {
|
|
latency := time.Since(latencyStart)
|
|
|
|
logger.Logger.Debug("http request served",
|
|
zap.String("proto", r.Proto),
|
|
zap.String("uri", r.RequestURI),
|
|
zap.String("path", r.URL.Path),
|
|
zap.String("method", r.Method),
|
|
zap.String("remote", r.RemoteAddr),
|
|
zap.Int("status", wrappedResponse.Status()),
|
|
zap.Int("size", wrappedResponse.BytesWritten()),
|
|
zap.Duration("latency", latency),
|
|
zap.String("requestId", middleware.GetReqID(r.Context())),
|
|
)
|
|
}()
|
|
|
|
next.ServeHTTP(wrappedResponse, r)
|
|
})
|
|
})
|
|
r.Use(middleware.Recoverer)
|
|
r.Use(middleware.Timeout(60 * time.Second))
|
|
|
|
r.Handle("/metrics", promhttp.Handler())
|
|
|
|
r.Mount("/api", SetupAPI())
|
|
|
|
httpServerExitDone := &sync.WaitGroup{}
|
|
|
|
server = startHttpServer(httpServerExitDone, r)
|
|
|
|
httpServerExitDone.Wait() // Wait for web server to shut down
|
|
}
|