162 lines
3.0 KiB
Go
162 lines
3.0 KiB
Go
package server
|
|
|
|
import (
|
|
"io/fs"
|
|
"net/http"
|
|
"time"
|
|
|
|
"git.eeqj.de/sneak/chat/web"
|
|
|
|
sentryhttp "github.com/getsentry/sentry-go/http"
|
|
"github.com/go-chi/chi"
|
|
"github.com/go-chi/chi/middleware"
|
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
|
"github.com/spf13/viper"
|
|
)
|
|
|
|
const routeTimeout = 60 * time.Second
|
|
|
|
// SetupRoutes configures the HTTP routes and middleware.
|
|
func (srv *Server) SetupRoutes() {
|
|
srv.router = chi.NewRouter()
|
|
|
|
srv.router.Use(middleware.Recoverer)
|
|
srv.router.Use(middleware.RequestID)
|
|
srv.router.Use(srv.mw.Logging())
|
|
|
|
if viper.GetString("METRICS_USERNAME") != "" {
|
|
srv.router.Use(srv.mw.Metrics())
|
|
}
|
|
|
|
srv.router.Use(srv.mw.CORS())
|
|
srv.router.Use(middleware.Timeout(routeTimeout))
|
|
|
|
if srv.sentryEnabled {
|
|
sentryHandler := sentryhttp.New(
|
|
sentryhttp.Options{ //nolint:exhaustruct // optional fields
|
|
Repanic: true,
|
|
},
|
|
)
|
|
|
|
srv.router.Use(sentryHandler.Handle)
|
|
}
|
|
|
|
// Health check.
|
|
srv.router.Get(
|
|
"/.well-known/healthcheck.json",
|
|
srv.handlers.HandleHealthCheck(),
|
|
)
|
|
|
|
// Protected metrics endpoint.
|
|
if viper.GetString("METRICS_USERNAME") != "" {
|
|
srv.router.Group(func(router chi.Router) {
|
|
router.Use(srv.mw.MetricsAuth())
|
|
router.Get("/metrics",
|
|
http.HandlerFunc(
|
|
promhttp.Handler().ServeHTTP,
|
|
))
|
|
})
|
|
}
|
|
|
|
// API v1.
|
|
srv.router.Route(
|
|
"/api/v1",
|
|
func(router chi.Router) {
|
|
router.Get(
|
|
"/server",
|
|
srv.handlers.HandleServerInfo(),
|
|
)
|
|
router.Post(
|
|
"/session",
|
|
srv.handlers.HandleCreateSession(),
|
|
)
|
|
router.Post(
|
|
"/register",
|
|
srv.handlers.HandleRegister(),
|
|
)
|
|
router.Post(
|
|
"/login",
|
|
srv.handlers.HandleLogin(),
|
|
)
|
|
router.Get(
|
|
"/state",
|
|
srv.handlers.HandleState(),
|
|
)
|
|
router.Get(
|
|
"/messages",
|
|
srv.handlers.HandleGetMessages(),
|
|
)
|
|
router.Post(
|
|
"/messages",
|
|
srv.handlers.HandleSendCommand(),
|
|
)
|
|
router.Get(
|
|
"/history",
|
|
srv.handlers.HandleGetHistory(),
|
|
)
|
|
router.Get(
|
|
"/channels",
|
|
srv.handlers.HandleListAllChannels(),
|
|
)
|
|
router.Get(
|
|
"/channels/{channel}/members",
|
|
srv.handlers.HandleChannelMembers(),
|
|
)
|
|
},
|
|
)
|
|
|
|
// Serve embedded SPA.
|
|
srv.setupSPA()
|
|
}
|
|
|
|
func (srv *Server) setupSPA() {
|
|
distFS, err := fs.Sub(web.Dist, "dist")
|
|
if err != nil {
|
|
srv.log.Error(
|
|
"failed to get web dist filesystem",
|
|
"error", err,
|
|
)
|
|
|
|
return
|
|
}
|
|
|
|
fileServer := http.FileServer(http.FS(distFS))
|
|
|
|
srv.router.Get("/*", func(
|
|
writer http.ResponseWriter,
|
|
request *http.Request,
|
|
) {
|
|
readFS, ok := distFS.(fs.ReadFileFS)
|
|
if !ok {
|
|
fileServer.ServeHTTP(writer, request)
|
|
|
|
return
|
|
}
|
|
|
|
fileData, readErr := readFS.ReadFile(
|
|
request.URL.Path[1:],
|
|
)
|
|
if readErr != nil || len(fileData) == 0 {
|
|
indexHTML, indexErr := readFS.ReadFile(
|
|
"index.html",
|
|
)
|
|
if indexErr != nil {
|
|
http.NotFound(writer, request)
|
|
|
|
return
|
|
}
|
|
|
|
writer.Header().Set(
|
|
"Content-Type",
|
|
"text/html; charset=utf-8",
|
|
)
|
|
writer.WriteHeader(http.StatusOK)
|
|
_, _ = writer.Write(indexHTML)
|
|
|
|
return
|
|
}
|
|
|
|
fileServer.ServeHTTP(writer, request)
|
|
})
|
|
}
|