webdav: set modtime using propset for owncloud and nextcloud
This commit is contained in:
parent
f5bab284c3
commit
ae6874170f
1 changed files with 48 additions and 0 deletions
|
@ -175,6 +175,7 @@ type Fs struct {
|
||||||
precision time.Duration // mod time precision
|
precision time.Duration // mod time precision
|
||||||
canStream bool // set if can stream
|
canStream bool // set if can stream
|
||||||
useOCMtime bool // set if can use X-OC-Mtime
|
useOCMtime bool // set if can use X-OC-Mtime
|
||||||
|
propsetMtime bool // set if can use propset
|
||||||
retryWithZeroDepth bool // some vendors (sharepoint) won't list files when Depth is 1 (our default)
|
retryWithZeroDepth bool // some vendors (sharepoint) won't list files when Depth is 1 (our default)
|
||||||
checkBeforePurge bool // enables extra check that directory to purge really exists
|
checkBeforePurge bool // enables extra check that directory to purge really exists
|
||||||
hasOCMD5 bool // set if can use owncloud style checksums for MD5
|
hasOCMD5 bool // set if can use owncloud style checksums for MD5
|
||||||
|
@ -582,11 +583,13 @@ func (f *Fs) setQuirks(ctx context.Context, vendor string) error {
|
||||||
f.canStream = true
|
f.canStream = true
|
||||||
f.precision = time.Second
|
f.precision = time.Second
|
||||||
f.useOCMtime = true
|
f.useOCMtime = true
|
||||||
|
f.propsetMtime = true
|
||||||
f.hasOCMD5 = true
|
f.hasOCMD5 = true
|
||||||
f.hasOCSHA1 = true
|
f.hasOCSHA1 = true
|
||||||
case "nextcloud":
|
case "nextcloud":
|
||||||
f.precision = time.Second
|
f.precision = time.Second
|
||||||
f.useOCMtime = true
|
f.useOCMtime = true
|
||||||
|
f.propsetMtime = true
|
||||||
f.hasOCSHA1 = true
|
f.hasOCSHA1 = true
|
||||||
f.canChunk = true
|
f.canChunk = true
|
||||||
if err := f.verifyChunkConfig(); err != nil {
|
if err := f.verifyChunkConfig(); err != nil {
|
||||||
|
@ -1299,8 +1302,53 @@ func (o *Object) ModTime(ctx context.Context) time.Time {
|
||||||
return o.modTime
|
return o.modTime
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set modified time using propset
|
||||||
|
//
|
||||||
|
// <d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns"><d:response><d:href>/ocm/remote.php/webdav/office/wir.jpg</d:href><d:propstat><d:prop><d:lastmodified/></d:prop><d:status>HTTP/1.1 200 OK</d:status></d:propstat></d:response></d:multistatus>
|
||||||
|
var owncloudPropset = `<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<D:propertyupdate xmlns:D="DAV:">
|
||||||
|
<D:set>
|
||||||
|
<D:prop>
|
||||||
|
<lastmodified xmlns="DAV:">%d</lastmodified>
|
||||||
|
</D:prop>
|
||||||
|
</D:set>
|
||||||
|
</D:propertyupdate>
|
||||||
|
`
|
||||||
|
|
||||||
// SetModTime sets the modification time of the local fs object
|
// SetModTime sets the modification time of the local fs object
|
||||||
func (o *Object) SetModTime(ctx context.Context, modTime time.Time) error {
|
func (o *Object) SetModTime(ctx context.Context, modTime time.Time) error {
|
||||||
|
if o.fs.propsetMtime {
|
||||||
|
opts := rest.Opts{
|
||||||
|
Method: "PROPPATCH",
|
||||||
|
Path: o.filePath(),
|
||||||
|
NoRedirect: true,
|
||||||
|
Body: strings.NewReader(fmt.Sprintf(owncloudPropset, modTime.Unix())),
|
||||||
|
}
|
||||||
|
var result api.Multistatus
|
||||||
|
var resp *http.Response
|
||||||
|
var err error
|
||||||
|
err = o.fs.pacer.Call(func() (bool, error) {
|
||||||
|
resp, err = o.fs.srv.CallXML(ctx, &opts, nil, &result)
|
||||||
|
return o.fs.shouldRetry(ctx, resp, err)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
if apiErr, ok := err.(*api.Error); ok {
|
||||||
|
// does not exist
|
||||||
|
if apiErr.StatusCode == http.StatusNotFound {
|
||||||
|
return fs.ErrorObjectNotFound
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fmt.Errorf("couldn't set modified time: %w", err)
|
||||||
|
}
|
||||||
|
// FIXME check if response is valid
|
||||||
|
if len(result.Responses) == 1 && result.Responses[0].Props.StatusOK() {
|
||||||
|
// update cached modtime
|
||||||
|
o.modTime = modTime
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// fallback
|
||||||
|
return fs.ErrorCantSetModTime
|
||||||
|
}
|
||||||
return fs.ErrorCantSetModTime
|
return fs.ErrorCantSetModTime
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue