From fded2644f8ddda33002353ee3aedd15195f17cb5 Mon Sep 17 00:00:00 2001 From: Dave Henderson Date: Mon, 5 Sep 2022 19:25:34 -0400 Subject: [PATCH] Drop requirement for filesystems to implement fs.StatFS Signed-off-by: Dave Henderson --- modules/caddyhttp/fileserver/browse.go | 2 +- .../caddyhttp/fileserver/browsetplcontext.go | 2 +- modules/caddyhttp/fileserver/caddyfile.go | 6 +++--- modules/caddyhttp/fileserver/matcher.go | 12 ++++++------ modules/caddyhttp/fileserver/staticfiles.go | 19 ++++++++++--------- 5 files changed, 21 insertions(+), 20 deletions(-) diff --git a/modules/caddyhttp/fileserver/browse.go b/modules/caddyhttp/fileserver/browse.go index 90263560..7804d19b 100644 --- a/modules/caddyhttp/fileserver/browse.go +++ b/modules/caddyhttp/fileserver/browse.go @@ -210,7 +210,7 @@ func (fsrv *FileServer) isSymlinkTargetDir(f fs.FileInfo, root, urlPath string) return false } target := caddyhttp.SanitizedPathJoin(root, path.Join(urlPath, f.Name())) - targetInfo, err := fsrv.fileSystem.Stat(target) + targetInfo, err := fs.Stat(fsrv.fileSystem, target) if err != nil { return false } diff --git a/modules/caddyhttp/fileserver/browsetplcontext.go b/modules/caddyhttp/fileserver/browsetplcontext.go index 49788ee2..cd24fc23 100644 --- a/modules/caddyhttp/fileserver/browsetplcontext.go +++ b/modules/caddyhttp/fileserver/browsetplcontext.go @@ -65,7 +65,7 @@ func (fsrv *FileServer) directoryListing(entries []fs.DirEntry, canGoUp bool, ro fileIsSymlink := isSymlink(info) if fileIsSymlink { path := caddyhttp.SanitizedPathJoin(root, path.Join(urlPath, info.Name())) - fileInfo, err := fsrv.fileSystem.Stat(path) + fileInfo, err := fs.Stat(fsrv.fileSystem, path) if err == nil { size = fileInfo.Size() } diff --git a/modules/caddyhttp/fileserver/caddyfile.go b/modules/caddyhttp/fileserver/caddyfile.go index 1a0424c1..df56092b 100644 --- a/modules/caddyhttp/fileserver/caddyfile.go +++ b/modules/caddyhttp/fileserver/caddyfile.go @@ -77,11 +77,11 @@ func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error) if err != nil { return nil, err } - statFS, ok := unm.(fs.StatFS) + fsys, ok := unm.(fs.FS) if !ok { - return nil, h.Errf("module %s (%T) is not a supported file system implementation (requires fs.StatFS)", modID, unm) + return nil, h.Errf("module %s (%T) is not a supported file system implementation (requires fs.FS)", modID, unm) } - fsrv.FileSystemRaw = caddyconfig.JSONModuleObject(statFS, "backend", name, nil) + fsrv.FileSystemRaw = caddyconfig.JSONModuleObject(fsys, "backend", name, nil) case "hide": fsrv.Hide = h.RemainingArgs() diff --git a/modules/caddyhttp/fileserver/matcher.go b/modules/caddyhttp/fileserver/matcher.go index a5dab6eb..87a15243 100644 --- a/modules/caddyhttp/fileserver/matcher.go +++ b/modules/caddyhttp/fileserver/matcher.go @@ -64,7 +64,7 @@ type MatchFile struct { // The file system implementation to use. By default, the // local disk file system will be used. FileSystemRaw json.RawMessage `json:"file_system,omitempty" caddy:"namespace=caddy.fs inline_key=backend"` - fileSystem fs.StatFS + fileSystem fs.FS // The root directory, used for creating absolute // file paths, and required when working with @@ -264,7 +264,7 @@ func (m *MatchFile) Provision(ctx caddy.Context) error { if err != nil { return fmt.Errorf("loading file system module: %v", err) } - m.fileSystem = mod.(fs.StatFS) + m.fileSystem = mod.(fs.FS) } if m.fileSystem == nil { m.fileSystem = osFS{} @@ -418,7 +418,7 @@ func (m MatchFile) selectFile(r *http.Request) (matched bool) { for _, pattern := range m.TryFiles { candidates := makeCandidates(pattern) for _, c := range candidates { - info, err := m.fileSystem.Stat(c.fullpath) + info, err := fs.Stat(m.fileSystem, c.fullpath) if err == nil && info.Size() > largestSize { largestSize = info.Size() largest = c @@ -439,7 +439,7 @@ func (m MatchFile) selectFile(r *http.Request) (matched bool) { for _, pattern := range m.TryFiles { candidates := makeCandidates(pattern) for _, c := range candidates { - info, err := m.fileSystem.Stat(c.fullpath) + info, err := fs.Stat(m.fileSystem, c.fullpath) if err == nil && (smallestSize == 0 || info.Size() < smallestSize) { smallestSize = info.Size() smallest = c @@ -459,7 +459,7 @@ func (m MatchFile) selectFile(r *http.Request) (matched bool) { for _, pattern := range m.TryFiles { candidates := makeCandidates(pattern) for _, c := range candidates { - info, err := m.fileSystem.Stat(c.fullpath) + info, err := fs.Stat(m.fileSystem, c.fullpath) if err == nil && (recentInfo == nil || info.ModTime().After(recentInfo.ModTime())) { recent = c @@ -498,7 +498,7 @@ func parseErrorCode(input string) error { // NOT end in a forward slash, the file must NOT // be a directory. func (m MatchFile) strictFileExists(file string) (os.FileInfo, bool) { - info, err := m.fileSystem.Stat(file) + info, err := fs.Stat(m.fileSystem, file) if err != nil { // in reality, this can be any error // such as permission or even obscure diff --git a/modules/caddyhttp/fileserver/staticfiles.go b/modules/caddyhttp/fileserver/staticfiles.go index 25bcf5a2..0639d979 100644 --- a/modules/caddyhttp/fileserver/staticfiles.go +++ b/modules/caddyhttp/fileserver/staticfiles.go @@ -83,14 +83,14 @@ type FileServer struct { // disk file system. // // File system modules used here must adhere to the following requirements: - // - Implement fs.StatFS interface. + // - Implement fs.FS interface. // - Support seeking on opened files; i.e.returned fs.File values must // implement the io.Seeker interface. This is required for determining // Content-Length and satisfying Range requests. // - fs.File values that represent directories must implement the // fs.ReadDirFile interface so that directory listings can be procured. FileSystemRaw json.RawMessage `json:"file_system,omitempty" caddy:"namespace=caddy.fs inline_key=backend"` - fileSystem fs.StatFS + fileSystem fs.FS // The path to the root of the site. Default is `{http.vars.root}` if set, // or current working directory otherwise. This should be a trusted value. @@ -175,7 +175,7 @@ func (fsrv *FileServer) Provision(ctx caddy.Context) error { if err != nil { return fmt.Errorf("loading file system module: %v", err) } - fsrv.fileSystem = mod.(fs.StatFS) + fsrv.fileSystem = mod.(fs.FS) } if fsrv.fileSystem == nil { fsrv.fileSystem = osFS{} @@ -244,7 +244,7 @@ func (fsrv *FileServer) ServeHTTP(w http.ResponseWriter, r *http.Request, next c zap.String("result", filename)) // get information about the file - info, err := fsrv.fileSystem.Stat(filename) + info, err := fs.Stat(fsrv.fileSystem, filename) if err != nil { err = fsrv.mapDirOpenError(err, filename) if errors.Is(err, fs.ErrNotExist) { @@ -270,7 +270,7 @@ func (fsrv *FileServer) ServeHTTP(w http.ResponseWriter, r *http.Request, next c continue } - indexInfo, err := fsrv.fileSystem.Stat(indexPath) + indexInfo, err := fs.Stat(fsrv.fileSystem, indexPath) if err != nil { continue } @@ -350,7 +350,7 @@ func (fsrv *FileServer) ServeHTTP(w http.ResponseWriter, r *http.Request, next c continue } compressedFilename := filename + precompress.Suffix() - compressedInfo, err := fsrv.fileSystem.Stat(compressedFilename) + compressedInfo, err := fs.Stat(fsrv.fileSystem, compressedFilename) if err != nil || compressedInfo.IsDir() { fsrv.logger.Debug("precompressed file not accessible", zap.String("filename", compressedFilename), zap.Error(err)) continue @@ -490,7 +490,7 @@ func (fsrv *FileServer) mapDirOpenError(originalErr error, name string) error { if parts[i] == "" { continue } - fi, err := fsrv.fileSystem.Stat(strings.Join(parts[:i+1], separator)) + fi, err := fs.Stat(fsrv.fileSystem, strings.Join(parts[:i+1], separator)) if err != nil { return originalErr } @@ -613,13 +613,13 @@ func (wr statusOverrideResponseWriter) WriteHeader(int) { wr.ResponseWriter.WriteHeader(wr.code) } -// osFS is a simple fs.StatFS implementation that uses the local +// osFS is a simple fs.FS implementation that uses the local // file system. (We do not use os.DirFS because we do our own // rooting or path prefixing without being constrained to a single // root folder. The standard os.DirFS implementation is problematic // since roots can be dynamic in our application.) // -// osFS also implements fs.GlobFS, fs.ReadDirFS, and fs.ReadFileFS. +// osFS also implements fs.StatFS, fs.GlobFS, fs.ReadDirFS, and fs.ReadFileFS. type osFS struct{} func (osFS) Open(name string) (fs.File, error) { return os.Open(name) } @@ -640,6 +640,7 @@ var ( _ caddy.Provisioner = (*FileServer)(nil) _ caddyhttp.MiddlewareHandler = (*FileServer)(nil) + _ fs.StatFS = (*osFS)(nil) _ fs.GlobFS = (*osFS)(nil) _ fs.ReadDirFS = (*osFS)(nil) _ fs.ReadFileFS = (*osFS)(nil)