1
0
mirror of https://github.com/rclone/rclone.git synced 2026-03-02 11:21:24 +00:00

Compare commits

..

1 Commits

Author SHA1 Message Date
Nick Craig-Wood
f4d822626e serve webdav: fix incorrect Content-Type immediately after upload
Before this change, if the Content-Type for an object was read
immediately after upload (before the object had been uploaded to the
backing store) then the Content-Type would be returned incorrectly.

This error would be more likely with `--vfs-cache-mode full` and
`writes` but may have been possible with the other
`--vfs-cache-mode`s.

This fixes the problem by always returning a sensible guess at the
content type - the same guess we would use for uploading the object.

Fixes #6433
2022-09-12 12:37:47 +01:00
3 changed files with 28 additions and 39 deletions

View File

@@ -222,19 +222,19 @@ func (f *Fs) Purge(ctx context.Context, dir string) error {
//
// If it isn't possible then return fs.ErrorCantCopy
func (f *Fs) Copy(ctx context.Context, src fs.Object, remote string) (fs.Object, error) {
var srcFs fs.Info
if srcObj, ok := src.(*Object); ok {
// Have a union object - unwrap
o := srcObj.UnWrapUpstream()
srcFs = o.UpstreamFs()
src = o
} else {
// Have a non union object - it might be compatible with a union member
srcFs = src.Fs()
srcObj, ok := src.(*Object)
if !ok {
fs.Debugf(src, "Can't copy - not same remote type")
return nil, fs.ErrorCantCopy
}
o := srcObj.UnWrapUpstream()
su := o.UpstreamFs()
if su.Features().Copy == nil {
return nil, fs.ErrorCantCopy
}
var du *upstream.Fs
for _, u := range f.upstreams {
if u.Features().Copy != nil && operations.Same(u.RootFs, srcFs) {
if operations.Same(u.RootFs, su.RootFs) {
du = u
}
}
@@ -244,7 +244,7 @@ func (f *Fs) Copy(ctx context.Context, src fs.Object, remote string) (fs.Object,
if !du.IsCreatable() {
return nil, fs.ErrorPermissionDenied
}
co, err := du.Features().Copy(ctx, src, remote)
co, err := du.Features().Copy(ctx, o, remote)
if err != nil || co == nil {
return nil, err
}

View File

@@ -377,18 +377,21 @@ func (fi FileInfo) ETag(ctx context.Context) (etag string, err error) {
// ContentType returns a content type for the FileInfo
func (fi FileInfo) ContentType(ctx context.Context) (contentType string, err error) {
// defer log.Trace(fi, "")("etag=%q, err=%v", &contentType, &err)
node, ok := (fi.FileInfo).(vfs.Node)
if !ok {
fs.Errorf(fi, "Expecting vfs.Node, got %T", fi.FileInfo)
return "application/octet-stream", nil
}
entry := node.DirEntry()
switch x := entry.(type) {
case fs.Object:
return fs.MimeType(ctx, x), nil
case fs.Directory:
if fi.IsDir() {
return "inode/directory", nil
}
fs.Errorf(fi, "Expecting fs.Object or fs.Directory, got %T", entry)
return "application/octet-stream", nil
if node, ok := (fi.FileInfo).(vfs.Node); !ok {
fs.Errorf(fi, "Expecting vfs.Node, got %T", fi.FileInfo)
} else {
entry := node.DirEntry()
switch x := entry.(type) {
case nil:
// object hasn't been uploaded yet if entry is nil
case fs.Object:
return fs.MimeType(ctx, x), nil
default:
fs.Errorf(fi, "Expecting fs.Object or nil, got %T", entry)
}
}
return fs.MimeTypeFromName(fi.Name()), nil
}

View File

@@ -383,20 +383,6 @@ func CommonHash(ctx context.Context, fa, fb fs.Info) (hash.Type, *fs.HashesOptio
return hashType, &fs.HashesOption{Hashes: common}
}
// Is it OK to server side move/copy from src to dst
func serverSideOK(ci *fs.ConfigInfo, fDst, fSrc fs.Info) bool {
if ci.ServerSideAcrossConfigs {
return true
}
if SameConfig(fSrc, fDst) {
return true
}
if SameRemoteType(fSrc, fDst) {
return fDst.Features().ServerSideAcrossConfigs
}
return false
}
// Copy src object to dst or f if nil. If dst is nil then it uses
// remote as the name of the new object.
//
@@ -438,7 +424,7 @@ func Copy(ctx context.Context, f fs.Fs, dst fs.Object, remote string, src fs.Obj
return nil, accounting.ErrorMaxTransferLimitReachedGraceful
}
}
if doCopy := f.Features().Copy; doCopy != nil && serverSideOK(ci, f, src.Fs()) {
if doCopy := f.Features().Copy; doCopy != nil && (SameConfig(src.Fs(), f) || (SameRemoteType(src.Fs(), f) && (f.Features().ServerSideAcrossConfigs || ci.ServerSideAcrossConfigs))) {
in := tr.Account(ctx, nil) // account the transfer
in.ServerSideCopyStart()
newDst, err = doCopy(ctx, src, remote)
@@ -633,7 +619,7 @@ func Move(ctx context.Context, fdst fs.Fs, dst fs.Object, remote string, src fs.
return newDst, nil
}
// See if we have Move available
if doMove := fdst.Features().Move; doMove != nil && serverSideOK(ci, fdst, src.Fs()) {
if doMove := fdst.Features().Move; doMove != nil && (SameConfig(src.Fs(), fdst) || (SameRemoteType(src.Fs(), fdst) && (fdst.Features().ServerSideAcrossConfigs || ci.ServerSideAcrossConfigs))) {
// Delete destination if it exists and is not the same file as src (could be same file while seemingly different if the remote is case insensitive)
if dst != nil && !SameObject(src, dst) {
err = DeleteFile(ctx, dst)