webdav: replace File with io.ReadCloser

Closes: https://github.com/emersion/go-webdav/issues/17
This commit is contained in:
Simon Ser 2020-01-21 22:19:34 +01:00
parent a5d750f1e1
commit 6023eb58a0
No known key found for this signature in database
GPG Key ID: 0FDE7BE0E88F5E48
2 changed files with 23 additions and 9 deletions

View File

@ -24,7 +24,7 @@ func (fs LocalFileSystem) path(name string) (string, error) {
return filepath.Join(string(fs), filepath.FromSlash(name)), nil return filepath.Join(string(fs), filepath.FromSlash(name)), nil
} }
func (fs LocalFileSystem) Open(name string) (File, error) { func (fs LocalFileSystem) Open(name string) (io.ReadCloser, error) {
p, err := fs.path(name) p, err := fs.path(name)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -8,19 +8,14 @@ import (
"net/url" "net/url"
"os" "os"
"path" "path"
"strconv"
"github.com/emersion/go-webdav/internal" "github.com/emersion/go-webdav/internal"
) )
type File interface {
io.Closer
io.Reader
io.Seeker
}
// FileSystem is a WebDAV server backend. // FileSystem is a WebDAV server backend.
type FileSystem interface { type FileSystem interface {
Open(name string) (File, error) Open(name string) (io.ReadCloser, error)
Stat(name string) (os.FileInfo, error) Stat(name string) (os.FileInfo, error)
Readdir(name string) ([]os.FileInfo, error) Readdir(name string) ([]os.FileInfo, error)
Create(name string) (io.WriteCloser, error) Create(name string) (io.WriteCloser, error)
@ -94,7 +89,26 @@ func (b *backend) HeadGet(w http.ResponseWriter, r *http.Request) error {
} }
defer f.Close() defer f.Close()
http.ServeContent(w, r, r.URL.Path, fi.ModTime(), f) if rs, ok := f.(io.ReadSeeker); ok {
// If it's an io.Seeker, use http.ServeContent which supports ranges
http.ServeContent(w, r, r.URL.Path, fi.ModTime(), rs)
} else {
// TODO: fallback to http.DetectContentType
t := mime.TypeByExtension(path.Ext(r.URL.Path))
if t != "" {
w.Header().Set("Content-Type", t)
}
if modTime := fi.ModTime(); !modTime.IsZero() {
w.Header().Set("Last-Modified", modTime.UTC().Format(http.TimeFormat))
}
w.Header().Set("Content-Length", strconv.FormatInt(fi.Size(), 10))
if r.Method != http.MethodHead {
io.Copy(w, f)
}
}
return nil return nil
} }