package files import ( "errors" "fmt" "hash/fnv" "io" "os" "strings" "github.com/Southclaws/fault" "github.com/Southclaws/fault/fmsg" "alin.ovh/homestead/shared/storage" ) var encodings = map[string]string{ "br": ".br", "gzip": ".gz", "zstd": ".zstd", } func (r *Reader) OpenFile(path string, filename string) (*storage.File, error) { file, err := storage.NewFile(path, filename) if err != nil { return nil, fault.Wrap(err, fmsg.With("could not init file")) } file.Etag, err = etag(file.Encodings["identity"]) if err != nil { return nil, err } for enc, suffix := range encodings { _, err := os.Stat(filename + suffix) if err != nil { if errors.Is(err, os.ErrNotExist) { continue } return nil, fault.Wrap( err, fmsg.With(fmt.Sprintf("could not stat file %s", filename+suffix)), ) } f, err := os.Open(filename + suffix) if err != nil { return nil, fault.Wrap( err, fmsg.With(fmt.Sprintf("could not read file %s", filename+suffix)), ) } file.Encodings[enc] = f } return file, nil } func etag(f io.Reader) (string, error) { hash := fnv.New64a() if _, err := io.Copy(hash, f); err != nil { return "", fault.Wrap(err, fmsg.With("could not hash file")) } return fmt.Sprintf(`W/"%x"`, hash.Sum(nil)), nil } func pathNameToFileName(pathname string) string { if strings.HasSuffix(pathname, "/") { pathname += "index.html" } return strings.TrimPrefix(pathname, "/") } func cutSuffix(s, suffix string) string { out, _ := strings.CutSuffix(s, suffix) return out } func fileNameToPathName(filename string) string { return cutSuffix( cutSuffix(filename, "index.html"), ".html", ) }
shared/storage/files/file.go (view raw)