From d2001de5f3c71d4edf081866ba16059d1cb88bf9 Mon Sep 17 00:00:00 2001 From: Adnan Maolood Date: Tue, 16 Feb 2021 18:53:41 -0500 Subject: [PATCH] fs: Replace FileSystem with io/fs.FS --- fs.go | 58 ++++++++-------------------------------------------------- 1 file changed, 8 insertions(+), 50 deletions(-) diff --git a/fs.go b/fs.go index 2a33e3d..7ebe82d 100644 --- a/fs.go +++ b/fs.go @@ -2,8 +2,8 @@ package gemini import ( "io" + "io/fs" "mime" - "os" "path" ) @@ -13,60 +13,18 @@ func init() { mime.AddExtensionType(".gemini", "text/gemini") } -// A FileSystem implements access to a collection of named files. The elements -// in a file path are separated by slash ('/', U+002F) characters, regardless -// of host operating system convention. -type FileSystem interface { - Open(name string) (File, error) -} - -// A File is returned by a FileSystem's Open method and can be served by the -// FileServer implementation. -// -// The methods should behave the same as those on an *os.File. -type File interface { - Stat() (os.FileInfo, error) - Read([]byte) (int, error) - Close() error -} - -// A Dir implements FileSystem using the native file system restricted -// to a specific directory tree. -// -// While the FileSystem.Open method takes '/'-separated paths, a Dir's string -// value is a filename on the native file system, not a URL, so it is separated -// by filepath.Separator, which isn't necessarily '/'. -// -// Note that Dir could expose sensitive files and directories. Dir will follow -// symlinks pointing out of the directory tree, which can be especially -// dangerous if serving from a directory in which users are able to create -// arbitrary symlinks. Dir will also allow access to files and directories -// starting with a period, which could expose sensitive directories like .git -// or sensitive files like .htpasswd. To exclude files with a leading period, -// remove the files/directories from the server or create a custom FileSystem -// implementation. -// -// An empty Dir is treated as ".". -type Dir string - -// Open implements FileSystem using os.Open, opening files for reading -// rooted and relative to the directory d. -func (d Dir) Open(name string) (File, error) { - return os.Open(path.Join(string(d), name)) -} - // FileServer returns a handler that serves Gemini requests with the contents // of the provided file system. // -// To use the operating system's file system implementation, use gemini.Dir: +// To use the operating system's file system implementation, use os.DirFS: // -// gemini.FileServer(gemini.Dir("/tmp")) -func FileServer(fsys FileSystem) Handler { +// gemini.FileServer(os.DirFS("/tmp")) +func FileServer(fsys fs.FS) Handler { return fileServer{fsys} } type fileServer struct { - FileSystem + fs.FS } func (fs fileServer) ServeGemini(w ResponseWriter, r *Request) { @@ -80,7 +38,7 @@ func (fs fileServer) ServeGemini(w ResponseWriter, r *Request) { // relative to the current directory and may ascend to parent directories. If // the provided name is constructed from user input, it should be sanitized // before calling ServeFile. -func ServeFile(w ResponseWriter, fsys FileSystem, name string) { +func ServeFile(w ResponseWriter, fsys fs.FS, name string) { f, err := openFile(fsys, name) if err != nil { w.Status(StatusNotFound) @@ -94,7 +52,7 @@ func ServeFile(w ResponseWriter, fsys FileSystem, name string) { _, _ = io.Copy(w, f) } -func openFile(fsys FileSystem, name string) (File, error) { +func openFile(fsys fs.FS, name string) (fs.File, error) { f, err := fsys.Open(name) if err != nil { return nil, err @@ -123,5 +81,5 @@ func openFile(fsys FileSystem, name string) (File, error) { } } - return nil, os.ErrNotExist + return nil, fs.ErrNotExist }