1
0
mirror of https://github.com/gilbertchen/duplicacy synced 2025-12-15 15:53:26 +00:00

Retry on "unexpected EOF" errors for the webdav backend.

This commit is contained in:
Gilbert Chen
2020-07-03 11:48:30 -04:00
parent 153f6a2d20
commit f2f07a120d

View File

@@ -14,7 +14,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"io/ioutil"
"math/rand" "math/rand"
"net/http" "net/http"
//"net/http/httputil" //"net/http/httputil"
@@ -214,53 +213,56 @@ type WebDAVMultiStatus struct {
func (storage *WebDAVStorage) getProperties(uri string, depth int, properties ...string) (map[string]WebDAVProperties, error) { func (storage *WebDAVStorage) getProperties(uri string, depth int, properties ...string) (map[string]WebDAVProperties, error) {
propfind := "<prop>" maxTries := 3
for _, p := range properties { for tries := 0; ; tries++ {
propfind += fmt.Sprintf("<%s/>", p) propfind := "<prop>"
} for _, p := range properties {
propfind += "</prop>" propfind += fmt.Sprintf("<%s/>", p)
}
propfind += "</prop>"
body := fmt.Sprintf(`<?xml version="1.0" encoding="utf-8" ?><propfind xmlns="DAV:">%s</propfind>`, propfind) body := fmt.Sprintf(`<?xml version="1.0" encoding="utf-8" ?><propfind xmlns="DAV:">%s</propfind>`, propfind)
readCloser, _, err := storage.sendRequest("PROPFIND", uri, depth, []byte(body)) readCloser, _, err := storage.sendRequest("PROPFIND", uri, depth, []byte(body))
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer readCloser.Close() defer readCloser.Close()
content, err := ioutil.ReadAll(readCloser)
if err != nil {
return nil, err
}
object := WebDAVMultiStatus{} object := WebDAVMultiStatus{}
err = xml.Unmarshal(content, &object) err = xml.NewDecoder(readCloser).Decode(&object)
if err != nil { if err != nil {
return nil, err if strings.Contains(err.Error(), "unexpected EOF") && tries < maxTries {
} LOG_WARN("WEBDAV_RETRY", "Retrying on %v", err)
continue
if object.Responses == nil || len(object.Responses) == 0 { }
return nil, errors.New("no WebDAV responses") return nil, err
}
responses := make(map[string]WebDAVProperties)
for _, responseTag := range object.Responses {
if responseTag.PropStat == nil || responseTag.PropStat.Prop == nil || responseTag.PropStat.Prop.PropList == nil {
return nil, errors.New("no WebDAV properties")
} }
properties := make(WebDAVProperties) if object.Responses == nil || len(object.Responses) == 0 {
for _, prop := range responseTag.PropStat.Prop.PropList { return nil, errors.New("no WebDAV responses")
properties[prop.XMLName.Local] = prop.Value
} }
responseKey := responseTag.Href responses := make(map[string]WebDAVProperties)
responses[responseKey] = properties
for _, responseTag := range object.Responses {
if responseTag.PropStat == nil || responseTag.PropStat.Prop == nil || responseTag.PropStat.Prop.PropList == nil {
return nil, errors.New("no WebDAV properties")
}
properties := make(WebDAVProperties)
for _, prop := range responseTag.PropStat.Prop.PropList {
properties[prop.XMLName.Local] = prop.Value
}
responseKey := responseTag.Href
responses[responseKey] = properties
}
return responses, nil
} }
return responses, nil
} }
// ListFiles return the list of files and subdirectories under 'dir'. A subdirectories returned must have a trailing '/', with // ListFiles return the list of files and subdirectories under 'dir'. A subdirectories returned must have a trailing '/', with