From 5f0a8a4e2859e2c81e37085429b29c51cf156252 Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Wed, 23 Jan 2019 10:59:19 +0000 Subject: [PATCH] rest: fix upload of 0 length files Before this change if ContentLength was set in the options but 0 then we would upload using chunked encoding. Fix this to always upload with a "Content-Length" header even if the size is 0. Remove workarounds for this from b2 and onedrive backends. This fixes the issue for the webdav backend described here: https://forum.rclone.org/t/code-500-errors-with-webdav-nextcloud/8440/ --- backend/b2/b2.go | 5 ----- backend/onedrive/onedrive.go | 4 ---- lib/rest/rest.go | 12 +++++++++++- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/backend/b2/b2.go b/backend/b2/b2.go index f5c3f7a2c..590314250 100644 --- a/backend/b2/b2.go +++ b/backend/b2/b2.go @@ -1500,11 +1500,6 @@ func (o *Object) Update(in io.Reader, src fs.ObjectInfo, options ...fs.OpenOptio }, ContentLength: &size, } - // for go1.8 (see release notes) we must nil the Body if we want a - // "Content-Length: 0" header which b2 requires for all files. - if size == 0 { - opts.Body = nil - } var response api.FileInfo // Don't retry, return a retry error instead err = o.fs.pacer.CallNoRetry(func() (bool, error) { diff --git a/backend/onedrive/onedrive.go b/backend/onedrive/onedrive.go index 890a7d48e..6545680c2 100644 --- a/backend/onedrive/onedrive.go +++ b/backend/onedrive/onedrive.go @@ -1560,10 +1560,6 @@ func (o *Object) uploadSinglepart(in io.Reader, size int64, modTime time.Time) ( } } - if size == 0 { - opts.Body = nil - } - err = o.fs.pacer.Call(func() (bool, error) { resp, err = o.fs.srv.CallJSON(&opts, nil, &info) if apiErr, ok := err.(*api.Error); ok { diff --git a/lib/rest/rest.go b/lib/rest/rest.go index 72a740759..bca249053 100644 --- a/lib/rest/rest.go +++ b/lib/rest/rest.go @@ -198,7 +198,17 @@ func (api *Client) Call(opts *Opts) (resp *http.Response, err error) { if opts.Parameters != nil && len(opts.Parameters) > 0 { url += "?" + opts.Parameters.Encode() } - req, err := http.NewRequest(opts.Method, url, opts.Body) + body := opts.Body + // If length is set and zero then nil out the body to stop use + // use of chunked encoding and insert a "Content-Length: 0" + // header. + // + // If we don't do this we get "Content-Length" headers for all + // files except 0 length files. + if opts.ContentLength != nil && *opts.ContentLength == 0 { + body = nil + } + req, err := http.NewRequest(opts.Method, url, body) if err != nil { return }