diff options
| author | Rose Hogenson <rosehogenson@posteo.net> | 2026-08-20 15:41:52 -0700 |
|---|---|---|
| committer | Rose Hogenson <rosehogenson@posteo.net> | 2026-08-20 15:47:18 -0700 |
| commit | dc9303a52320c89956c129298285eb75869ac5f0 (patch) | |
| tree | a4343d417e2544187b1312e81272f7267defde54 /roseh.moe.go | |
| parent | b4cb28b0c019252326d372630bd52b2a3559f426 (diff) | |
| download | roseh.moe-dc9303a52320c89956c129298285eb75869ac5f0.tar.zst | |
Add ETag for static files
Diffstat (limited to 'roseh.moe.go')
| -rw-r--r-- | roseh.moe.go | 40 |
1 files changed, 37 insertions, 3 deletions
diff --git a/roseh.moe.go b/roseh.moe.go index 206679b..95f303c 100644 --- a/roseh.moe.go +++ b/roseh.moe.go @@ -48,8 +48,6 @@ var ( holeTempDir = flag.String("hole-temp-dir", "hole", "directory to store temporary files for the wormhole") codeDir = flag.String("code-dir", "code", "directory to serve git repos") nezuko = flag.String("nezuko", "nezuko", "nezuko partition") - - serverStartTime = time.Now() ) var notepadPassword, secretKey, authenticatorKey []byte @@ -228,6 +226,31 @@ func stallmanShooter(w http.ResponseWriter, _ *http.Request) { //go:embed static var staticFiles embed.FS +var staticFileHashes = buildStaticFileHashes() + +func buildStaticFileHashes() map[string]string { + hashMap := make(map[string]string) + if err := fs.WalkDir(staticFiles, ".", func(path string, d fs.DirEntry, err error) error { + if err != nil || d.IsDir() { + return err + } + f, err := staticFiles.Open(path) + if err != nil { + return err + } + defer f.Close() + h := sha256.New() + if _, err := io.Copy(h, f); err != nil { + return err + } + hashMap[path] = `"` + base64.RawURLEncoding.EncodeToString(h.Sum(nil)[:8]) + `"` + return nil + }); err != nil { + panic(fmt.Sprintf("Build static file hash map: %s", err)) + } + return hashMap +} + func serveStaticFile(w http.ResponseWriter, r *http.Request, path string) { f, err := staticFiles.Open(path) if err != nil { @@ -235,7 +258,18 @@ func serveStaticFile(w http.ResponseWriter, r *http.Request, path string) { return } defer f.Close() - http.ServeContent(w, r, path, serverStartTime, f.(io.ReadSeeker)) + stat, err := f.Stat() + if err != nil { + log.Printf("Warning: stat static file: %s", err) + http.Error(w, "internal error", http.StatusInternalServerError) + return + } + if stat.IsDir() { + notFound(w, r) + return + } + w.Header().Set("ETag", staticFileHashes[path]) + http.ServeContent(w, r, path, time.Time{}, f.(io.ReadSeeker)) } func static(w http.ResponseWriter, r *http.Request) { |
