webdav: list children in PROPFIND

This commit is contained in:
Simon Ser 2020-01-15 18:39:25 +01:00
parent ae93da82c1
commit d83efedfb5
No known key found for this signature in database
GPG Key ID: 0FDE7BE0E88F5E48

View File

@ -6,6 +6,7 @@ import (
"mime" "mime"
"net/http" "net/http"
"os" "os"
"path"
"github.com/emersion/go-webdav/internal" "github.com/emersion/go-webdav/internal"
) )
@ -104,6 +105,8 @@ func (h *Handler) handlePropfind(w http.ResponseWriter, r *http.Request) error {
} }
} }
// TODO: refuse DepthInfinity, can cause infinite loops with symlinks
f, err := h.FileSystem.Open(r.URL.Path) f, err := h.FileSystem.Open(r.URL.Path)
if err != nil { if err != nil {
return err return err
@ -115,16 +118,12 @@ func (h *Handler) handlePropfind(w http.ResponseWriter, r *http.Request) error {
return err return err
} }
if depth != internal.DepthZero { var resps []internal.Response
depth = internal.DepthZero // TODO if err := h.propfind(&propfind, r.URL.Path, fi, depth, &resps); err != nil {
}
resp, err := h.propfindFile(&propfind, r.URL.Path, fi)
if err != nil {
return err return err
} }
ms := internal.NewMultistatus(*resp) ms := internal.NewMultistatus(resps...)
w.Header().Add("Content-Type", "text/xml; charset=\"utf-8\"") w.Header().Add("Content-Type", "text/xml; charset=\"utf-8\"")
w.WriteHeader(http.StatusMultiStatus) w.WriteHeader(http.StatusMultiStatus)
@ -132,6 +131,42 @@ func (h *Handler) handlePropfind(w http.ResponseWriter, r *http.Request) error {
return xml.NewEncoder(w).Encode(&ms) return xml.NewEncoder(w).Encode(&ms)
} }
func (h *Handler) propfind(propfind *internal.Propfind, name string, fi os.FileInfo, depth internal.Depth, resps *[]internal.Response) error {
// TODO: use partial error Response on error
resp, err := h.propfindFile(propfind, name, fi)
if err != nil {
return err
}
*resps = append(*resps, *resp)
if depth != internal.DepthZero && fi.IsDir() {
childDepth := depth
if depth == internal.DepthOne {
childDepth = internal.DepthZero
}
f, err := h.FileSystem.Open(name)
if err != nil {
return err
}
defer f.Close()
children, err := f.Readdir(-1)
if err != nil {
return err
}
for _, child := range children {
if err := h.propfind(propfind, path.Join(name, child.Name()), child, childDepth, resps); err != nil {
return err
}
}
}
return nil
}
func (h *Handler) propfindFile(propfind *internal.Propfind, name string, fi os.FileInfo) (*internal.Response, error) { func (h *Handler) propfindFile(propfind *internal.Propfind, name string, fi os.FileInfo) (*internal.Response, error) {
resp := internal.NewOKResponse(name) resp := internal.NewOKResponse(name)