mirror of
				https://github.com/caddyserver/caddy.git
				synced 2025-11-04 03:27:23 -05:00 
			
		
		
		
	Drop requirement for filesystems to implement fs.StatFS
Signed-off-by: Dave Henderson <dhenderson@gmail.com>
This commit is contained in:
		
							parent
							
								
									487217519c
								
							
						
					
					
						commit
						fded2644f8
					
				@ -210,7 +210,7 @@ func (fsrv *FileServer) isSymlinkTargetDir(f fs.FileInfo, root, urlPath string)
 | 
				
			|||||||
		return false
 | 
							return false
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	target := caddyhttp.SanitizedPathJoin(root, path.Join(urlPath, f.Name()))
 | 
						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 {
 | 
						if err != nil {
 | 
				
			||||||
		return false
 | 
							return false
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
@ -65,7 +65,7 @@ func (fsrv *FileServer) directoryListing(entries []fs.DirEntry, canGoUp bool, ro
 | 
				
			|||||||
		fileIsSymlink := isSymlink(info)
 | 
							fileIsSymlink := isSymlink(info)
 | 
				
			||||||
		if fileIsSymlink {
 | 
							if fileIsSymlink {
 | 
				
			||||||
			path := caddyhttp.SanitizedPathJoin(root, path.Join(urlPath, info.Name()))
 | 
								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 {
 | 
								if err == nil {
 | 
				
			||||||
				size = fileInfo.Size()
 | 
									size = fileInfo.Size()
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
				
			|||||||
@ -77,11 +77,11 @@ func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error)
 | 
				
			|||||||
				if err != nil {
 | 
									if err != nil {
 | 
				
			||||||
					return nil, err
 | 
										return nil, err
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				statFS, ok := unm.(fs.StatFS)
 | 
									fsys, ok := unm.(fs.FS)
 | 
				
			||||||
				if !ok {
 | 
									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":
 | 
								case "hide":
 | 
				
			||||||
				fsrv.Hide = h.RemainingArgs()
 | 
									fsrv.Hide = h.RemainingArgs()
 | 
				
			||||||
 | 
				
			|||||||
@ -64,7 +64,7 @@ type MatchFile struct {
 | 
				
			|||||||
	// The file system implementation to use. By default, the
 | 
						// The file system implementation to use. By default, the
 | 
				
			||||||
	// local disk file system will be used.
 | 
						// local disk file system will be used.
 | 
				
			||||||
	FileSystemRaw json.RawMessage `json:"file_system,omitempty" caddy:"namespace=caddy.fs inline_key=backend"`
 | 
						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
 | 
						// The root directory, used for creating absolute
 | 
				
			||||||
	// file paths, and required when working with
 | 
						// file paths, and required when working with
 | 
				
			||||||
@ -264,7 +264,7 @@ func (m *MatchFile) Provision(ctx caddy.Context) error {
 | 
				
			|||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return fmt.Errorf("loading file system module: %v", err)
 | 
								return fmt.Errorf("loading file system module: %v", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		m.fileSystem = mod.(fs.StatFS)
 | 
							m.fileSystem = mod.(fs.FS)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if m.fileSystem == nil {
 | 
						if m.fileSystem == nil {
 | 
				
			||||||
		m.fileSystem = osFS{}
 | 
							m.fileSystem = osFS{}
 | 
				
			||||||
@ -418,7 +418,7 @@ func (m MatchFile) selectFile(r *http.Request) (matched bool) {
 | 
				
			|||||||
		for _, pattern := range m.TryFiles {
 | 
							for _, pattern := range m.TryFiles {
 | 
				
			||||||
			candidates := makeCandidates(pattern)
 | 
								candidates := makeCandidates(pattern)
 | 
				
			||||||
			for _, c := range candidates {
 | 
								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 {
 | 
									if err == nil && info.Size() > largestSize {
 | 
				
			||||||
					largestSize = info.Size()
 | 
										largestSize = info.Size()
 | 
				
			||||||
					largest = c
 | 
										largest = c
 | 
				
			||||||
@ -439,7 +439,7 @@ func (m MatchFile) selectFile(r *http.Request) (matched bool) {
 | 
				
			|||||||
		for _, pattern := range m.TryFiles {
 | 
							for _, pattern := range m.TryFiles {
 | 
				
			||||||
			candidates := makeCandidates(pattern)
 | 
								candidates := makeCandidates(pattern)
 | 
				
			||||||
			for _, c := range candidates {
 | 
								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) {
 | 
									if err == nil && (smallestSize == 0 || info.Size() < smallestSize) {
 | 
				
			||||||
					smallestSize = info.Size()
 | 
										smallestSize = info.Size()
 | 
				
			||||||
					smallest = c
 | 
										smallest = c
 | 
				
			||||||
@ -459,7 +459,7 @@ func (m MatchFile) selectFile(r *http.Request) (matched bool) {
 | 
				
			|||||||
		for _, pattern := range m.TryFiles {
 | 
							for _, pattern := range m.TryFiles {
 | 
				
			||||||
			candidates := makeCandidates(pattern)
 | 
								candidates := makeCandidates(pattern)
 | 
				
			||||||
			for _, c := range candidates {
 | 
								for _, c := range candidates {
 | 
				
			||||||
				info, err := m.fileSystem.Stat(c.fullpath)
 | 
									info, err := fs.Stat(m.fileSystem, c.fullpath)
 | 
				
			||||||
				if err == nil &&
 | 
									if err == nil &&
 | 
				
			||||||
					(recentInfo == nil || info.ModTime().After(recentInfo.ModTime())) {
 | 
										(recentInfo == nil || info.ModTime().After(recentInfo.ModTime())) {
 | 
				
			||||||
					recent = c
 | 
										recent = c
 | 
				
			||||||
@ -498,7 +498,7 @@ func parseErrorCode(input string) error {
 | 
				
			|||||||
// NOT end in a forward slash, the file must NOT
 | 
					// NOT end in a forward slash, the file must NOT
 | 
				
			||||||
// be a directory.
 | 
					// be a directory.
 | 
				
			||||||
func (m MatchFile) strictFileExists(file string) (os.FileInfo, bool) {
 | 
					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 {
 | 
						if err != nil {
 | 
				
			||||||
		// in reality, this can be any error
 | 
							// in reality, this can be any error
 | 
				
			||||||
		// such as permission or even obscure
 | 
							// such as permission or even obscure
 | 
				
			||||||
 | 
				
			|||||||
@ -83,14 +83,14 @@ type FileServer struct {
 | 
				
			|||||||
	// disk file system.
 | 
						// disk file system.
 | 
				
			||||||
	//
 | 
						//
 | 
				
			||||||
	// File system modules used here must adhere to the following requirements:
 | 
						// 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
 | 
						// - Support seeking on opened files; i.e.returned fs.File values must
 | 
				
			||||||
	//   implement the io.Seeker interface. This is required for determining
 | 
						//   implement the io.Seeker interface. This is required for determining
 | 
				
			||||||
	//   Content-Length and satisfying Range requests.
 | 
						//   Content-Length and satisfying Range requests.
 | 
				
			||||||
	// - fs.File values that represent directories must implement the
 | 
						// - fs.File values that represent directories must implement the
 | 
				
			||||||
	//   fs.ReadDirFile interface so that directory listings can be procured.
 | 
						//   fs.ReadDirFile interface so that directory listings can be procured.
 | 
				
			||||||
	FileSystemRaw json.RawMessage `json:"file_system,omitempty" caddy:"namespace=caddy.fs inline_key=backend"`
 | 
						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,
 | 
						// 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.
 | 
						// 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 {
 | 
							if err != nil {
 | 
				
			||||||
			return fmt.Errorf("loading file system module: %v", err)
 | 
								return fmt.Errorf("loading file system module: %v", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		fsrv.fileSystem = mod.(fs.StatFS)
 | 
							fsrv.fileSystem = mod.(fs.FS)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if fsrv.fileSystem == nil {
 | 
						if fsrv.fileSystem == nil {
 | 
				
			||||||
		fsrv.fileSystem = osFS{}
 | 
							fsrv.fileSystem = osFS{}
 | 
				
			||||||
@ -244,7 +244,7 @@ func (fsrv *FileServer) ServeHTTP(w http.ResponseWriter, r *http.Request, next c
 | 
				
			|||||||
		zap.String("result", filename))
 | 
							zap.String("result", filename))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// get information about the file
 | 
						// get information about the file
 | 
				
			||||||
	info, err := fsrv.fileSystem.Stat(filename)
 | 
						info, err := fs.Stat(fsrv.fileSystem, filename)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		err = fsrv.mapDirOpenError(err, filename)
 | 
							err = fsrv.mapDirOpenError(err, filename)
 | 
				
			||||||
		if errors.Is(err, fs.ErrNotExist) {
 | 
							if errors.Is(err, fs.ErrNotExist) {
 | 
				
			||||||
@ -270,7 +270,7 @@ func (fsrv *FileServer) ServeHTTP(w http.ResponseWriter, r *http.Request, next c
 | 
				
			|||||||
				continue
 | 
									continue
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			indexInfo, err := fsrv.fileSystem.Stat(indexPath)
 | 
								indexInfo, err := fs.Stat(fsrv.fileSystem, indexPath)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				continue
 | 
									continue
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@ -350,7 +350,7 @@ func (fsrv *FileServer) ServeHTTP(w http.ResponseWriter, r *http.Request, next c
 | 
				
			|||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		compressedFilename := filename + precompress.Suffix()
 | 
							compressedFilename := filename + precompress.Suffix()
 | 
				
			||||||
		compressedInfo, err := fsrv.fileSystem.Stat(compressedFilename)
 | 
							compressedInfo, err := fs.Stat(fsrv.fileSystem, compressedFilename)
 | 
				
			||||||
		if err != nil || compressedInfo.IsDir() {
 | 
							if err != nil || compressedInfo.IsDir() {
 | 
				
			||||||
			fsrv.logger.Debug("precompressed file not accessible", zap.String("filename", compressedFilename), zap.Error(err))
 | 
								fsrv.logger.Debug("precompressed file not accessible", zap.String("filename", compressedFilename), zap.Error(err))
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
@ -490,7 +490,7 @@ func (fsrv *FileServer) mapDirOpenError(originalErr error, name string) error {
 | 
				
			|||||||
		if parts[i] == "" {
 | 
							if parts[i] == "" {
 | 
				
			||||||
			continue
 | 
								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 {
 | 
							if err != nil {
 | 
				
			||||||
			return originalErr
 | 
								return originalErr
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -613,13 +613,13 @@ func (wr statusOverrideResponseWriter) WriteHeader(int) {
 | 
				
			|||||||
	wr.ResponseWriter.WriteHeader(wr.code)
 | 
						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
 | 
					// file system. (We do not use os.DirFS because we do our own
 | 
				
			||||||
// rooting or path prefixing without being constrained to a single
 | 
					// rooting or path prefixing without being constrained to a single
 | 
				
			||||||
// root folder. The standard os.DirFS implementation is problematic
 | 
					// root folder. The standard os.DirFS implementation is problematic
 | 
				
			||||||
// since roots can be dynamic in our application.)
 | 
					// 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{}
 | 
					type osFS struct{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (osFS) Open(name string) (fs.File, error)          { return os.Open(name) }
 | 
					func (osFS) Open(name string) (fs.File, error)          { return os.Open(name) }
 | 
				
			||||||
@ -640,6 +640,7 @@ var (
 | 
				
			|||||||
	_ caddy.Provisioner           = (*FileServer)(nil)
 | 
						_ caddy.Provisioner           = (*FileServer)(nil)
 | 
				
			||||||
	_ caddyhttp.MiddlewareHandler = (*FileServer)(nil)
 | 
						_ caddyhttp.MiddlewareHandler = (*FileServer)(nil)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_ fs.StatFS     = (*osFS)(nil)
 | 
				
			||||||
	_ fs.GlobFS     = (*osFS)(nil)
 | 
						_ fs.GlobFS     = (*osFS)(nil)
 | 
				
			||||||
	_ fs.ReadDirFS  = (*osFS)(nil)
 | 
						_ fs.ReadDirFS  = (*osFS)(nil)
 | 
				
			||||||
	_ fs.ReadFileFS = (*osFS)(nil)
 | 
						_ fs.ReadFileFS = (*osFS)(nil)
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user