api_client.go (35433B)
1 // Code generated by smithy-go-codegen DO NOT EDIT. 2 3 package sts 4 5 import ( 6 "context" 7 "errors" 8 "fmt" 9 "net" 10 "net/http" 11 "sync/atomic" 12 "time" 13 14 "github.com/aws/aws-sdk-go-v2/aws" 15 "github.com/aws/aws-sdk-go-v2/aws/defaults" 16 awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" 17 "github.com/aws/aws-sdk-go-v2/aws/protocol/query" 18 "github.com/aws/aws-sdk-go-v2/aws/retry" 19 v4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4" 20 awshttp "github.com/aws/aws-sdk-go-v2/aws/transport/http" 21 internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" 22 internalauthsmithy "github.com/aws/aws-sdk-go-v2/internal/auth/smithy" 23 internalConfig "github.com/aws/aws-sdk-go-v2/internal/configsources" 24 "github.com/aws/aws-sdk-go-v2/internal/v4a" 25 acceptencodingcust "github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding" 26 presignedurlcust "github.com/aws/aws-sdk-go-v2/service/internal/presigned-url" 27 smithy "github.com/aws/smithy-go" 28 smithydocument "github.com/aws/smithy-go/document" 29 "github.com/aws/smithy-go/logging" 30 "github.com/aws/smithy-go/metrics" 31 "github.com/aws/smithy-go/middleware" 32 "github.com/aws/smithy-go/tracing" 33 smithyhttp "github.com/aws/smithy-go/transport/http" 34 ) 35 36 const ServiceID = "STS" 37 const ServiceAPIVersion = "2011-06-15" 38 39 type operationMetrics struct { 40 Duration metrics.Float64Histogram 41 SerializeDuration metrics.Float64Histogram 42 ResolveIdentityDuration metrics.Float64Histogram 43 ResolveEndpointDuration metrics.Float64Histogram 44 SignRequestDuration metrics.Float64Histogram 45 DeserializeDuration metrics.Float64Histogram 46 } 47 48 func (m *operationMetrics) histogramFor(name string) metrics.Float64Histogram { 49 switch name { 50 case "client.call.duration": 51 return m.Duration 52 case "client.call.serialization_duration": 53 return m.SerializeDuration 54 case "client.call.resolve_identity_duration": 55 return m.ResolveIdentityDuration 56 case "client.call.resolve_endpoint_duration": 57 return m.ResolveEndpointDuration 58 case "client.call.signing_duration": 59 return m.SignRequestDuration 60 case "client.call.deserialization_duration": 61 return m.DeserializeDuration 62 default: 63 panic("unrecognized operation metric") 64 } 65 } 66 67 func timeOperationMetric[T any]( 68 ctx context.Context, metric string, fn func() (T, error), 69 opts ...metrics.RecordMetricOption, 70 ) (T, error) { 71 mm := getOperationMetrics(ctx) 72 if mm == nil { // not using the metrics system 73 return fn() 74 } 75 76 instr := mm.histogramFor(metric) 77 opts = append([]metrics.RecordMetricOption{withOperationMetadata(ctx)}, opts...) 78 79 start := time.Now() 80 v, err := fn() 81 end := time.Now() 82 83 elapsed := end.Sub(start) 84 instr.Record(ctx, float64(elapsed)/1e9, opts...) 85 return v, err 86 } 87 88 func startMetricTimer(ctx context.Context, metric string, opts ...metrics.RecordMetricOption) func() { 89 mm := getOperationMetrics(ctx) 90 if mm == nil { // not using the metrics system 91 return func() {} 92 } 93 94 instr := mm.histogramFor(metric) 95 opts = append([]metrics.RecordMetricOption{withOperationMetadata(ctx)}, opts...) 96 97 var ended bool 98 start := time.Now() 99 return func() { 100 if ended { 101 return 102 } 103 ended = true 104 105 end := time.Now() 106 107 elapsed := end.Sub(start) 108 instr.Record(ctx, float64(elapsed)/1e9, opts...) 109 } 110 } 111 112 func withOperationMetadata(ctx context.Context) metrics.RecordMetricOption { 113 return func(o *metrics.RecordMetricOptions) { 114 o.Properties.Set("rpc.service", middleware.GetServiceID(ctx)) 115 o.Properties.Set("rpc.method", middleware.GetOperationName(ctx)) 116 } 117 } 118 119 type operationMetricsKey struct{} 120 121 func withOperationMetrics(parent context.Context, mp metrics.MeterProvider) (context.Context, error) { 122 if _, ok := mp.(metrics.NopMeterProvider); ok { 123 // not using the metrics system - setting up the metrics context is a memory-intensive operation 124 // so we should skip it in this case 125 return parent, nil 126 } 127 128 meter := mp.Meter("github.com/aws/aws-sdk-go-v2/service/sts") 129 om := &operationMetrics{} 130 131 var err error 132 133 om.Duration, err = operationMetricTimer(meter, "client.call.duration", 134 "Overall call duration (including retries and time to send or receive request and response body)") 135 if err != nil { 136 return nil, err 137 } 138 om.SerializeDuration, err = operationMetricTimer(meter, "client.call.serialization_duration", 139 "The time it takes to serialize a message body") 140 if err != nil { 141 return nil, err 142 } 143 om.ResolveIdentityDuration, err = operationMetricTimer(meter, "client.call.auth.resolve_identity_duration", 144 "The time taken to acquire an identity (AWS credentials, bearer token, etc) from an Identity Provider") 145 if err != nil { 146 return nil, err 147 } 148 om.ResolveEndpointDuration, err = operationMetricTimer(meter, "client.call.resolve_endpoint_duration", 149 "The time it takes to resolve an endpoint (endpoint resolver, not DNS) for the request") 150 if err != nil { 151 return nil, err 152 } 153 om.SignRequestDuration, err = operationMetricTimer(meter, "client.call.auth.signing_duration", 154 "The time it takes to sign a request") 155 if err != nil { 156 return nil, err 157 } 158 om.DeserializeDuration, err = operationMetricTimer(meter, "client.call.deserialization_duration", 159 "The time it takes to deserialize a message body") 160 if err != nil { 161 return nil, err 162 } 163 164 return context.WithValue(parent, operationMetricsKey{}, om), nil 165 } 166 167 func operationMetricTimer(m metrics.Meter, name, desc string) (metrics.Float64Histogram, error) { 168 return m.Float64Histogram(name, func(o *metrics.InstrumentOptions) { 169 o.UnitLabel = "s" 170 o.Description = desc 171 }) 172 } 173 174 func getOperationMetrics(ctx context.Context) *operationMetrics { 175 if v := ctx.Value(operationMetricsKey{}); v != nil { 176 return v.(*operationMetrics) 177 } 178 return nil 179 } 180 181 func operationTracer(p tracing.TracerProvider) tracing.Tracer { 182 return p.Tracer("github.com/aws/aws-sdk-go-v2/service/sts") 183 } 184 185 // Client provides the API client to make operations call for AWS Security Token 186 // Service. 187 type Client struct { 188 options Options 189 190 // Difference between the time reported by the server and the client 191 timeOffset *atomic.Int64 192 } 193 194 // New returns an initialized Client based on the functional options. Provide 195 // additional functional options to further configure the behavior of the client, 196 // such as changing the client's endpoint or adding custom middleware behavior. 197 func New(options Options, optFns ...func(*Options)) *Client { 198 options = options.Copy() 199 200 resolveDefaultLogger(&options) 201 202 setResolvedDefaultsMode(&options) 203 204 resolveRetryer(&options) 205 206 resolveHTTPClient(&options) 207 208 resolveHTTPSignerV4(&options) 209 210 resolveEndpointResolverV2(&options) 211 212 resolveHTTPSignerV4a(&options) 213 214 resolveTracerProvider(&options) 215 216 resolveMeterProvider(&options) 217 218 resolveAuthSchemeResolver(&options) 219 220 for _, fn := range optFns { 221 fn(&options) 222 } 223 224 finalizeRetryMaxAttempts(&options) 225 226 ignoreAnonymousAuth(&options) 227 228 finalizeSTSRetryableErrors(&options) 229 230 wrapWithAnonymousAuth(&options) 231 232 resolveAuthSchemes(&options) 233 234 client := &Client{ 235 options: options, 236 } 237 238 initializeTimeOffsetResolver(client) 239 240 return client 241 } 242 243 // Options returns a copy of the client configuration. 244 // 245 // Callers SHOULD NOT perform mutations on any inner structures within client 246 // config. Config overrides should instead be made on a per-operation basis through 247 // functional options. 248 func (c *Client) Options() Options { 249 return c.options.Copy() 250 } 251 252 func (c *Client) invokeOperation( 253 ctx context.Context, opID string, params interface{}, optFns []func(*Options), stackFns ...func(*middleware.Stack, Options) error, 254 ) ( 255 result interface{}, metadata middleware.Metadata, err error, 256 ) { 257 ctx = middleware.ClearStackValues(ctx) 258 ctx = middleware.WithServiceID(ctx, ServiceID) 259 ctx = middleware.WithOperationName(ctx, opID) 260 261 stack := middleware.NewStack(opID, smithyhttp.NewStackRequest) 262 options := c.options.Copy() 263 264 for _, fn := range optFns { 265 fn(&options) 266 } 267 268 finalizeOperationRetryMaxAttempts(&options, *c) 269 270 finalizeClientEndpointResolverOptions(&options) 271 272 ctx = setLoggerContext(ctx, options, opID) 273 274 ctx = resolveServiceMetadata(ctx, options, opID) 275 276 if err := c.addCommonMiddlewares(stack, options, opID); err != nil { 277 return nil, metadata, err 278 } 279 280 for _, fn := range stackFns { 281 if err := fn(stack, options); err != nil { 282 return nil, metadata, err 283 } 284 } 285 286 for _, fn := range options.APIOptions { 287 if err := fn(stack); err != nil { 288 return nil, metadata, err 289 } 290 } 291 292 ctx, err = withOperationMetrics(ctx, options.MeterProvider) 293 if err != nil { 294 return nil, metadata, err 295 } 296 297 tracer := operationTracer(options.TracerProvider) 298 spanName := fmt.Sprintf("%s.%s", ServiceID, opID) 299 300 ctx = tracing.WithOperationTracer(ctx, tracer) 301 302 ctx, span := tracer.StartSpan(ctx, spanName, func(o *tracing.SpanOptions) { 303 o.Kind = tracing.SpanKindClient 304 o.Properties.Set("rpc.system", "aws-api") 305 o.Properties.Set("rpc.method", opID) 306 o.Properties.Set("rpc.service", ServiceID) 307 }) 308 endTimer := startMetricTimer(ctx, "client.call.duration") 309 defer endTimer() 310 defer span.End() 311 312 handler := smithyhttp.NewClientHandlerWithOptions(options.HTTPClient, func(o *smithyhttp.ClientHandler) { 313 o.Meter = options.MeterProvider.Meter("github.com/aws/aws-sdk-go-v2/service/sts") 314 }) 315 decorated := middleware.DecorateHandler(handler, stack) 316 result, metadata, err = decorated.Handle(ctx, params) 317 if err != nil { 318 span.SetProperty("exception.type", fmt.Sprintf("%T", err)) 319 span.SetProperty("exception.message", err.Error()) 320 321 var aerr smithy.APIError 322 if errors.As(err, &aerr) { 323 span.SetProperty("api.error_code", aerr.ErrorCode()) 324 span.SetProperty("api.error_message", aerr.ErrorMessage()) 325 span.SetProperty("api.error_fault", aerr.ErrorFault().String()) 326 } 327 328 err = &smithy.OperationError{ 329 ServiceID: ServiceID, 330 OperationName: opID, 331 Err: err, 332 } 333 } 334 335 span.SetProperty("error", err != nil) 336 if err == nil { 337 span.SetStatus(tracing.SpanStatusOK) 338 } else { 339 span.SetStatus(tracing.SpanStatusError) 340 } 341 342 return result, metadata, err 343 } 344 345 type operationInputKey struct{} 346 347 func setOperationInput(ctx context.Context, input interface{}) context.Context { 348 return middleware.WithStackValue(ctx, operationInputKey{}, input) 349 } 350 351 func getOperationInput(ctx context.Context) interface{} { 352 return middleware.GetStackValue(ctx, operationInputKey{}) 353 } 354 355 type setOperationInputMiddleware struct { 356 } 357 358 func (*setOperationInputMiddleware) ID() string { 359 return "setOperationInput" 360 } 361 362 func (m *setOperationInputMiddleware) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( 363 out middleware.SerializeOutput, metadata middleware.Metadata, err error, 364 ) { 365 ctx = setOperationInput(ctx, in.Parameters) 366 return next.HandleSerialize(ctx, in) 367 } 368 369 func addProtocolFinalizerMiddlewares(stack *middleware.Stack, options Options, operation string) error { 370 if err := stack.Finalize.Add(&resolveAuthSchemeMiddleware{operation: operation, options: options}, middleware.Before); err != nil { 371 return fmt.Errorf("add ResolveAuthScheme: %w", err) 372 } 373 if err := stack.Finalize.Insert(&getIdentityMiddleware{options: options}, "ResolveAuthScheme", middleware.After); err != nil { 374 return fmt.Errorf("add GetIdentity: %v", err) 375 } 376 if err := stack.Finalize.Insert(&resolveEndpointV2Middleware{options: options}, "GetIdentity", middleware.After); err != nil { 377 return fmt.Errorf("add ResolveEndpointV2: %v", err) 378 } 379 if err := stack.Finalize.Insert(&signRequestMiddleware{options: options}, "ResolveEndpointV2", middleware.After); err != nil { 380 return fmt.Errorf("add Signing: %w", err) 381 } 382 return nil 383 } 384 385 func (c *Client) addCommonMiddlewares(stack *middleware.Stack, options Options, operation string) error { 386 if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { 387 return err 388 } 389 if err := addProtocolFinalizerMiddlewares(stack, options, operation); err != nil { 390 return fmt.Errorf("add protocol finalizers: %v", err) 391 } 392 if err := addClientRequestID(stack); err != nil { 393 return err 394 } 395 if err := addRetry(stack, options, c); err != nil { 396 return err 397 } 398 if err := addRawResponseToMetadata(stack); err != nil { 399 return err 400 } 401 if err := addSpanRetryLoop(stack, options); err != nil { 402 return err 403 } 404 if err := addClientUserAgent(stack, options); err != nil { 405 return err 406 } 407 if err := addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { 408 return err 409 } 410 if err := addUserAgentRetryMode(stack, options); err != nil { 411 return err 412 } 413 if err := addRecursionDetection(stack); err != nil { 414 return err 415 } 416 if err := addInterceptBeforeRetryLoop(stack, options); err != nil { 417 return err 418 } 419 if err := addInterceptAttempt(stack, options); err != nil { 420 return err 421 } 422 return nil 423 } 424 func resolveAuthSchemeResolver(options *Options) { 425 if options.AuthSchemeResolver == nil { 426 options.AuthSchemeResolver = &defaultAuthSchemeResolver{} 427 } 428 } 429 430 func resolveAuthSchemes(options *Options) { 431 if options.AuthSchemes == nil { 432 options.AuthSchemes = []smithyhttp.AuthScheme{ 433 internalauth.NewHTTPAuthScheme("aws.auth#sigv4", &internalauthsmithy.V4SignerAdapter{ 434 Signer: options.HTTPSignerV4, 435 Logger: options.Logger, 436 LogSigning: options.ClientLogMode.IsSigning(), 437 }), 438 internalauth.NewHTTPAuthScheme("aws.auth#sigv4a", &v4a.SignerAdapter{ 439 Signer: options.httpSignerV4a, 440 Logger: options.Logger, 441 LogSigning: options.ClientLogMode.IsSigning(), 442 }), 443 } 444 } 445 } 446 447 type noSmithyDocumentSerde = smithydocument.NoSerde 448 449 func resolveDefaultLogger(o *Options) { 450 if o.Logger != nil { 451 return 452 } 453 o.Logger = logging.Nop{} 454 } 455 456 func setLoggerContext(ctx context.Context, options Options, operation string) context.Context { 457 _ = operation 458 return middleware.SetLogger(ctx, options.Logger) 459 } 460 461 func setResolvedDefaultsMode(o *Options) { 462 if len(o.resolvedDefaultsMode) > 0 { 463 return 464 } 465 466 var mode aws.DefaultsMode 467 mode.SetFromString(string(o.DefaultsMode)) 468 469 if mode == aws.DefaultsModeAuto { 470 mode = defaults.ResolveDefaultsModeAuto(o.Region, o.RuntimeEnvironment) 471 } 472 473 o.resolvedDefaultsMode = mode 474 } 475 476 // NewFromConfig returns a new client from the provided config. 477 func NewFromConfig(cfg aws.Config, optFns ...func(*Options)) *Client { 478 opts := Options{ 479 Region: cfg.Region, 480 DefaultsMode: cfg.DefaultsMode, 481 RuntimeEnvironment: cfg.RuntimeEnvironment, 482 HTTPClient: cfg.HTTPClient, 483 Credentials: cfg.Credentials, 484 APIOptions: cfg.APIOptions, 485 Logger: cfg.Logger, 486 ClientLogMode: cfg.ClientLogMode, 487 AppID: cfg.AppID, 488 DisableClockSkewCorrection: cfg.DisableClockSkewCorrection, 489 AuthSchemePreference: cfg.AuthSchemePreference, 490 } 491 resolveAWSRetryerProvider(cfg, &opts) 492 resolveAWSRetryMaxAttempts(cfg, &opts) 493 resolveAWSRetryMode(cfg, &opts) 494 resolveAWSEndpointResolver(cfg, &opts) 495 resolveInterceptors(cfg, &opts) 496 resolveUseDualStackEndpoint(cfg, &opts) 497 resolveUseFIPSEndpoint(cfg, &opts) 498 resolveBaseEndpoint(cfg, &opts) 499 return New(opts, func(o *Options) { 500 for _, opt := range cfg.ServiceOptions { 501 opt(ServiceID, o) 502 } 503 for _, opt := range optFns { 504 opt(o) 505 } 506 }) 507 } 508 509 func resolveHTTPClient(o *Options) { 510 var buildable *awshttp.BuildableClient 511 512 if o.HTTPClient != nil { 513 var ok bool 514 buildable, ok = o.HTTPClient.(*awshttp.BuildableClient) 515 if !ok { 516 return 517 } 518 } else { 519 buildable = awshttp.NewBuildableClient() 520 } 521 522 modeConfig, err := defaults.GetModeConfiguration(o.resolvedDefaultsMode) 523 if err == nil { 524 buildable = buildable.WithDialerOptions(func(dialer *net.Dialer) { 525 if dialerTimeout, ok := modeConfig.GetConnectTimeout(); ok { 526 dialer.Timeout = dialerTimeout 527 } 528 }) 529 530 buildable = buildable.WithTransportOptions(func(transport *http.Transport) { 531 if tlsHandshakeTimeout, ok := modeConfig.GetTLSNegotiationTimeout(); ok { 532 transport.TLSHandshakeTimeout = tlsHandshakeTimeout 533 } 534 }) 535 } 536 537 o.HTTPClient = buildable 538 } 539 540 func resolveRetryer(o *Options) { 541 if o.Retryer != nil { 542 return 543 } 544 545 if len(o.RetryMode) == 0 { 546 modeConfig, err := defaults.GetModeConfiguration(o.resolvedDefaultsMode) 547 if err == nil { 548 o.RetryMode = modeConfig.RetryMode 549 } 550 } 551 if len(o.RetryMode) == 0 { 552 o.RetryMode = aws.RetryModeStandard 553 } 554 555 var standardOptions []func(*retry.StandardOptions) 556 if v := o.RetryMaxAttempts; v != 0 { 557 standardOptions = append(standardOptions, func(so *retry.StandardOptions) { 558 so.MaxAttempts = v 559 }) 560 } 561 562 switch o.RetryMode { 563 case aws.RetryModeAdaptive: 564 var adaptiveOptions []func(*retry.AdaptiveModeOptions) 565 if len(standardOptions) != 0 { 566 adaptiveOptions = append(adaptiveOptions, func(ao *retry.AdaptiveModeOptions) { 567 ao.StandardOptions = append(ao.StandardOptions, standardOptions...) 568 }) 569 } 570 o.Retryer = retry.NewAdaptiveMode(adaptiveOptions...) 571 572 default: 573 o.Retryer = retry.NewStandard(standardOptions...) 574 } 575 } 576 577 func resolveAWSRetryerProvider(cfg aws.Config, o *Options) { 578 if cfg.Retryer == nil { 579 return 580 } 581 o.Retryer = cfg.Retryer() 582 } 583 584 func resolveAWSRetryMode(cfg aws.Config, o *Options) { 585 if len(cfg.RetryMode) == 0 { 586 return 587 } 588 o.RetryMode = cfg.RetryMode 589 } 590 func resolveAWSRetryMaxAttempts(cfg aws.Config, o *Options) { 591 if cfg.RetryMaxAttempts == 0 { 592 return 593 } 594 o.RetryMaxAttempts = cfg.RetryMaxAttempts 595 } 596 597 func finalizeRetryMaxAttempts(o *Options) { 598 if o.RetryMaxAttempts == 0 { 599 return 600 } 601 602 o.Retryer = retry.AddWithMaxAttempts(o.Retryer, o.RetryMaxAttempts) 603 } 604 605 func finalizeOperationRetryMaxAttempts(o *Options, client Client) { 606 if v := o.RetryMaxAttempts; v == 0 || v == client.options.RetryMaxAttempts { 607 return 608 } 609 610 o.Retryer = retry.AddWithMaxAttempts(o.Retryer, o.RetryMaxAttempts) 611 } 612 613 func resolveAWSEndpointResolver(cfg aws.Config, o *Options) { 614 if cfg.EndpointResolver == nil && cfg.EndpointResolverWithOptions == nil { 615 return 616 } 617 o.EndpointResolver = withEndpointResolver(cfg.EndpointResolver, cfg.EndpointResolverWithOptions) 618 } 619 620 func resolveInterceptors(cfg aws.Config, o *Options) { 621 o.Interceptors = cfg.Interceptors.Copy() 622 } 623 624 func addClientUserAgent(stack *middleware.Stack, options Options) error { 625 ua, err := getOrAddRequestUserAgent(stack) 626 if err != nil { 627 return err 628 } 629 630 ua.AddSDKAgentKeyValue(awsmiddleware.APIMetadata, "sts", goModuleVersion) 631 if len(options.AppID) > 0 { 632 ua.AddSDKAgentKey(awsmiddleware.ApplicationIdentifier, options.AppID) 633 } 634 635 return nil 636 } 637 638 func getOrAddRequestUserAgent(stack *middleware.Stack) (*awsmiddleware.RequestUserAgent, error) { 639 id := (*awsmiddleware.RequestUserAgent)(nil).ID() 640 mw, ok := stack.Build.Get(id) 641 if !ok { 642 mw = awsmiddleware.NewRequestUserAgent() 643 if err := stack.Build.Add(mw, middleware.After); err != nil { 644 return nil, err 645 } 646 } 647 648 ua, ok := mw.(*awsmiddleware.RequestUserAgent) 649 if !ok { 650 return nil, fmt.Errorf("%T for %s middleware did not match expected type", mw, id) 651 } 652 653 return ua, nil 654 } 655 656 type HTTPSignerV4 interface { 657 SignHTTP(ctx context.Context, credentials aws.Credentials, r *http.Request, payloadHash string, service string, region string, signingTime time.Time, optFns ...func(*v4.SignerOptions)) error 658 } 659 660 func resolveHTTPSignerV4(o *Options) { 661 if o.HTTPSignerV4 != nil { 662 return 663 } 664 o.HTTPSignerV4 = newDefaultV4Signer(*o) 665 } 666 667 func newDefaultV4Signer(o Options) *v4.Signer { 668 return v4.NewSigner(func(so *v4.SignerOptions) { 669 so.Logger = o.Logger 670 so.LogSigning = o.ClientLogMode.IsSigning() 671 }) 672 } 673 674 func addClientRequestID(stack *middleware.Stack) error { 675 return stack.Build.Add(&awsmiddleware.ClientRequestID{}, middleware.After) 676 } 677 678 func addComputeContentLength(stack *middleware.Stack) error { 679 return stack.Build.Insert(&smithyhttp.ComputeContentLength{}, "ClientRequestID", middleware.After) 680 } 681 682 func addRawResponseToMetadata(stack *middleware.Stack) error { 683 return stack.Deserialize.Add(&awsmiddleware.AddRawResponse{}, middleware.Before) 684 } 685 686 func addRecordResponseTiming(stack *middleware.Stack, options Options) error { 687 return stack.Deserialize.Add(&awsmiddleware.RecordResponseTiming{ 688 DisableClockSkewCorrection: options.DisableClockSkewCorrection, 689 }, middleware.After) 690 } 691 692 func addSpanRetryLoop(stack *middleware.Stack, options Options) error { 693 return stack.Finalize.Insert(&spanRetryLoop{options: options}, "Retry", middleware.Before) 694 } 695 696 type spanRetryLoop struct { 697 options Options 698 } 699 700 func (*spanRetryLoop) ID() string { 701 return "spanRetryLoop" 702 } 703 704 func (m *spanRetryLoop) HandleFinalize( 705 ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler, 706 ) ( 707 middleware.FinalizeOutput, middleware.Metadata, error, 708 ) { 709 tracer := operationTracer(m.options.TracerProvider) 710 ctx, span := tracer.StartSpan(ctx, "RetryLoop") 711 defer span.End() 712 713 return next.HandleFinalize(ctx, in) 714 } 715 func addStreamingEventsPayload(stack *middleware.Stack) error { 716 return stack.Finalize.Add(&v4.StreamingEventsPayload{}, middleware.Before) 717 } 718 719 func addUnsignedPayload(stack *middleware.Stack) error { 720 return stack.Finalize.Insert(&v4.UnsignedPayload{}, "ResolveEndpointV2", middleware.After) 721 } 722 723 func addComputePayloadSHA256(stack *middleware.Stack) error { 724 return stack.Finalize.Insert(&v4.ComputePayloadSHA256{}, "ResolveEndpointV2", middleware.After) 725 } 726 727 func addContentSHA256Header(stack *middleware.Stack) error { 728 return stack.Finalize.Insert(&v4.ContentSHA256Header{}, (*v4.ComputePayloadSHA256)(nil).ID(), middleware.After) 729 } 730 731 func addIsWaiterUserAgent(o *Options) { 732 o.APIOptions = append(o.APIOptions, func(stack *middleware.Stack) error { 733 ua, err := getOrAddRequestUserAgent(stack) 734 if err != nil { 735 return err 736 } 737 738 ua.AddUserAgentFeature(awsmiddleware.UserAgentFeatureWaiter) 739 return nil 740 }) 741 } 742 743 func addIsPaginatorUserAgent(o *Options) { 744 o.APIOptions = append(o.APIOptions, func(stack *middleware.Stack) error { 745 ua, err := getOrAddRequestUserAgent(stack) 746 if err != nil { 747 return err 748 } 749 750 ua.AddUserAgentFeature(awsmiddleware.UserAgentFeaturePaginator) 751 return nil 752 }) 753 } 754 755 func addRetry(stack *middleware.Stack, o Options, c *Client) error { 756 attempt := retry.NewAttemptMiddleware(o.Retryer, smithyhttp.RequestCloner, func(m *retry.Attempt) { 757 m.LogAttempts = o.ClientLogMode.IsRetries() 758 m.OperationMeter = o.MeterProvider.Meter("github.com/aws/aws-sdk-go-v2/service/sts") 759 m.ClientSkew = c.timeOffset 760 m.DisableClockSkewCorrection = o.DisableClockSkewCorrection 761 }) 762 if err := stack.Finalize.Insert(attempt, "ResolveAuthScheme", middleware.Before); err != nil { 763 return err 764 } 765 if err := stack.Finalize.Insert(&retry.MetricsHeader{}, attempt.ID(), middleware.After); err != nil { 766 return err 767 } 768 return nil 769 } 770 771 // resolves dual-stack endpoint configuration 772 func resolveUseDualStackEndpoint(cfg aws.Config, o *Options) error { 773 if len(cfg.ConfigSources) == 0 { 774 return nil 775 } 776 value, found, err := internalConfig.ResolveUseDualStackEndpoint(context.Background(), cfg.ConfigSources) 777 if err != nil { 778 return err 779 } 780 if found { 781 o.EndpointOptions.UseDualStackEndpoint = value 782 } 783 return nil 784 } 785 786 // resolves FIPS endpoint configuration 787 func resolveUseFIPSEndpoint(cfg aws.Config, o *Options) error { 788 if len(cfg.ConfigSources) == 0 { 789 return nil 790 } 791 value, found, err := internalConfig.ResolveUseFIPSEndpoint(context.Background(), cfg.ConfigSources) 792 if err != nil { 793 return err 794 } 795 if found { 796 o.EndpointOptions.UseFIPSEndpoint = value 797 } 798 return nil 799 } 800 801 type httpSignerV4a interface { 802 SignHTTP(ctx context.Context, credentials v4a.Credentials, r *http.Request, payloadHash, 803 service string, regionSet []string, signingTime time.Time, 804 optFns ...func(*v4a.SignerOptions)) error 805 } 806 807 func resolveHTTPSignerV4a(o *Options) { 808 if o.httpSignerV4a != nil { 809 return 810 } 811 o.httpSignerV4a = newDefaultV4aSigner(*o) 812 } 813 814 func newDefaultV4aSigner(o Options) *v4a.Signer { 815 return v4a.NewSigner(func(so *v4a.SignerOptions) { 816 so.Logger = o.Logger 817 so.LogSigning = o.ClientLogMode.IsSigning() 818 }) 819 } 820 821 func initializeTimeOffsetResolver(c *Client) { 822 c.timeOffset = new(atomic.Int64) 823 } 824 825 func addUserAgentRetryMode(stack *middleware.Stack, options Options) error { 826 ua, err := getOrAddRequestUserAgent(stack) 827 if err != nil { 828 return err 829 } 830 831 switch options.Retryer.(type) { 832 case *retry.Standard: 833 ua.AddUserAgentFeature(awsmiddleware.UserAgentFeatureRetryModeStandard) 834 case *retry.AdaptiveMode: 835 ua.AddUserAgentFeature(awsmiddleware.UserAgentFeatureRetryModeAdaptive) 836 } 837 return nil 838 } 839 840 type setCredentialSourceMiddleware struct { 841 ua *awsmiddleware.RequestUserAgent 842 options Options 843 } 844 845 func (m setCredentialSourceMiddleware) ID() string { return "SetCredentialSourceMiddleware" } 846 847 func (m setCredentialSourceMiddleware) HandleBuild(ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler) ( 848 out middleware.BuildOutput, metadata middleware.Metadata, err error, 849 ) { 850 asProviderSource, ok := m.options.Credentials.(aws.CredentialProviderSource) 851 if !ok { 852 return next.HandleBuild(ctx, in) 853 } 854 providerSources := asProviderSource.ProviderSources() 855 for _, source := range providerSources { 856 m.ua.AddCredentialsSource(source) 857 } 858 return next.HandleBuild(ctx, in) 859 } 860 861 func addCredentialSource(stack *middleware.Stack, options Options) error { 862 ua, err := getOrAddRequestUserAgent(stack) 863 if err != nil { 864 return err 865 } 866 867 mw := setCredentialSourceMiddleware{ua: ua, options: options} 868 return stack.Build.Insert(&mw, "UserAgent", middleware.Before) 869 } 870 871 func finalizeSTSRetryableErrors(o *Options) { 872 o.Retryer = retry.AddWithErrorCodes(o.Retryer, "IDPCommunicationError") 873 } 874 875 func resolveTracerProvider(options *Options) { 876 if options.TracerProvider == nil { 877 options.TracerProvider = &tracing.NopTracerProvider{} 878 } 879 } 880 881 func resolveMeterProvider(options *Options) { 882 if options.MeterProvider == nil { 883 options.MeterProvider = metrics.NopMeterProvider{} 884 } 885 } 886 887 func resolveServiceMetadata(ctx context.Context, options Options, operation string) context.Context { 888 ctx = awsmiddleware.SetServiceID(ctx, ServiceID) 889 if options.Region != "" { 890 ctx = awsmiddleware.SetRegion(ctx, options.Region) 891 } 892 ctx = awsmiddleware.SetOperationName(ctx, operation) 893 if options.EndpointResolver != nil { 894 ctx = awsmiddleware.SetRequiresLegacyEndpoints(ctx, true) 895 } 896 return ctx 897 } 898 899 func addRecursionDetection(stack *middleware.Stack) error { 900 return stack.Build.Add(&awsmiddleware.RecursionDetection{}, middleware.After) 901 } 902 903 func addRequestIDRetrieverMiddleware(stack *middleware.Stack) error { 904 return stack.Deserialize.Insert(&awsmiddleware.RequestIDRetriever{}, "OperationDeserializer", middleware.Before) 905 906 } 907 908 func addResponseErrorMiddleware(stack *middleware.Stack) error { 909 return stack.Deserialize.Insert(&awshttp.ResponseErrorWrapper{}, "RequestIDRetriever", middleware.Before) 910 911 } 912 913 // HTTPPresignerV4 represents presigner interface used by presign url client 914 type HTTPPresignerV4 interface { 915 PresignHTTP( 916 ctx context.Context, credentials aws.Credentials, r *http.Request, 917 payloadHash string, service string, region string, signingTime time.Time, 918 optFns ...func(*v4.SignerOptions), 919 ) (url string, signedHeader http.Header, err error) 920 } 921 922 // PresignOptions represents the presign client options 923 type PresignOptions struct { 924 925 // ClientOptions are list of functional options to mutate client options used by 926 // the presign client. 927 ClientOptions []func(*Options) 928 929 // Presigner is the presigner used by the presign url client 930 Presigner HTTPPresignerV4 931 } 932 933 func (o PresignOptions) copy() PresignOptions { 934 clientOptions := make([]func(*Options), len(o.ClientOptions)) 935 copy(clientOptions, o.ClientOptions) 936 o.ClientOptions = clientOptions 937 return o 938 } 939 940 // WithPresignClientFromClientOptions is a helper utility to retrieve a function 941 // that takes PresignOption as input 942 func WithPresignClientFromClientOptions(optFns ...func(*Options)) func(*PresignOptions) { 943 return withPresignClientFromClientOptions(optFns).options 944 } 945 946 type withPresignClientFromClientOptions []func(*Options) 947 948 func (w withPresignClientFromClientOptions) options(o *PresignOptions) { 949 o.ClientOptions = append(o.ClientOptions, w...) 950 } 951 952 // PresignClient represents the presign url client 953 type PresignClient struct { 954 client *Client 955 options PresignOptions 956 } 957 958 // NewPresignClient generates a presign client using provided API Client and 959 // presign options 960 func NewPresignClient(c *Client, optFns ...func(*PresignOptions)) *PresignClient { 961 var options PresignOptions 962 for _, fn := range optFns { 963 fn(&options) 964 } 965 if len(options.ClientOptions) != 0 { 966 c = New(c.options, options.ClientOptions...) 967 } 968 969 if options.Presigner == nil { 970 options.Presigner = newDefaultV4Signer(c.options) 971 } 972 973 return &PresignClient{ 974 client: c, 975 options: options, 976 } 977 } 978 979 func withNopHTTPClientAPIOption(o *Options) { 980 o.HTTPClient = smithyhttp.NopClient{} 981 } 982 983 type presignContextPolyfillMiddleware struct { 984 } 985 986 func (*presignContextPolyfillMiddleware) ID() string { 987 return "presignContextPolyfill" 988 } 989 990 func (m *presignContextPolyfillMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( 991 out middleware.FinalizeOutput, metadata middleware.Metadata, err error, 992 ) { 993 rscheme := getResolvedAuthScheme(ctx) 994 if rscheme == nil { 995 return out, metadata, fmt.Errorf("no resolved auth scheme") 996 } 997 998 schemeID := rscheme.Scheme.SchemeID() 999 1000 if schemeID == "aws.auth#sigv4" || schemeID == "com.amazonaws.s3#sigv4express" { 1001 if sn, ok := smithyhttp.GetSigV4SigningName(&rscheme.SignerProperties); ok { 1002 ctx = awsmiddleware.SetSigningName(ctx, sn) 1003 } 1004 if sr, ok := smithyhttp.GetSigV4SigningRegion(&rscheme.SignerProperties); ok { 1005 ctx = awsmiddleware.SetSigningRegion(ctx, sr) 1006 } 1007 } else if schemeID == "aws.auth#sigv4a" { 1008 if sn, ok := smithyhttp.GetSigV4ASigningName(&rscheme.SignerProperties); ok { 1009 ctx = awsmiddleware.SetSigningName(ctx, sn) 1010 } 1011 if sr, ok := smithyhttp.GetSigV4ASigningRegions(&rscheme.SignerProperties); ok { 1012 ctx = awsmiddleware.SetSigningRegion(ctx, sr[0]) 1013 } 1014 } 1015 1016 return next.HandleFinalize(ctx, in) 1017 } 1018 1019 type presignConverter PresignOptions 1020 1021 func (c presignConverter) convertToPresignMiddleware(stack *middleware.Stack, options Options) (err error) { 1022 if _, ok := stack.Finalize.Get((*acceptencodingcust.DisableGzip)(nil).ID()); ok { 1023 stack.Finalize.Remove((*acceptencodingcust.DisableGzip)(nil).ID()) 1024 } 1025 if _, ok := stack.Finalize.Get((*retry.Attempt)(nil).ID()); ok { 1026 stack.Finalize.Remove((*retry.Attempt)(nil).ID()) 1027 } 1028 if _, ok := stack.Finalize.Get((*retry.MetricsHeader)(nil).ID()); ok { 1029 stack.Finalize.Remove((*retry.MetricsHeader)(nil).ID()) 1030 } 1031 stack.Deserialize.Clear() 1032 stack.Build.Remove((*awsmiddleware.ClientRequestID)(nil).ID()) 1033 stack.Build.Remove("UserAgent") 1034 if err := stack.Finalize.Insert(&presignContextPolyfillMiddleware{}, "Signing", middleware.Before); err != nil { 1035 return err 1036 } 1037 1038 pmw := v4.NewPresignHTTPRequestMiddleware(v4.PresignHTTPRequestMiddlewareOptions{ 1039 CredentialsProvider: options.Credentials, 1040 Presigner: c.Presigner, 1041 LogSigning: options.ClientLogMode.IsSigning(), 1042 }) 1043 if _, err := stack.Finalize.Swap("Signing", pmw); err != nil { 1044 return err 1045 } 1046 if err = smithyhttp.AddNoPayloadDefaultContentTypeRemover(stack); err != nil { 1047 return err 1048 } 1049 // convert request to a GET request 1050 err = query.AddAsGetRequestMiddleware(stack) 1051 if err != nil { 1052 return err 1053 } 1054 err = presignedurlcust.AddAsIsPresigningMiddleware(stack) 1055 if err != nil { 1056 return err 1057 } 1058 return nil 1059 } 1060 1061 func addRequestResponseLogging(stack *middleware.Stack, o Options) error { 1062 return stack.Deserialize.Add(&smithyhttp.RequestResponseLogger{ 1063 LogRequest: o.ClientLogMode.IsRequest(), 1064 LogRequestWithBody: o.ClientLogMode.IsRequestWithBody(), 1065 LogResponse: o.ClientLogMode.IsResponse(), 1066 LogResponseWithBody: o.ClientLogMode.IsResponseWithBody(), 1067 }, middleware.After) 1068 } 1069 1070 type disableHTTPSMiddleware struct { 1071 DisableHTTPS bool 1072 } 1073 1074 func (*disableHTTPSMiddleware) ID() string { 1075 return "disableHTTPS" 1076 } 1077 1078 func (m *disableHTTPSMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( 1079 out middleware.FinalizeOutput, metadata middleware.Metadata, err error, 1080 ) { 1081 req, ok := in.Request.(*smithyhttp.Request) 1082 if !ok { 1083 return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) 1084 } 1085 1086 if m.DisableHTTPS && !smithyhttp.GetHostnameImmutable(ctx) { 1087 req.URL.Scheme = "http" 1088 } 1089 1090 return next.HandleFinalize(ctx, in) 1091 } 1092 1093 func addDisableHTTPSMiddleware(stack *middleware.Stack, o Options) error { 1094 return stack.Finalize.Insert(&disableHTTPSMiddleware{ 1095 DisableHTTPS: o.EndpointOptions.DisableHTTPS, 1096 }, "ResolveEndpointV2", middleware.After) 1097 } 1098 1099 func addInterceptBeforeRetryLoop(stack *middleware.Stack, opts Options) error { 1100 return stack.Finalize.Insert(&smithyhttp.InterceptBeforeRetryLoop{ 1101 Interceptors: opts.Interceptors.BeforeRetryLoop, 1102 }, "Retry", middleware.Before) 1103 } 1104 1105 func addInterceptAttempt(stack *middleware.Stack, opts Options) error { 1106 return stack.Finalize.Insert(&smithyhttp.InterceptAttempt{ 1107 BeforeAttempt: opts.Interceptors.BeforeAttempt, 1108 AfterAttempt: opts.Interceptors.AfterAttempt, 1109 }, "Retry", middleware.After) 1110 } 1111 1112 func addInterceptors(stack *middleware.Stack, opts Options) error { 1113 // middlewares are expensive, don't add all of these interceptor ones unless the caller 1114 // actually has at least one interceptor configured 1115 // 1116 // at the moment it's all-or-nothing because some of the middlewares here are responsible for 1117 // setting fields in the interceptor context for future ones 1118 if len(opts.Interceptors.BeforeExecution) == 0 && 1119 len(opts.Interceptors.BeforeSerialization) == 0 && len(opts.Interceptors.AfterSerialization) == 0 && 1120 len(opts.Interceptors.BeforeRetryLoop) == 0 && 1121 len(opts.Interceptors.BeforeAttempt) == 0 && 1122 len(opts.Interceptors.BeforeSigning) == 0 && len(opts.Interceptors.AfterSigning) == 0 && 1123 len(opts.Interceptors.BeforeTransmit) == 0 && len(opts.Interceptors.AfterTransmit) == 0 && 1124 len(opts.Interceptors.BeforeDeserialization) == 0 && len(opts.Interceptors.AfterDeserialization) == 0 && 1125 len(opts.Interceptors.AfterAttempt) == 0 && len(opts.Interceptors.AfterExecution) == 0 { 1126 return nil 1127 } 1128 1129 return errors.Join( 1130 stack.Initialize.Add(&smithyhttp.InterceptExecution{ 1131 BeforeExecution: opts.Interceptors.BeforeExecution, 1132 AfterExecution: opts.Interceptors.AfterExecution, 1133 }, middleware.Before), 1134 stack.Serialize.Insert(&smithyhttp.InterceptBeforeSerialization{ 1135 Interceptors: opts.Interceptors.BeforeSerialization, 1136 }, "OperationSerializer", middleware.Before), 1137 stack.Serialize.Insert(&smithyhttp.InterceptAfterSerialization{ 1138 Interceptors: opts.Interceptors.AfterSerialization, 1139 }, "OperationSerializer", middleware.After), 1140 stack.Finalize.Insert(&smithyhttp.InterceptBeforeSigning{ 1141 Interceptors: opts.Interceptors.BeforeSigning, 1142 }, "Signing", middleware.Before), 1143 stack.Finalize.Insert(&smithyhttp.InterceptAfterSigning{ 1144 Interceptors: opts.Interceptors.AfterSigning, 1145 }, "Signing", middleware.After), 1146 stack.Deserialize.Add(&smithyhttp.InterceptTransmit{ 1147 BeforeTransmit: opts.Interceptors.BeforeTransmit, 1148 AfterTransmit: opts.Interceptors.AfterTransmit, 1149 }, middleware.After), 1150 stack.Deserialize.Insert(&smithyhttp.InterceptBeforeDeserialization{ 1151 Interceptors: opts.Interceptors.BeforeDeserialization, 1152 }, "OperationDeserializer", middleware.After), // (deserialize stack is called in reverse) 1153 stack.Deserialize.Insert(&smithyhttp.InterceptAfterDeserialization{ 1154 Interceptors: opts.Interceptors.AfterDeserialization, 1155 }, "OperationDeserializer", middleware.Before), 1156 ) 1157 }