package main import ( "fmt" "hash/fnv" "io" "io/fs" "log" "log/slog" "os" "path/filepath" "strings" "github.com/pkg/errors" ) type File struct { filename string etag string } var files = map[string]File{} func hashFile(filename string) (string, error) { f, err := os.Open(filename) if err != nil { return "", err } defer f.Close() hash := fnv.New64a() if _, err := io.Copy(hash, f); err != nil { return "", err } return fmt.Sprintf(`W/"%x"`, hash.Sum(nil)), nil } func registerFile(urlpath string, filepath string) error { if files[urlpath] != (File{}) { log.Printf("registerFile called with duplicate file, urlPath: %s", urlpath) return nil } hash, err := hashFile(filepath) if err != nil { return err } files[urlpath] = File{ filename: filepath, etag: hash, } return nil } func registerContentFiles(root string) error { err := filepath.WalkDir(root, func(filePath string, f fs.DirEntry, err error) error { if err != nil { return errors.WithMessagef(err, "failed to access path %s", filePath) } relPath, err := filepath.Rel(root, filePath) if err != nil { return errors.WithMessagef(err, "failed to make path relative, path: %s", filePath) } urlPath, _ := strings.CutSuffix(relPath, "index.html") if !f.IsDir() { slog.Debug("registering file", "urlpath", "/"+urlPath) return registerFile("/"+urlPath, filePath) } return nil }) if err != nil { return err } return nil } func GetFile(urlPath string) File { return files[urlPath] }