From dfc5b0460bd08cf657a0f796b004458557abb8db Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Wed, 8 Jun 2022 14:31:25 +0100 Subject: [PATCH] webdav: add --webdav-base-path flag for unusual servers See: https://forum.rclone.org/t/how-to-specify-a-webdav-backend-root-path-using-connection-string-syntax/31092 --- backend/webdav/webdav.go | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/backend/webdav/webdav.go b/backend/webdav/webdav.go index 64c3e983a..834a27362 100644 --- a/backend/webdav/webdav.go +++ b/backend/webdav/webdav.go @@ -124,6 +124,22 @@ You can set multiple headers, e.g. '"Cookie","name=value","Authorization","xxx"' `, Default: fs.CommaSepList{}, Advanced: true, + }, { + Name: "base_path", + Help: `Base path of expected replies + +Normally WebDAV servers return the files they are listing under the +url path as specified above. However some WebDAV servers return files +with URLs that are not under the endpoint URL. This causes rclone to +get confused and return errors like + + Item with unknown path received: "/remote.php/webdav/folder1/", "/elsewhere/remote.php/webdav/folder1/" + +errors. If that is the case, then set "base_path" to the path +specified in the error message up to the first item, in the above +example "/elsewhere/remote.php/webdav/". +`, + Advanced: true, }}, }) } @@ -138,6 +154,7 @@ type Options struct { BearerTokenCommand string `config:"bearer_token_command"` Enc encoder.MultiEncoder `config:"encoding"` Headers fs.CommaSepList `config:"headers"` + BasePath string `config:"base_path"` } // Fs represents a remote webdav @@ -693,6 +710,10 @@ func (f *Fs) listAll(ctx context.Context, dir string, directoriesOnly bool, file if err != nil { return false, fmt.Errorf("couldn't join URL: %w", err) } + basePath := baseURL.Path + if f.opt.BasePath != "" { + basePath = f.opt.BasePath + } for i := range result.Responses { item := &result.Responses[i] isDir := itemIsDir(item) @@ -707,11 +728,11 @@ func (f *Fs) listAll(ctx context.Context, dir string, directoriesOnly bool, file if isDir { u.Path = addSlash(u.Path) } - if !strings.HasPrefix(u.Path, baseURL.Path) { - fs.Debugf(nil, "Item with unknown path received: %q, %q", u.Path, baseURL.Path) + if !strings.HasPrefix(u.Path, basePath) { + fs.Debugf(nil, "Item with unknown path received: %q, %q", u.Path, basePath) continue } - subPath := u.Path[len(baseURL.Path):] + subPath := u.Path[len(basePath):] if f.opt.Enc != encoder.EncodeZero { subPath = f.opt.Enc.ToStandardPath(subPath) }