forked from TrueCloudLab/rclone
Compare commits
4 commits
master
...
fix-5995-z
Author | SHA1 | Date | |
---|---|---|---|
|
a2f55eccbc | ||
|
3933b1e7f5 | ||
|
151224d3f8 | ||
|
1f28f4d05d |
2 changed files with 46 additions and 37 deletions
|
@ -29,6 +29,7 @@ import (
|
||||||
"github.com/rclone/rclone/fs/config/configstruct"
|
"github.com/rclone/rclone/fs/config/configstruct"
|
||||||
"github.com/rclone/rclone/fs/fspath"
|
"github.com/rclone/rclone/fs/fspath"
|
||||||
"github.com/rclone/rclone/fs/hash"
|
"github.com/rclone/rclone/fs/hash"
|
||||||
|
"github.com/rclone/rclone/fs/log"
|
||||||
"github.com/rclone/rclone/fs/object"
|
"github.com/rclone/rclone/fs/object"
|
||||||
"github.com/rclone/rclone/fs/operations"
|
"github.com/rclone/rclone/fs/operations"
|
||||||
)
|
)
|
||||||
|
@ -367,13 +368,16 @@ func (f *Fs) NewObject(ctx context.Context, remote string) (fs.Object, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
meta := readMetadata(ctx, mo)
|
meta, err := readMetadata(ctx, mo)
|
||||||
if meta == nil {
|
if err != nil {
|
||||||
return nil, errors.New("error decoding metadata")
|
return nil, fmt.Errorf("error decoding metadata: %w", err)
|
||||||
}
|
}
|
||||||
// Create our Object
|
// Create our Object
|
||||||
o, err := f.Fs.NewObject(ctx, makeDataName(remote, meta.CompressionMetadata.Size, meta.Mode))
|
o, err := f.Fs.NewObject(ctx, makeDataName(remote, meta.CompressionMetadata.Size, meta.Mode))
|
||||||
return f.newObject(o, mo, meta), err
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return f.newObject(o, mo, meta), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkCompressAndType checks if an object is compressible and determines it's mime type
|
// checkCompressAndType checks if an object is compressible and determines it's mime type
|
||||||
|
@ -677,7 +681,7 @@ func (f *Fs) putWithCustomFunctions(ctx context.Context, in io.Reader, src fs.Ob
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return f.newObject(dataObject, mo, meta), err
|
return f.newObject(dataObject, mo, meta), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put in to the remote path with the modTime given of the given size
|
// Put in to the remote path with the modTime given of the given size
|
||||||
|
@ -1040,24 +1044,19 @@ func newMetadata(size int64, mode int, cmeta sgzip.GzipMetadata, md5 string, mim
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function will read the metadata from a metadata object.
|
// This function will read the metadata from a metadata object.
|
||||||
func readMetadata(ctx context.Context, mo fs.Object) (meta *ObjectMetadata) {
|
func readMetadata(ctx context.Context, mo fs.Object) (meta *ObjectMetadata, err error) {
|
||||||
// Open our meradata object
|
// Open our meradata object
|
||||||
rc, err := mo.Open(ctx)
|
rc, err := mo.Open(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil, err
|
||||||
}
|
}
|
||||||
defer func() {
|
defer fs.CheckClose(rc, &err)
|
||||||
err := rc.Close()
|
|
||||||
if err != nil {
|
|
||||||
fs.Errorf(mo, "Error closing object: %v", err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
jr := json.NewDecoder(rc)
|
jr := json.NewDecoder(rc)
|
||||||
meta = new(ObjectMetadata)
|
meta = new(ObjectMetadata)
|
||||||
if err = jr.Decode(meta); err != nil {
|
if err = jr.Decode(meta); err != nil {
|
||||||
return nil
|
return nil, err
|
||||||
}
|
}
|
||||||
return meta
|
return meta, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove removes this object
|
// Remove removes this object
|
||||||
|
@ -1102,6 +1101,9 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op
|
||||||
origName := o.Remote()
|
origName := o.Remote()
|
||||||
if o.meta.Mode != Uncompressed || compressible {
|
if o.meta.Mode != Uncompressed || compressible {
|
||||||
newObject, err = o.f.putWithCustomFunctions(ctx, in, o.f.wrapInfo(src, origName, src.Size()), options, o.f.Fs.Put, updateMeta, compressible, mimeType)
|
newObject, err = o.f.putWithCustomFunctions(ctx, in, o.f.wrapInfo(src, origName, src.Size()), options, o.f.Fs.Put, updateMeta, compressible, mimeType)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if newObject.Object.Remote() != o.Object.Remote() {
|
if newObject.Object.Remote() != o.Object.Remote() {
|
||||||
if removeErr := o.Object.Remove(ctx); removeErr != nil {
|
if removeErr := o.Object.Remove(ctx); removeErr != nil {
|
||||||
return removeErr
|
return removeErr
|
||||||
|
@ -1115,9 +1117,9 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op
|
||||||
}
|
}
|
||||||
// If we are, just update the object and metadata
|
// If we are, just update the object and metadata
|
||||||
newObject, err = o.f.putWithCustomFunctions(ctx, in, src, options, update, updateMeta, compressible, mimeType)
|
newObject, err = o.f.putWithCustomFunctions(ctx, in, src, options, update, updateMeta, compressible, mimeType)
|
||||||
}
|
if err != nil {
|
||||||
if err != nil {
|
return err
|
||||||
return err
|
}
|
||||||
}
|
}
|
||||||
// Update object metadata and return
|
// Update object metadata and return
|
||||||
o.Object = newObject.Object
|
o.Object = newObject.Object
|
||||||
|
@ -1128,6 +1130,9 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op
|
||||||
|
|
||||||
// This will initialize the variables of a new press Object. The metadata object, mo, and metadata struct, meta, must be specified.
|
// This will initialize the variables of a new press Object. The metadata object, mo, and metadata struct, meta, must be specified.
|
||||||
func (f *Fs) newObject(o fs.Object, mo fs.Object, meta *ObjectMetadata) *Object {
|
func (f *Fs) newObject(o fs.Object, mo fs.Object, meta *ObjectMetadata) *Object {
|
||||||
|
if o == nil {
|
||||||
|
log.Trace(nil, "newObject(%#v, %#v, %#v) called with nil o", o, mo, meta)
|
||||||
|
}
|
||||||
return &Object{
|
return &Object{
|
||||||
Object: o,
|
Object: o,
|
||||||
f: f,
|
f: f,
|
||||||
|
@ -1140,6 +1145,9 @@ func (f *Fs) newObject(o fs.Object, mo fs.Object, meta *ObjectMetadata) *Object
|
||||||
|
|
||||||
// This initializes the variables of a press Object with only the size. The metadata will be loaded later on demand.
|
// This initializes the variables of a press Object with only the size. The metadata will be loaded later on demand.
|
||||||
func (f *Fs) newObjectSizeAndNameOnly(o fs.Object, moName string, size int64) *Object {
|
func (f *Fs) newObjectSizeAndNameOnly(o fs.Object, moName string, size int64) *Object {
|
||||||
|
if o == nil {
|
||||||
|
log.Trace(nil, "newObjectSizeAndNameOnly(%#v, %#v, %#v) called with nil o", o, moName, size)
|
||||||
|
}
|
||||||
return &Object{
|
return &Object{
|
||||||
Object: o,
|
Object: o,
|
||||||
f: f,
|
f: f,
|
||||||
|
@ -1167,7 +1175,7 @@ func (o *Object) loadMetadataIfNotLoaded(ctx context.Context) (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if o.meta == nil {
|
if o.meta == nil {
|
||||||
o.meta = readMetadata(ctx, o.mo)
|
o.meta, err = readMetadata(ctx, o.mo)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -670,27 +670,28 @@ func isSimpleName(s string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Fs) upload(ctx context.Context, name string, parent string, size int64, in io.Reader, options ...fs.OpenOption) (*api.Item, error) {
|
func (f *Fs) upload(ctx context.Context, name string, parent string, size int64, in io.Reader, options ...fs.OpenOption) (*api.Item, error) {
|
||||||
params := url.Values{}
|
uploadID := random.String(20) // random upload ID
|
||||||
params.Set("filename", name)
|
|
||||||
params.Set("parent_id", parent)
|
|
||||||
params.Set("override-name-exist", strconv.FormatBool(true))
|
|
||||||
formReader, contentType, overhead, err := rest.MultipartUpload(ctx, in, nil, "content", name)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to make multipart upload: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
contentLength := overhead + size
|
|
||||||
opts := rest.Opts{
|
opts := rest.Opts{
|
||||||
Method: "POST",
|
Method: "POST",
|
||||||
Path: "/upload",
|
//RootURL: "https://upload.zoho.com/workdrive-api/v1",
|
||||||
Body: formReader,
|
RootURL: "https://upload.zoho.eu/workdrive-api/v1",
|
||||||
ContentType: contentType,
|
Path: "/stream/upload",
|
||||||
ContentLength: &contentLength,
|
Body: in,
|
||||||
Options: options,
|
ContentType: fs.MimeTypeFromName(name), // FIXME should read mime type of original object
|
||||||
Parameters: params,
|
ContentLength: &size,
|
||||||
TransferEncoding: []string{"identity"},
|
Options: options,
|
||||||
|
ExtraHeaders: map[string]string{
|
||||||
|
"x-filename": name,
|
||||||
|
"x-parent_id": parent,
|
||||||
|
"upload-id": uploadID,
|
||||||
|
"x-streammode": "1",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if size < 0 {
|
||||||
|
opts.ContentLength = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
var resp *http.Response
|
var resp *http.Response
|
||||||
var uploadResponse *api.UploadResponse
|
var uploadResponse *api.UploadResponse
|
||||||
err = f.pacer.CallNoRetry(func() (bool, error) {
|
err = f.pacer.CallNoRetry(func() (bool, error) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue