mailru: fix range requests after june changes on server

This commit is contained in:
Ivan Andreev 2020-09-17 22:02:59 +03:00
parent 0e8965060f
commit 8928441466
1 changed files with 35 additions and 8 deletions

View File

@ -37,6 +37,7 @@ import (
"github.com/rclone/rclone/lib/encoder" "github.com/rclone/rclone/lib/encoder"
"github.com/rclone/rclone/lib/oauthutil" "github.com/rclone/rclone/lib/oauthutil"
"github.com/rclone/rclone/lib/pacer" "github.com/rclone/rclone/lib/pacer"
"github.com/rclone/rclone/lib/readers"
"github.com/rclone/rclone/lib/rest" "github.com/rclone/rclone/lib/rest"
"github.com/pkg/errors" "github.com/pkg/errors"
@ -2116,7 +2117,18 @@ func (o *Object) Open(ctx context.Context, options ...fs.OpenOption) (in io.Read
return nil, err return nil, err
} }
start, end, partial := getTransferRange(o.size, options...) start, end, partialRequest := getTransferRange(o.size, options...)
headers := map[string]string{
"Accept": "*/*",
"Content-Type": "application/octet-stream",
}
if partialRequest {
rangeStr := fmt.Sprintf("bytes=%d-%d", start, end-1)
headers["Range"] = rangeStr
// headers["Content-Range"] = rangeStr
headers["Accept-Ranges"] = "bytes"
}
// TODO: set custom timeouts // TODO: set custom timeouts
opts := rest.Opts{ opts := rest.Opts{
@ -2127,10 +2139,7 @@ func (o *Object) Open(ctx context.Context, options ...fs.OpenOption) (in io.Read
"client_id": {api.OAuthClientID}, "client_id": {api.OAuthClientID},
"token": {token}, "token": {token},
}, },
ExtraHeaders: map[string]string{ ExtraHeaders: headers,
"Accept": "*/*",
"Range": fmt.Sprintf("bytes=%d-%d", start, end-1),
},
} }
var res *http.Response var res *http.Response
@ -2151,18 +2160,36 @@ func (o *Object) Open(ctx context.Context, options ...fs.OpenOption) (in io.Read
return nil, err return nil, err
} }
var hasher gohash.Hash // Server should respond with Status 206 and Content-Range header to a range
if !partial { // request. Status 200 (and no Content-Range) means a full-content response.
partialResponse := res.StatusCode == 206
var (
hasher gohash.Hash
wrapStream io.ReadCloser
)
if !partialResponse {
// Cannot check hash of partial download // Cannot check hash of partial download
hasher = mrhash.New() hasher = mrhash.New()
} }
wrapStream := &endHandler{ wrapStream = &endHandler{
ctx: ctx, ctx: ctx,
stream: res.Body, stream: res.Body,
hasher: hasher, hasher: hasher,
o: o, o: o,
server: server, server: server,
} }
if partialRequest && !partialResponse {
fs.Debugf(o, "Server returned full content instead of range")
if start > 0 {
// Discard the beginning of the data
_, err = io.CopyN(ioutil.Discard, wrapStream, start)
if err != nil {
return nil, err
}
}
wrapStream = readers.NewLimitedReadCloser(wrapStream, end-start)
}
return wrapStream, nil return wrapStream, nil
} }