@@ -2680,6 +2680,34 @@ knows about - please make a bug report if not.
26802680You can change this if you want to disable the use of multipart uploads.
26812681This shouldn't be necessary in normal operation.
26822682
2683+ This should be automatically set correctly for all providers rclone
2684+ knows about - please make a bug report if not.
2685+ ` ,
2686+ Default : fs.Tristate {},
2687+ Advanced : true ,
2688+ }, {
2689+ Name : "use_x_id" ,
2690+ Help : `Set if rclone should add x-id URL parameters.
2691+
2692+ You can change this if you want to disable the AWS SDK from
2693+ adding x-id URL parameters.
2694+
2695+ This shouldn't be necessary in normal operation.
2696+
2697+ This should be automatically set correctly for all providers rclone
2698+ knows about - please make a bug report if not.
2699+ ` ,
2700+ Default : fs.Tristate {},
2701+ Advanced : true ,
2702+ }, {
2703+ Name : "sign_accept_encoding" ,
2704+ Help : `Set if rclone should include Accept-Encoding as part of the signature.
2705+
2706+ You can change this if you want to stop rclone including
2707+ Accept-Encoding as part of the signature.
2708+
2709+ This shouldn't be necessary in normal operation.
2710+
26832711This should be automatically set correctly for all providers rclone
26842712knows about - please make a bug report if not.
26852713` ,
@@ -2901,6 +2929,8 @@ type Options struct {
29012929 DirectoryBucket bool `config:"directory_bucket"`
29022930 IBMAPIKey string `config:"ibm_api_key"`
29032931 IBMInstanceID string `config:"ibm_resource_instance_id"`
2932+ UseXID fs.Tristate `config:"use_x_id"`
2933+ SignAcceptEncoding fs.Tristate `config:"sign_accept_encoding"`
29042934}
29052935
29062936// Fs represents a remote s3 server
@@ -3085,59 +3115,67 @@ func getClient(ctx context.Context, opt *Options) *http.Client {
30853115 }
30863116}
30873117
3118+ // Fixup the request if needed.
3119+ //
30883120// Google Cloud Storage alters the Accept-Encoding header, which
3089- // breaks the v2 request signature
3121+ // breaks the v2 request signature. This is set with opt.SignAcceptEncoding.
30903122//
30913123// It also doesn't like the x-id URL parameter SDKv2 puts in so we
3092- // remove that too.
3124+ // remove that too. This is set with opt.UseXID.Value.
30933125//
30943126// See https://github.com/aws/aws-sdk-go-v2/issues/1816.
30953127// Adapted from: https://github.com/aws/aws-sdk-go-v2/issues/1816#issuecomment-1927281540
3096- func fixupGCS (o * s3.Options ) {
3128+ func fixupRequest (o * s3.Options , opt * Options ) {
30973129 type ignoredHeadersKey struct {}
30983130 headers := []string {"Accept-Encoding" }
30993131
31003132 fixup := middleware .FinalizeMiddlewareFunc (
3101- "FixupGCS " ,
3133+ "FixupRequest " ,
31023134 func (ctx context.Context , in middleware.FinalizeInput , next middleware.FinalizeHandler ) (out middleware.FinalizeOutput , metadata middleware.Metadata , err error ) {
31033135 req , ok := in .Request .(* smithyhttp.Request )
31043136 if ! ok {
3105- return out , metadata , fmt .Errorf ("fixupGCS : unexpected request middleware type %T" , in .Request )
3137+ return out , metadata , fmt .Errorf ("fixupRequest : unexpected request middleware type %T" , in .Request )
31063138 }
31073139
3108- // Delete headers from being signed - will restore later
3109- ignored := make (map [string ]string , len (headers ))
3110- for _ , h := range headers {
3111- ignored [h ] = req .Header .Get (h )
3112- req .Header .Del (h )
3113- }
3140+ if ! opt .SignAcceptEncoding .Value {
3141+ // Delete headers from being signed - will restore later
3142+ ignored := make (map [string ]string , len (headers ))
3143+ for _ , h := range headers {
3144+ ignored [h ] = req .Header .Get (h )
3145+ req .Header .Del (h )
3146+ }
31143147
3115- // Remove x-id because Google doesn't like them
3116- if query := req .URL .Query (); query .Has ("x-id" ) {
3117- query .Del ("x-id" )
3118- req .URL .RawQuery = query .Encode ()
3148+ // Store ignored on context
3149+ ctx = middleware .WithStackValue (ctx , ignoredHeadersKey {}, ignored )
31193150 }
31203151
3121- // Store ignored on context
3122- ctx = middleware .WithStackValue (ctx , ignoredHeadersKey {}, ignored )
3152+ if ! opt .UseXID .Value {
3153+ // Remove x-id
3154+ if query := req .URL .Query (); query .Has ("x-id" ) {
3155+ query .Del ("x-id" )
3156+ req .URL .RawQuery = query .Encode ()
3157+ }
3158+ }
31233159
31243160 return next .HandleFinalize (ctx , in )
31253161 },
31263162 )
31273163
31283164 // Restore headers if necessary
31293165 restore := middleware .FinalizeMiddlewareFunc (
3130- "FixupGCSRestoreHeaders " ,
3166+ "FixupRequestRestoreHeaders " ,
31313167 func (ctx context.Context , in middleware.FinalizeInput , next middleware.FinalizeHandler ) (out middleware.FinalizeOutput , metadata middleware.Metadata , err error ) {
31323168 req , ok := in .Request .(* smithyhttp.Request )
31333169 if ! ok {
3134- return out , metadata , fmt .Errorf ("fixupGCS : unexpected request middleware type %T" , in .Request )
3170+ return out , metadata , fmt .Errorf ("fixupRequest : unexpected request middleware type %T" , in .Request )
31353171 }
31363172
3137- // Restore ignored from ctx
3138- ignored , _ := middleware .GetStackValue (ctx , ignoredHeadersKey {}).(map [string ]string )
3139- for k , v := range ignored {
3140- req .Header .Set (k , v )
3173+ if ! opt .SignAcceptEncoding .Value {
3174+ // Restore ignored from ctx
3175+ ignored , _ := middleware .GetStackValue (ctx , ignoredHeadersKey {}).(map [string ]string )
3176+ for k , v := range ignored {
3177+ req .Header .Set (k , v )
3178+ }
31413179 }
31423180
31433181 return next .HandleFinalize (ctx , in )
@@ -3267,9 +3305,10 @@ func s3Connection(ctx context.Context, opt *Options, client *http.Client) (s3Cli
32673305 }
32683306 }
32693307
3270- if opt .Provider == "GCS" {
3308+ // Fixup the request if needed
3309+ if ! opt .UseXID .Value || ! opt .SignAcceptEncoding .Value {
32713310 options = append (options , func (o * s3.Options ) {
3272- fixupGCS ( o )
3311+ fixupRequest ( o , opt )
32733312 })
32743313 }
32753314
@@ -3384,6 +3423,8 @@ func setQuirks(opt *Options) {
33843423 useAlreadyExists = true // Set if provider returns AlreadyOwnedByYou or no error if you try to remake your own bucket
33853424 useMultipartUploads = true // Set if provider supports multipart uploads
33863425 useUnsignedPayload = true // Do we need to use unsigned payloads to avoid seeking in PutObject
3426+ useXID = true // Add x-id URL parameter into requests
3427+ signAcceptEncoding = true // If we should include AcceptEncoding in the signature
33873428 )
33883429 switch opt .Provider {
33893430 case "AWS" :
@@ -3528,11 +3569,14 @@ func setQuirks(opt *Options) {
35283569 // Google break request Signature by mutating accept-encoding HTTP header
35293570 // https://github.com/rclone/rclone/issues/6670
35303571 useAcceptEncodingGzip = false
3572+ signAcceptEncoding = false
35313573 useAlreadyExists = true // returns BucketNameUnavailable instead of BucketAlreadyExists but good enough!
35323574 // GCS S3 doesn't support multi-part server side copy:
35333575 // See: https://issuetracker.google.com/issues/323465186
35343576 // So make cutoff very large which it does seem to support
35353577 opt .CopyCutoff = math .MaxInt64
3578+ // GCS doesn't like the x-id URL parameter the SDKv2 inserts
3579+ useXID = false
35363580 default : //nolint:gocritic // Don't include gocritic when running golangci-lint to avoid defaultCaseOrder: consider to make `default` case as first or as last case
35373581 fs .Logf ("s3" , "s3 provider %q not known - please set correctly" , opt .Provider )
35383582 fallthrough
@@ -3602,6 +3646,18 @@ func setQuirks(opt *Options) {
36023646 opt .UseUnsignedPayload .Valid = true
36033647 opt .UseUnsignedPayload .Value = useUnsignedPayload
36043648 }
3649+
3650+ // Set the correct use UseXID if not manually set
3651+ if ! opt .UseXID .Valid {
3652+ opt .UseXID .Valid = true
3653+ opt .UseXID .Value = useXID
3654+ }
3655+
3656+ // Set the correct SignAcceptEncoding if not manually set
3657+ if ! opt .SignAcceptEncoding .Valid {
3658+ opt .SignAcceptEncoding .Valid = true
3659+ opt .SignAcceptEncoding .Value = signAcceptEncoding
3660+ }
36053661}
36063662
36073663// setRoot changes the root of the Fs
0 commit comments