From 6448c445f5f2b9f8ceeb809f80e0d0bb36280fb9 Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Fri, 24 Nov 2017 09:08:35 +0000 Subject: [PATCH] acd: Fix download of large files failing - Fixes #1501 Previously it was necessary to work around large files failing to download with `--acd-templink-threshold`. This change makes that flag obsolete and all files should download. Templinks may be useful under some circumstances though the flag isn't being removed. It does this by filtering `Authorization:` headers out in the transport if the authorization is supplied in the URL. This prevents the "Only one auth mechanism allowed; only the X-Amz-Algorithm query parameter, Signature query string parameter or the Authorization header should be specified" error from AWS. --- amazonclouddrive/amazonclouddrive.go | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/amazonclouddrive/amazonclouddrive.go b/amazonclouddrive/amazonclouddrive.go index d6ab93123..af1cf16bc 100644 --- a/amazonclouddrive/amazonclouddrive.go +++ b/amazonclouddrive/amazonclouddrive.go @@ -174,10 +174,34 @@ func (f *Fs) shouldRetry(resp *http.Response, err error) (bool, error) { return fs.ShouldRetry(err) || fs.ShouldRetryHTTP(resp, retryErrorCodes), err } +// If query parameters contain X-Amz-Algorithm remove Authorization header +// +// This happens when ACD redirects to S3 for the download. The oauth +// transport puts an Authorization header in which we need to remove +// otherwise we get this message from AWS +// +// Only one auth mechanism allowed; only the X-Amz-Algorithm query +// parameter, Signature query string parameter or the Authorization +// header should be specified +func filterRequest(req *http.Request) { + if req.URL.Query().Get("X-Amz-Algorithm") != "" { + fs.Debugf(nil, "Removing Authorization: header after redirect to S3") + req.Header.Del("Authorization") + } +} + // NewFs constructs an Fs from the path, container:path func NewFs(name, root string) (fs.Fs, error) { root = parsePath(root) - oAuthClient, ts, err := oauthutil.NewClient(name, acdConfig) + baseClient := fs.Config.Client() + if do, ok := baseClient.Transport.(interface { + SetRequestFilter(f func(req *http.Request)) + }); ok { + do.SetRequestFilter(filterRequest) + } else { + fs.Debugf(name+":", "Couldn't add request filter - large file downloads will fail") + } + oAuthClient, ts, err := oauthutil.NewClientWithBaseClient(name, acdConfig, baseClient) if err != nil { log.Fatalf("Failed to configure Amazon Drive: %v", err) }