75 lines
1.4 KiB
Go
75 lines
1.4 KiB
Go
|
package status
|
||
|
|
||
|
import (
|
||
|
"embed"
|
||
|
"html/template"
|
||
|
"io/fs"
|
||
|
"net/http"
|
||
|
"sync"
|
||
|
"sync/atomic"
|
||
|
|
||
|
"github.com/pkg/errors"
|
||
|
"gitlab.com/wpetit/goweb/logger"
|
||
|
)
|
||
|
|
||
|
//go:embed templates/*.gotpl
|
||
|
var templates embed.FS
|
||
|
|
||
|
//go:embed public/*
|
||
|
var public embed.FS
|
||
|
|
||
|
type Handler struct {
|
||
|
status *atomic.Value
|
||
|
|
||
|
public http.Handler
|
||
|
templates *template.Template
|
||
|
|
||
|
init sync.Once
|
||
|
initErr error
|
||
|
}
|
||
|
|
||
|
// ServeHTTP implements http.Handler.
|
||
|
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||
|
h.init.Do(func() {
|
||
|
root, err := fs.Sub(public, "public")
|
||
|
if err != nil {
|
||
|
h.initErr = errors.WithStack(err)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
h.public = http.FileServer(http.FS(root))
|
||
|
|
||
|
tmpl, err := template.ParseFS(templates, "templates/*.gotpl")
|
||
|
if err != nil {
|
||
|
h.initErr = errors.WithStack(err)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
h.templates = tmpl
|
||
|
})
|
||
|
if h.initErr != nil {
|
||
|
logger.Error(r.Context(), "could not initialize handler", logger.E(h.initErr))
|
||
|
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||
|
|
||
|
return
|
||
|
}
|
||
|
|
||
|
switch r.URL.Path {
|
||
|
case "/":
|
||
|
h.serveIndex(w, r)
|
||
|
default:
|
||
|
h.public.ServeHTTP(w, r)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (h *Handler) serveIndex(w http.ResponseWriter, r *http.Request) {
|
||
|
data := h.status.Load()
|
||
|
|
||
|
if err := h.templates.ExecuteTemplate(w, "index.html.gotpl", data); err != nil {
|
||
|
logger.Error(r.Context(), "could not render template", logger.E(errors.WithStack(err)))
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var _ http.Handler = &Handler{}
|