@@ -5,18 +5,22 @@ import (
55 "crypto/tls"
66 "errors"
77 "fmt"
8+ "strings"
89
910 "github.com/fleetdm/fleet/v4/pkg/fleethttp"
1011 "github.com/fleetdm/fleet/v4/server/aws_common"
1112 "github.com/fleetdm/fleet/v4/server/config"
1213 "github.com/fleetdm/fleet/v4/server/fleet"
1314
1415 "github.com/aws/aws-sdk-go-v2/aws"
16+ v4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4"
1517 aws_config "github.com/aws/aws-sdk-go-v2/config"
1618 "github.com/aws/aws-sdk-go-v2/credentials"
1719 "github.com/aws/aws-sdk-go-v2/feature/s3/manager"
1820 "github.com/aws/aws-sdk-go-v2/service/s3"
1921 types "github.com/aws/aws-sdk-go-v2/service/s3/types"
22+ "github.com/aws/smithy-go/middleware"
23+ smithyhttp "github.com/aws/smithy-go/transport/http"
2024)
2125
2226const awsRegionHint = "us-east-1"
@@ -105,6 +109,14 @@ func newS3Store(cfg config.S3ConfigInternal) (*s3store, error) {
105109
106110 s3Client := s3 .NewFromConfig (conf , func (o * s3.Options ) {
107111 o .UsePathStyle = cfg .ForceS3PathStyle
112+
113+ // Apply workaround if using Google Cloud Storage (GCS) endpoint
114+ // This fixes signature issues with AWS SDK v2 when using GCS
115+ // See: https://github.com/aws/aws-sdk-go-v2/issues/1816#issuecomment-1927281540
116+ if cfg .EndpointURL != "" && strings .Contains (cfg .EndpointURL , "storage.googleapis.com" ) {
117+ // GCS alters the Accept-Encoding header which breaks the request signature
118+ ignoreSigningHeaders (o , []string {"Accept-Encoding" })
119+ }
108120 })
109121
110122 return & s3store {
@@ -133,3 +145,65 @@ func (s *s3store) CreateTestBucket(ctx context.Context, name string) error {
133145 }
134146 return err
135147}
148+
149+ // GCS workaround middleware functions to fix signature issues
150+ // See: https://github.com/aws/aws-sdk-go-v2/issues/1816#issuecomment-1927281540
151+
152+ type ignoredHeadersKey struct {}
153+
154+ // ignoreSigningHeaders excludes the listed headers from the request signature
155+ // because some providers (like GCS) may alter them, causing signature mismatches.
156+ func ignoreSigningHeaders (o * s3.Options , headers []string ) {
157+ o .APIOptions = append (o .APIOptions , func (stack * middleware.Stack ) error {
158+ if err := stack .Finalize .Insert (ignoreHeaders (headers ), "Signing" , middleware .Before ); err != nil {
159+ return err
160+ }
161+
162+ if err := stack .Finalize .Insert (restoreIgnored (), "Signing" , middleware .After ); err != nil {
163+ return err
164+ }
165+
166+ return nil
167+ })
168+ }
169+
170+ func ignoreHeaders (headers []string ) middleware.FinalizeMiddleware {
171+ return middleware .FinalizeMiddlewareFunc (
172+ "IgnoreHeaders" ,
173+ func (ctx context.Context , in middleware.FinalizeInput , next middleware.FinalizeHandler ) (out middleware.FinalizeOutput , metadata middleware.Metadata , err error ) {
174+ req , ok := in .Request .(* smithyhttp.Request )
175+ if ! ok {
176+ return out , metadata , & v4.SigningError {Err : fmt .Errorf ("(ignoreHeaders) unexpected request middleware type %T" , in .Request )}
177+ }
178+
179+ ignored := make (map [string ]string , len (headers ))
180+ for _ , h := range headers {
181+ ignored [h ] = req .Header .Get (h )
182+ req .Header .Del (h )
183+ }
184+
185+ ctx = middleware .WithStackValue (ctx , ignoredHeadersKey {}, ignored )
186+
187+ return next .HandleFinalize (ctx , in )
188+ },
189+ )
190+ }
191+
192+ func restoreIgnored () middleware.FinalizeMiddleware {
193+ return middleware .FinalizeMiddlewareFunc (
194+ "RestoreIgnored" ,
195+ func (ctx context.Context , in middleware.FinalizeInput , next middleware.FinalizeHandler ) (out middleware.FinalizeOutput , metadata middleware.Metadata , err error ) {
196+ req , ok := in .Request .(* smithyhttp.Request )
197+ if ! ok {
198+ return out , metadata , & v4.SigningError {Err : fmt .Errorf ("(restoreIgnored) unexpected request middleware type %T" , in .Request )}
199+ }
200+
201+ ignored , _ := middleware .GetStackValue (ctx , ignoredHeadersKey {}).(map [string ]string )
202+ for k , v := range ignored {
203+ req .Header .Set (k , v )
204+ }
205+
206+ return next .HandleFinalize (ctx , in )
207+ },
208+ )
209+ }
0 commit comments