diff options
| -rw-r--r-- | backend/data.go | 50 | ||||
| -rw-r--r-- | backend/router.go | 4 | ||||
| -rw-r--r-- | backend/templates/base.html | 4 | ||||
| -rw-r--r-- | main.go | 13 |
4 files changed, 57 insertions, 14 deletions
diff --git a/backend/data.go b/backend/data.go index 241f47a..a1b2dba 100644 --- a/backend/data.go +++ b/backend/data.go @@ -1,8 +1,14 @@ package backend import ( + "context" + "crypto/sha256" + "encoding/base64" "fmt" "html/template" + "io" + "io/fs" + "log/slog" "math/rand" "net/http" "regexp" @@ -75,11 +81,8 @@ func (d *data) handleGeneric(w http.ResponseWriter, r *http.Request, name string } return fmt.Sprintf("https://%s/static/%s", cfg.Domain, path) }, - "assets": func(path string) string { - if regexIsHttp.MatchString(path) { - return path - } - return fmt.Sprintf("/assets/%s", path) + "asset": func(path string) *assetData { + return getAsset(r.Context(), path) }, "next": func(i int) int { return i + 1 }, "before": func(i int) int { return i - 1 }, @@ -125,3 +128,40 @@ func getStatic(path string) string { } return fmt.Sprintf("/static/%s", path) } + +type assetData struct { + Src string + Checksum string +} + +func getAsset(ctx context.Context, path string) *assetData { + var asset assetData + var b []byte + var err error + if regexIsHttp.MatchString(path) { + asset.Src = path + resp, err := http.Get(path) + if err != nil { + slog.Warn("get remote asset", "error", err) + return &asset + } + defer resp.Body.Close() + b, err = io.ReadAll(resp.Body) + if err != nil { + slog.Warn("read remote asset", "error", err) + return &asset + } + } else { + asset.Src = fmt.Sprintf("/assets/%s", path) + aFS := ctx.Value(assetsFS).(fs.FS) + b, err = fs.ReadFile(aFS, path) + if err != nil { + slog.Warn("read asset", "error", err) + return &asset + } + } + sum := sha256.Sum256(b) + checksum := base64.StdEncoding.EncodeToString(sum[:]) + asset.Checksum = fmt.Sprintf("sha256-%s", checksum) + return &asset +} diff --git a/backend/router.go b/backend/router.go index 01b8a07..65514ea 100644 --- a/backend/router.go +++ b/backend/router.go @@ -19,6 +19,7 @@ const ( Version = "0.2.0" configKey = "config" isUpdateKey = "is_update" + assetsFS = "assets_fs" ) //go:embed templates @@ -43,7 +44,7 @@ func SetupLogger(debug bool) { slog.SetDefault(logger) } -func NewRouter(debug bool, cfg *Config) *chi.Mux { +func NewRouter(debug bool, cfg *Config, assets fs.FS) *chi.Mux { r := chi.NewRouter() logLevel := slog.LevelWarn @@ -67,6 +68,7 @@ func NewRouter(debug bool, cfg *Config) *chi.Mux { r.Use(func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { ctx := context.WithValue(r.Context(), configKey, cfg) + ctx = context.WithValue(ctx, assetsFS, assets) next.ServeHTTP(w, r.WithContext(ctx)) }) }) diff --git a/backend/templates/base.html b/backend/templates/base.html index e56341b..cf0d834 100644 --- a/backend/templates/base.html +++ b/backend/templates/base.html @@ -4,7 +4,7 @@ <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>{{ .Title }}</title> - <link rel="stylesheet" href="{{ assets "styles.css" }}"> + {{ $styles := asset "styles.css" }}<link rel="stylesheet" href="{{ $styles.Src }}" integrity="{{ $styles.Checksum }}"> <link rel="shortcut icon" href="{{ static .Logo.Favicon }}"> <meta property="description" content="{{ .Description }}" /> <!-- Open Graph --> @@ -37,6 +37,6 @@ <p id="quote">« {{ .Quote }} »</p> <p><a href="/legal">Mentions légales</a>, <a href="https://git.anhgelus.world/anhgelus/small-web">code source</a>.</p> </footer> -<script src="{{ assets "index.js" }}" defer></script> +{{ $script := asset "index.js" }}<script src="{{ $script.Src }}" integrity="{{ $script.Checksum }}" defer></script> </body> </html> @@ -63,18 +63,19 @@ func main() { os.Exit(2) } - r := backend.NewRouter(dev, cfg) + assetsFS := backend.UsableEmbedFS("dist", embeds) + if dev { + assetsFS = os.DirFS("dist") + } + + r := backend.NewRouter(dev, cfg, assetsFS) backend.HandleHome(r) backend.HandleRoot(r, cfg) backend.HandleLogs(r) backend.Handle404(r) - if dev { - backend.HandleStaticFiles(r, "/assets", os.DirFS("dist")) - } else { - backend.HandleStaticFiles(r, "/assets", backend.UsableEmbedFS("dist", embeds)) - } + backend.HandleStaticFiles(r, "/assets", assetsFS) backend.HandleStaticFiles(r, "/static", os.DirFS(cfg.PublicFolder)) slog.Info("starting http server") |
