forked from TrueCloudLab/rclone
Seafile: Fix download/upload error when FILE_SERVER_ROOT is relative
A seafile server can be configured to use a relative URL as FILE_SERVER_ROOT in order to support more than one hostname/ip. (see https://github.com/haiwen/seahub/issues/3398#issuecomment-506920360 ) The previous backend implementation always expected an absolute download/upload URL, resulting in an "unsupported protocol scheme" error. With this commit it supports both absolute and relative.
This commit is contained in:
parent
91b54aafcc
commit
a0dff2dd9c
1 changed files with 20 additions and 5 deletions
|
@ -577,7 +577,7 @@ func (f *Fs) getDownloadLink(ctx context.Context, libraryID, filePath string) (s
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Fs) download(ctx context.Context, url string, size int64, options ...fs.OpenOption) (io.ReadCloser, error) {
|
func (f *Fs) download(ctx context.Context, downloadLink string, size int64, options ...fs.OpenOption) (io.ReadCloser, error) {
|
||||||
// Check if we need to download partial content
|
// Check if we need to download partial content
|
||||||
var start, end int64 = 0, size
|
var start, end int64 = 0, size
|
||||||
partialContent := false
|
partialContent := false
|
||||||
|
@ -606,11 +606,18 @@ func (f *Fs) download(ctx context.Context, url string, size int64, options ...fs
|
||||||
// Build the http request
|
// Build the http request
|
||||||
opts := rest.Opts{
|
opts := rest.Opts{
|
||||||
Method: "GET",
|
Method: "GET",
|
||||||
RootURL: url,
|
|
||||||
Options: options,
|
Options: options,
|
||||||
}
|
}
|
||||||
|
parsedURL, err := url.Parse(downloadLink)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to parse download url: %w", err)
|
||||||
|
}
|
||||||
|
if parsedURL.IsAbs() {
|
||||||
|
opts.RootURL = downloadLink
|
||||||
|
} else {
|
||||||
|
opts.Path = downloadLink
|
||||||
|
}
|
||||||
var resp *http.Response
|
var resp *http.Response
|
||||||
var err error
|
|
||||||
err = f.pacer.Call(func() (bool, error) {
|
err = f.pacer.Call(func() (bool, error) {
|
||||||
resp, err = f.srv.Call(ctx, &opts)
|
resp, err = f.srv.Call(ctx, &opts)
|
||||||
return f.shouldRetry(ctx, resp, err)
|
return f.shouldRetry(ctx, resp, err)
|
||||||
|
@ -618,7 +625,7 @@ func (f *Fs) download(ctx context.Context, url string, size int64, options ...fs
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if resp != nil {
|
if resp != nil {
|
||||||
if resp.StatusCode == 404 {
|
if resp.StatusCode == 404 {
|
||||||
return nil, fmt.Errorf("file not found '%s'", url)
|
return nil, fmt.Errorf("file not found '%s'", downloadLink)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -688,11 +695,19 @@ func (f *Fs) upload(ctx context.Context, in io.Reader, uploadLink, filePath stri
|
||||||
|
|
||||||
opts := rest.Opts{
|
opts := rest.Opts{
|
||||||
Method: "POST",
|
Method: "POST",
|
||||||
RootURL: uploadLink,
|
|
||||||
Body: formReader,
|
Body: formReader,
|
||||||
ContentType: contentType,
|
ContentType: contentType,
|
||||||
Parameters: url.Values{"ret-json": {"1"}}, // It needs to be on the url, not in the body parameters
|
Parameters: url.Values{"ret-json": {"1"}}, // It needs to be on the url, not in the body parameters
|
||||||
}
|
}
|
||||||
|
parsedURL, err := url.Parse(uploadLink)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to parse upload url: %w", err)
|
||||||
|
}
|
||||||
|
if parsedURL.IsAbs() {
|
||||||
|
opts.RootURL = uploadLink
|
||||||
|
} else {
|
||||||
|
opts.Path = uploadLink
|
||||||
|
}
|
||||||
result := make([]api.FileDetail, 1)
|
result := make([]api.FileDetail, 1)
|
||||||
var resp *http.Response
|
var resp *http.Response
|
||||||
// If an error occurs during the call, do not attempt to retry: The upload link is single use only
|
// If an error occurs during the call, do not attempt to retry: The upload link is single use only
|
||||||
|
|
Loading…
Add table
Reference in a new issue