package s3
import (
awsmiddleware
awshttp
internalConfig
acceptencodingcust
internalChecksum
presignedurlcust
s3sharedconfig
s3cust
smithy
smithydocument
smithyhttp
)
const ServiceID = "S3"
const ServiceAPIVersion = "2006-03-01"
type Client struct {
options Options
}
func ( Options, ...func(*Options)) *Client {
= .Copy()
resolveDefaultLogger(&)
setResolvedDefaultsMode(&)
resolveRetryer(&)
resolveHTTPClient(&)
resolveHTTPSignerV4(&)
resolveDefaultEndpointConfiguration(&)
resolveHTTPSignerV4a(&)
for , := range {
(&)
}
resolveCredentialProvider(&)
:= &Client{
options: ,
}
return
}
type Options struct {
APIOptions []func(*middleware.Stack) error
ClientLogMode aws.ClientLogMode
Credentials aws.CredentialsProvider
DefaultsMode aws.DefaultsMode
DisableMultiRegionAccessPoints bool
EndpointOptions EndpointResolverOptions
EndpointResolver EndpointResolver
HTTPSignerV4 HTTPSignerV4
Logger logging.Logger
Region string
RetryMaxAttempts int
RetryMode aws.RetryMode
Retryer aws.Retryer
RuntimeEnvironment aws.RuntimeEnvironment
UseARNRegion bool
UseAccelerate bool
UseDualstack bool
UsePathStyle bool
httpSignerV4a httpSignerV4a
resolvedDefaultsMode aws.DefaultsMode
HTTPClient HTTPClient
}
func ( ...func(*middleware.Stack) error) func(*Options) {
return func( *Options) {
.APIOptions = append(.APIOptions, ...)
}
}
func ( EndpointResolver) func(*Options) {
return func( *Options) {
.EndpointResolver =
}
}
type HTTPClient interface {
Do(*http.Request) (*http.Response, error)
}
func ( Options) () Options {
:=
.APIOptions = make([]func(*middleware.Stack) error, len(.APIOptions))
copy(.APIOptions, .APIOptions)
return
}
func ( *Client) ( context.Context, string, interface{}, []func(*Options), ...func(*middleware.Stack, Options) error) ( interface{}, middleware.Metadata, error) {
= middleware.ClearStackValues()
:= middleware.NewStack(, smithyhttp.NewStackRequest)
:= .options.Copy()
for , := range {
(&)
}
setSafeEventStreamClientLogMode(&, )
finalizeRetryMaxAttemptOptions(&, *)
finalizeClientEndpointResolverOptions(&)
resolveCredentialProvider(&)
for , := range {
if := (, ); != nil {
return nil, ,
}
}
for , := range .APIOptions {
if := (); != nil {
return nil, ,
}
}
:= middleware.DecorateHandler(smithyhttp.NewClientHandler(.HTTPClient), )
, , = .Handle(, )
if != nil {
= &smithy.OperationError{
ServiceID: ServiceID,
OperationName: ,
Err: ,
}
}
return , ,
}
type noSmithyDocumentSerde = smithydocument.NoSerde
func ( *Options) {
if .Logger != nil {
return
}
.Logger = logging.Nop{}
}
func ( *middleware.Stack, Options) error {
return middleware.AddSetLoggerMiddleware(, .Logger)
}
func ( *Options) {
if len(.resolvedDefaultsMode) > 0 {
return
}
var aws.DefaultsMode
.SetFromString(string(.DefaultsMode))
if == aws.DefaultsModeAuto {
= defaults.ResolveDefaultsModeAuto(.Region, .RuntimeEnvironment)
}
.resolvedDefaultsMode =
}
func ( aws.Config, ...func(*Options)) *Client {
:= Options{
Region: .Region,
DefaultsMode: .DefaultsMode,
RuntimeEnvironment: .RuntimeEnvironment,
HTTPClient: .HTTPClient,
Credentials: .Credentials,
APIOptions: .APIOptions,
Logger: .Logger,
ClientLogMode: .ClientLogMode,
}
resolveAWSRetryerProvider(, &)
resolveAWSRetryMaxAttempts(, &)
resolveAWSRetryMode(, &)
resolveAWSEndpointResolver(, &)
resolveUseARNRegion(, &)
resolveUseDualStackEndpoint(, &)
resolveUseFIPSEndpoint(, &)
return New(, ...)
}
func ( *Options) {
var *awshttp.BuildableClient
if .HTTPClient != nil {
var bool
, = .HTTPClient.(*awshttp.BuildableClient)
if ! {
return
}
} else {
= awshttp.NewBuildableClient()
}
, := defaults.GetModeConfiguration(.resolvedDefaultsMode)
if == nil {
= .WithDialerOptions(func( *net.Dialer) {
if , := .GetConnectTimeout(); {
.Timeout =
}
})
= .WithTransportOptions(func( *http.Transport) {
if , := .GetTLSNegotiationTimeout(); {
.TLSHandshakeTimeout =
}
})
}
.HTTPClient =
}
func ( *Options) {
if .Retryer != nil {
return
}
if len(.RetryMode) == 0 {
, := defaults.GetModeConfiguration(.resolvedDefaultsMode)
if == nil {
.RetryMode = .RetryMode
}
}
if len(.RetryMode) == 0 {
.RetryMode = aws.RetryModeStandard
}
var []func(*retry.StandardOptions)
if := .RetryMaxAttempts; != 0 {
= append(, func( *retry.StandardOptions) {
.MaxAttempts =
})
}
switch .RetryMode {
case aws.RetryModeAdaptive:
var []func(*retry.AdaptiveModeOptions)
if len() != 0 {
= append(, func( *retry.AdaptiveModeOptions) {
.StandardOptions = append(.StandardOptions, ...)
})
}
.Retryer = retry.NewAdaptiveMode(...)
default:
.Retryer = retry.NewStandard(...)
}
}
func ( aws.Config, *Options) {
if .Retryer == nil {
return
}
.Retryer = .Retryer()
}
func ( aws.Config, *Options) {
if len(.RetryMode) == 0 {
return
}
.RetryMode = .RetryMode
}
func ( aws.Config, *Options) {
if .RetryMaxAttempts == 0 {
return
}
.RetryMaxAttempts = .RetryMaxAttempts
}
func ( *Options, Client) {
if := .RetryMaxAttempts; == 0 || == .options.RetryMaxAttempts {
return
}
.Retryer = retry.AddWithMaxAttempts(.Retryer, .RetryMaxAttempts)
}
func ( aws.Config, *Options) {
if .EndpointResolver == nil && .EndpointResolverWithOptions == nil {
return
}
.EndpointResolver = withEndpointResolver(.EndpointResolver, .EndpointResolverWithOptions, NewDefaultEndpointResolver())
}
func ( *middleware.Stack) error {
return awsmiddleware.AddSDKAgentKeyValue(awsmiddleware.APIMetadata, "s3", goModuleVersion)()
}
func ( *middleware.Stack, Options) error {
:= v4.NewSignHTTPRequestMiddleware(v4.SignHTTPRequestMiddlewareOptions{
CredentialsProvider: .Credentials,
Signer: .HTTPSignerV4,
LogSigning: .ClientLogMode.IsSigning(),
})
return .Finalize.Add(, middleware.After)
}
type HTTPSignerV4 interface {
SignHTTP(ctx context.Context, credentials aws.Credentials, r *http.Request, payloadHash string, service string, region string, signingTime time.Time, optFns ...func(*v4.SignerOptions)) error
}
func ( *Options) {
if .HTTPSignerV4 != nil {
return
}
.HTTPSignerV4 = newDefaultV4Signer(*)
}
func ( Options) *v4.Signer {
return v4.NewSigner(func( *v4.SignerOptions) {
.Logger = .Logger
.LogSigning = .ClientLogMode.IsSigning()
.DisableURIPathEscaping = true
})
}
func ( *middleware.Stack, Options) error {
:= retry.AddRetryMiddlewaresOptions{
Retryer: .Retryer,
LogRetryAttempts: .ClientLogMode.IsRetries(),
}
return retry.AddRetryMiddlewares(, )
}
func ( aws.Config, *Options) error {
if len(.ConfigSources) == 0 {
return nil
}
, , := s3sharedconfig.ResolveUseARNRegion(context.Background(), .ConfigSources)
if != nil {
return
}
if {
.UseARNRegion =
}
return nil
}
func ( aws.Config, *Options) error {
if len(.ConfigSources) == 0 {
return nil
}
, , := internalConfig.ResolveUseDualStackEndpoint(context.Background(), .ConfigSources)
if != nil {
return
}
if {
.EndpointOptions.UseDualStackEndpoint =
}
return nil
}
func ( aws.Config, *Options) error {
if len(.ConfigSources) == 0 {
return nil
}
, , := internalConfig.ResolveUseFIPSEndpoint(context.Background(), .ConfigSources)
if != nil {
return
}
if {
.EndpointOptions.UseFIPSEndpoint =
}
return nil
}
func ( *Options) {
if .Credentials == nil {
return
}
if , := .Credentials.(v4a.CredentialsProvider); {
return
}
if aws.IsCredentialsProvider(.Credentials, (*aws.AnonymousCredentials)(nil)) {
return
}
.Credentials = &v4a.SymmetricCredentialAdaptor{SymmetricProvider: .Credentials}
}
func ( *middleware.Stack, Options) error {
:= s3cust.NewSignHTTPRequestMiddleware(s3cust.SignHTTPRequestMiddlewareOptions{
CredentialsProvider: .Credentials,
V4Signer: .HTTPSignerV4,
V4aSigner: .httpSignerV4a,
LogSigning: .ClientLogMode.IsSigning(),
})
return s3cust.RegisterSigningMiddleware(, )
}
type httpSignerV4a interface {
SignHTTP(ctx context.Context, credentials v4a.Credentials, r *http.Request, payloadHash,
service string, regionSet []string, signingTime time.Time,
optFns ...func(*v4a.SignerOptions)) error
}
func ( *Options) {
if .httpSignerV4a != nil {
return
}
.httpSignerV4a = newDefaultV4aSigner(*)
}
func ( Options) *v4a.Signer {
return v4a.NewSigner(func( *v4a.SignerOptions) {
.Logger = .Logger
.LogSigning = .ClientLogMode.IsSigning()
.DisableURIPathEscaping = true
})
}
func ( *middleware.Stack) error {
return s3shared.AddMetadataRetrieverMiddleware()
}
type ComputedInputChecksumsMetadata struct {
ComputedChecksums map[string]string
}
func ( middleware.Metadata) (ComputedInputChecksumsMetadata, bool) {
, := internalChecksum.GetComputedInputChecksums()
if ! {
return ComputedInputChecksumsMetadata{}, false
}
return ComputedInputChecksumsMetadata{
ComputedChecksums: ,
}, true
}
type ChecksumValidationMetadata struct {
AlgorithmsUsed []string
}
func ( middleware.Metadata) (ChecksumValidationMetadata, bool) {
, := internalChecksum.GetOutputValidationAlgorithmsUsed()
if ! {
return ChecksumValidationMetadata{}, false
}
return ChecksumValidationMetadata{
AlgorithmsUsed: append(make([]string, 0, len()), ...),
}, true
}
func ( interface{}) (*string, bool) {
return nil, false
}
func ( *middleware.Stack) error {
return s3shared.AddResponseErrorMiddleware()
}
func ( *middleware.Stack) error {
return acceptencodingcust.AddAcceptEncodingGzip(, acceptencodingcust.AddAcceptEncodingGzipOptions{})
}
type ResponseError interface {
error
ServiceHostID() string
ServiceRequestID() string
}
var _ ResponseError = (*s3shared.ResponseError)(nil)
func ( middleware.Metadata) (string, bool) {
return s3shared.GetHostIDMetadata()
}
type HTTPPresignerV4 interface {
PresignHTTP(
ctx context.Context, credentials aws.Credentials, r *http.Request,
payloadHash string, service string, region string, signingTime time.Time,
optFns ...func(*v4.SignerOptions),
) (url string, signedHeader http.Header, err error)
}
type httpPresignerV4a interface {
PresignHTTP(
ctx context.Context, credentials v4a.Credentials, r *http.Request,
payloadHash string, service string, regionSet []string, signingTime time.Time,
optFns ...func(*v4a.SignerOptions),
) (url string, signedHeader http.Header, err error)
}
type PresignOptions struct {
ClientOptions []func(*Options)
Presigner HTTPPresignerV4
Expires time.Duration
presignerV4a httpPresignerV4a
}
func ( PresignOptions) () PresignOptions {
:= make([]func(*Options), len(.ClientOptions))
copy(, .ClientOptions)
.ClientOptions =
return
}
func ( ...func(*Options)) func(*PresignOptions) {
return withPresignClientFromClientOptions().options
}
type withPresignClientFromClientOptions []func(*Options)
func ( withPresignClientFromClientOptions) ( *PresignOptions) {
.ClientOptions = append(.ClientOptions, ...)
}
func ( time.Duration) func(*PresignOptions) {
return withPresignExpires().options
}
type withPresignExpires time.Duration
func ( withPresignExpires) ( *PresignOptions) {
.Expires = time.Duration()
}
type PresignClient struct {
client *Client
options PresignOptions
}
func ( *Client, ...func(*PresignOptions)) *PresignClient {
var PresignOptions
for , := range {
(&)
}
if len(.ClientOptions) != 0 {
= New(.options, .ClientOptions...)
}
if .Presigner == nil {
.Presigner = newDefaultV4Signer(.options)
}
if .presignerV4a == nil {
.presignerV4a = newDefaultV4aSigner(.options)
}
return &PresignClient{
client: ,
options: ,
}
}
func ( *Options) {
.HTTPClient = smithyhttp.NopClient{}
}
type presignConverter PresignOptions
func ( presignConverter) ( *middleware.Stack, Options) ( error) {
.Finalize.Clear()
.Deserialize.Clear()
.Build.Remove((*awsmiddleware.ClientRequestID)(nil).ID())
.Build.Remove("UserAgent")
:= v4.NewPresignHTTPRequestMiddleware(v4.PresignHTTPRequestMiddlewareOptions{
CredentialsProvider: .Credentials,
Presigner: .Presigner,
LogSigning: .ClientLogMode.IsSigning(),
})
= .Finalize.Add(, middleware.After)
if != nil {
return
}
if = smithyhttp.AddNoPayloadDefaultContentTypeRemover(); != nil {
return
}
:= s3cust.NewPresignHTTPRequestMiddleware(s3cust.PresignHTTPRequestMiddlewareOptions{
CredentialsProvider: .Credentials,
V4Presigner: .Presigner,
V4aPresigner: .presignerV4a,
LogSigning: .ClientLogMode.IsSigning(),
})
= s3cust.RegisterPreSigningMiddleware(, )
if != nil {
return
}
if .Expires < 0 {
return fmt.Errorf("presign URL duration must be 0 or greater, %v", .Expires)
}
= .Build.Add(&s3cust.AddExpiresOnPresignedURL{Expires: .Expires}, middleware.After)
if != nil {
return
}
= presignedurlcust.AddAsIsPresigingMiddleware()
if != nil {
return
}
return nil
}
func ( *middleware.Stack, Options) error {
return .Deserialize.Add(&smithyhttp.RequestResponseLogger{
LogRequest: .ClientLogMode.IsRequest(),
LogRequestWithBody: .ClientLogMode.IsRequestWithBody(),
LogResponse: .ClientLogMode.IsResponse(),
LogResponseWithBody: .ClientLogMode.IsResponseWithBody(),
}, middleware.After)
}