forked from TrueCloudLab/rclone
webdav: support put.io #580
* Add docs on how to set up * Fix the listing routine * Use Depth: 1 in otherwise we get a recursive listing * Detect collections properly rather than relying on them ending in / * Add / to collection URLs which don't have one
This commit is contained in:
parent
683befaec1
commit
6df1f6fad1
4 changed files with 52 additions and 8 deletions
|
@ -35,6 +35,7 @@ Rclone is a command line program to sync files and directories to and from:
|
||||||
* {{< provider name="Oracle Cloud Storage" home="https://cloud.oracle.com/storage-opc" config="/swift/" >}}
|
* {{< provider name="Oracle Cloud Storage" home="https://cloud.oracle.com/storage-opc" config="/swift/" >}}
|
||||||
* {{< provider name="Ownloud" home="https://owncloud.org/" config="/webdav/#owncloud" >}}
|
* {{< provider name="Ownloud" home="https://owncloud.org/" config="/webdav/#owncloud" >}}
|
||||||
* {{< provider name="pCloud" home="https://www.pcloud.com/" config="/pcloud/" >}}
|
* {{< provider name="pCloud" home="https://www.pcloud.com/" config="/pcloud/" >}}
|
||||||
|
* {{< provider name="put.io" home="https://put.io/" config="/webdav/#put-io" >}}
|
||||||
* {{< provider name="QingStor" home="https://www.qingcloud.com/products/storage" config="/qingstor/" >}}
|
* {{< provider name="QingStor" home="https://www.qingcloud.com/products/storage" config="/qingstor/" >}}
|
||||||
* {{< provider name="Rackspace Cloud Files" home="https://www.rackspace.com/cloud/files" config="/swift/" >}}
|
* {{< provider name="Rackspace Cloud Files" home="https://www.rackspace.com/cloud/files" config="/swift/" >}}
|
||||||
* {{< provider name="SFTP" home="https://en.wikipedia.org/wiki/SFTP" config="/sftp/" >}}
|
* {{< provider name="SFTP" home="https://en.wikipedia.org/wiki/SFTP" config="/sftp/" >}}
|
||||||
|
|
|
@ -146,3 +146,28 @@ Nextcloud does not support streaming of files (`rcat`) whereas
|
||||||
Owncloud does. This [may be
|
Owncloud does. This [may be
|
||||||
fixed](https://github.com/nextcloud/nextcloud-snap/issues/365) in the
|
fixed](https://github.com/nextcloud/nextcloud-snap/issues/365) in the
|
||||||
future.
|
future.
|
||||||
|
|
||||||
|
## Put.io ##
|
||||||
|
|
||||||
|
put.io can be accessed in a read only way using webdav.
|
||||||
|
|
||||||
|
Configure the `url` as `https://webdav.put.io` and use your normal
|
||||||
|
account username and password for `user` and `pass`. Set the `vendor`
|
||||||
|
to `other`.
|
||||||
|
|
||||||
|
Your config file should end up looking like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
[putio]
|
||||||
|
type = webdav
|
||||||
|
url = https://webdav.put.io
|
||||||
|
vendor = other
|
||||||
|
user = YourUserName
|
||||||
|
pass = encryptedpassword
|
||||||
|
```
|
||||||
|
|
||||||
|
If you are using `put.io` with `rclone mount` then use the
|
||||||
|
`--read-only` flag to signal to the OS that it can't write to the
|
||||||
|
mount.
|
||||||
|
|
||||||
|
For more help see [the put.io webdav docs](http://help.put.io/apps-and-integrations/ftp-and-webdav).
|
||||||
|
|
|
@ -26,11 +26,11 @@ type Response struct {
|
||||||
|
|
||||||
// Prop is the properties of a response
|
// Prop is the properties of a response
|
||||||
type Prop struct {
|
type Prop struct {
|
||||||
Status string `xml:"DAV: status"`
|
Status string `xml:"DAV: status"`
|
||||||
Name string `xml:"DAV: prop>displayname,omitempty"`
|
Name string `xml:"DAV: prop>displayname,omitempty"`
|
||||||
Type xml.Name `xml:"DAV: prop>resourcetype>collection,omitempty"`
|
Type *xml.Name `xml:"DAV: prop>resourcetype>collection,omitempty"`
|
||||||
Size int64 `xml:"DAV: prop>getcontentlength,omitempty"`
|
Size int64 `xml:"DAV: prop>getcontentlength,omitempty"`
|
||||||
Modified Time `xml:"DAV: prop>getlastmodified,omitempty"`
|
Modified Time `xml:"DAV: prop>getlastmodified,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse a status of the form "HTTP/1.1 200 OK",
|
// Parse a status of the form "HTTP/1.1 200 OK",
|
||||||
|
|
|
@ -360,6 +360,9 @@ func (f *Fs) listAll(dir string, directoriesOnly bool, filesOnly bool, fn listAl
|
||||||
opts := rest.Opts{
|
opts := rest.Opts{
|
||||||
Method: "PROPFIND",
|
Method: "PROPFIND",
|
||||||
Path: f.dirPath(dir), // FIXME Should not start with /
|
Path: f.dirPath(dir), // FIXME Should not start with /
|
||||||
|
ExtraHeaders: map[string]string{
|
||||||
|
"Depth": "1",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
var result api.Multistatus
|
var result api.Multistatus
|
||||||
var resp *http.Response
|
var resp *http.Response
|
||||||
|
@ -384,8 +387,19 @@ func (f *Fs) listAll(dir string, directoriesOnly bool, filesOnly bool, fn listAl
|
||||||
for i := range result.Responses {
|
for i := range result.Responses {
|
||||||
item := &result.Responses[i]
|
item := &result.Responses[i]
|
||||||
|
|
||||||
// Collections must end in /
|
// Figure out what this is
|
||||||
isDir := strings.HasSuffix(item.Href, "/")
|
isDir := false
|
||||||
|
if t := item.Props.Type; t != nil {
|
||||||
|
// When a client sees a resourcetype it
|
||||||
|
// doesn't recognize it should assume it is a
|
||||||
|
// regular non-collection resource. [WebDav
|
||||||
|
// book by Lisa Dusseault ch 7.5.8 p170]
|
||||||
|
if t.Space == "DAV:" && t.Local == "collection" {
|
||||||
|
isDir = true
|
||||||
|
} else {
|
||||||
|
fs.Debugf(nil, "Unknown resource type %q/%q on %q", t.Space, t.Local, item.Props.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Find name
|
// Find name
|
||||||
u, err := rest.URLJoin(baseURL, item.Href)
|
u, err := rest.URLJoin(baseURL, item.Href)
|
||||||
|
@ -393,8 +407,12 @@ func (f *Fs) listAll(dir string, directoriesOnly bool, filesOnly bool, fn listAl
|
||||||
fs.Errorf(nil, "URL Join failed for %q and %q: %v", baseURL, item.Href, err)
|
fs.Errorf(nil, "URL Join failed for %q and %q: %v", baseURL, item.Href, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
// Make sure directories end with a /
|
||||||
|
if isDir {
|
||||||
|
u.Path = addSlash(u.Path)
|
||||||
|
}
|
||||||
if !strings.HasPrefix(u.Path, baseURL.Path) {
|
if !strings.HasPrefix(u.Path, baseURL.Path) {
|
||||||
fs.Debugf(nil, "Item with unknown path received: %q, %q", item.Href, u.Path)
|
fs.Debugf(nil, "Item with unknown path received: %q, %q", u.Path, baseURL.Path)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
remote := path.Join(dir, u.Path[len(baseURL.Path):])
|
remote := path.Join(dir, u.Path[len(baseURL.Path):])
|
||||||
|
|
Loading…
Reference in a new issue