WebDAV: Add timeout for fetching directories #664

This commit is contained in:
Michael Mayer 2020-12-05 01:24:33 +01:00
parent 917abbe39f
commit 56851f4892
4 changed files with 27 additions and 9 deletions

View File

@ -106,7 +106,7 @@ func (m *Account) Delete() error {
func (m *Account) Directories() (result fs.FileInfos, err error) { func (m *Account) Directories() (result fs.FileInfos, err error) {
if m.AccType == remote.ServiceWebDAV { if m.AccType == remote.ServiceWebDAV {
c := webdav.New(m.AccURL, m.AccUser, m.AccPass) c := webdav.New(m.AccURL, m.AccUser, m.AccPass)
result, err = c.Directories("/", true) result, err = c.Directories("/", true, webdav.SyncTimeout)
} }
sort.Sort(result) sort.Sort(result)

View File

@ -45,6 +45,9 @@ import (
var log = event.Log var log = event.Log
const SyncTimeout = time.Second * 45
const AsyncTimeout = time.Minute * 20
type Client struct { type Client struct {
client *gowebdav.Client client *gowebdav.Client
} }
@ -55,7 +58,9 @@ func New(url, user, pass string) Client {
clt.SetTimeout(10 * time.Minute) // TODO: Change timeout if needed clt.SetTimeout(10 * time.Minute) // TODO: Change timeout if needed
result := Client{client: clt} result := Client{
client: clt,
}
return result return result
} }
@ -90,7 +95,20 @@ func (c Client) Files(dir string) (result fs.FileInfos, err error) {
} }
// Directories returns all sub directories in path as string slice. // Directories returns all sub directories in path as string slice.
func (c Client) Directories(root string, recursive bool) (result fs.FileInfos, err error) { func (c Client) Directories(root string, recursive bool, timeout time.Duration) (result fs.FileInfos, err error) {
start := time.Now()
result, err = c.fetchDirs(root, recursive, start, timeout)
if time.Now().Sub(start) >= timeout {
log.Warnf("webdav: read dir timeout reached")
}
return result, err
}
// fetchDirs recursively fetches all directories until the timeout is reached.
func (c Client) fetchDirs(root string, recursive bool, start time.Time, timeout time.Duration) (result fs.FileInfos, err error) {
files, err := c.readDir(root) files, err := c.readDir(root)
if err != nil { if err != nil {
@ -110,8 +128,8 @@ func (c Client) Directories(root string, recursive bool) (result fs.FileInfos, e
result = append(result, info) result = append(result, info)
if recursive { if recursive && time.Now().Sub(start) < timeout {
subDirs, err := c.Directories(info.Abs, true) subDirs, err := c.fetchDirs(info.Abs, true, start, timeout)
if err != nil { if err != nil {
return result, err return result, err
@ -182,7 +200,7 @@ func (c Client) DownloadDir(from, to string, recursive, force bool) (errs []erro
return errs return errs
} }
dirs, err := c.Directories(from, false) dirs, err := c.Directories(from, false, AsyncTimeout)
for _, dir := range dirs { for _, dir := range dirs {
errs = append(errs, c.DownloadDir(dir.Abs, to, true, force)...) errs = append(errs, c.DownloadDir(dir.Abs, to, true, force)...)

View File

@ -44,7 +44,7 @@ func TestClient_Directories(t *testing.T) {
assert.IsType(t, Client{}, c) assert.IsType(t, Client{}, c)
t.Run("non-recursive", func(t *testing.T) { t.Run("non-recursive", func(t *testing.T) {
dirs, err := c.Directories("", false) dirs, err := c.Directories("", false, SyncTimeout)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -62,7 +62,7 @@ func TestClient_Directories(t *testing.T) {
}) })
t.Run("recursive", func(t *testing.T) { t.Run("recursive", func(t *testing.T) {
dirs, err := c.Directories("", true) dirs, err := c.Directories("", true, SyncTimeout)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)

View File

@ -16,7 +16,7 @@ func (worker *Sync) refresh(a entity.Account) (complete bool, err error) {
client := webdav.New(a.AccURL, a.AccUser, a.AccPass) client := webdav.New(a.AccURL, a.AccUser, a.AccPass)
subDirs, err := client.Directories(a.SyncPath, true) subDirs, err := client.Directories(a.SyncPath, true, webdav.AsyncTimeout)
if err != nil { if err != nil {
log.Error(err) log.Error(err)