From e851e6e3f1fef54a9388be8d5d62b1b7717c743e Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Tue, 21 Jan 2020 19:55:02 +0100 Subject: [PATCH] webdav: remove File.Stat, add FileSystem.Stat References: https://github.com/emersion/go-webdav/issues/15 --- fs_local.go | 8 ++++++++ server.go | 46 +++++++++++++++++++++------------------------- 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/fs_local.go b/fs_local.go index c7ab3ef..67f8d6d 100644 --- a/fs_local.go +++ b/fs_local.go @@ -31,4 +31,12 @@ func (fs LocalFileSystem) Open(name string) (File, error) { return os.Open(p) } +func (fs LocalFileSystem) Stat(name string) (os.FileInfo, error) { + p, err := fs.path(name) + if err != nil { + return nil, err + } + return os.Stat(p) +} + var _ FileSystem = LocalFileSystem("") diff --git a/server.go b/server.go index c3f5517..3078db0 100644 --- a/server.go +++ b/server.go @@ -2,6 +2,7 @@ package webdav import ( "encoding/xml" + "io" "mime" "net/http" "os" @@ -11,11 +12,15 @@ import ( ) type File interface { - http.File + io.Closer + io.Reader + io.Seeker + Readdir(count int) ([]os.FileInfo, error) } type FileSystem interface { Open(name string) (File, error) + Stat(name string) (os.FileInfo, error) } type Handler struct { @@ -38,18 +43,12 @@ type backend struct { } func (b *backend) Options(r *http.Request) ([]string, error) { - f, err := b.FileSystem.Open(r.URL.Path) + fi, err := b.FileSystem.Stat(r.URL.Path) if os.IsNotExist(err) { return []string{http.MethodOptions}, nil } else if err != nil { return nil, err } - defer f.Close() - - fi, err := f.Stat() - if err != nil { - return nil, err - } if fi.IsDir() { return []string{http.MethodOptions, "PROPFIND"}, nil @@ -59,34 +58,31 @@ func (b *backend) Options(r *http.Request) ([]string, error) { } func (b *backend) HeadGet(w http.ResponseWriter, r *http.Request) error { + fi, err := b.FileSystem.Stat(r.URL.Path) + if os.IsNotExist(err) { + return &internal.HTTPError{Code: http.StatusNotFound, Err: err} + } else if err != nil { + return err + } + if fi.IsDir() { + return &internal.HTTPError{Code: http.StatusMethodNotAllowed} + } + f, err := b.FileSystem.Open(r.URL.Path) if err != nil { return err } defer f.Close() - fi, err := f.Stat() - if err != nil { - return err - } - - if fi.IsDir() { - return &internal.HTTPError{Code: http.StatusMethodNotAllowed} - } - http.ServeContent(w, r, r.URL.Path, fi.ModTime(), f) return nil } func (b *backend) Propfind(r *http.Request, propfind *internal.Propfind, depth internal.Depth) (*internal.Multistatus, error) { - f, err := b.FileSystem.Open(r.URL.Path) - if err != nil { - return nil, err - } - defer f.Close() - - fi, err := f.Stat() - if err != nil { + fi, err := b.FileSystem.Stat(r.URL.Path) + if os.IsNotExist(err) { + return nil, &internal.HTTPError{Code: http.StatusNotFound, Err: err} + } else if err != nil { return nil, err }