package customizations
import (
awsmiddleware
internalendpoints
smithyhttp
)
type EndpointResolver interface {
ResolveEndpoint(region string, options EndpointResolverOptions) (aws.Endpoint, error)
}
type EndpointResolverOptions = internalendpoints.Options
type UpdateEndpointParameterAccessor struct {
GetBucketFromInput func(interface{}) (*string, bool)
}
type UpdateEndpointOptions struct {
Accessor UpdateEndpointParameterAccessor
UsePathStyle bool
UseAccelerate bool
SupportsAccelerate bool
UseARNRegion bool
TargetS3ObjectLambda bool
EndpointResolver EndpointResolver
EndpointResolverOptions EndpointResolverOptions
DisableMultiRegionAccessPoints bool
}
func ( *middleware.Stack, UpdateEndpointOptions) ( error) {
const = "OperationSerializer"
= .Initialize.Add(&s3shared.ARNLookup{
GetARNValue: .Accessor.GetBucketFromInput,
}, middleware.Before)
if != nil {
return
}
= .Serialize.Insert(&processARNResource{
UseARNRegion: .UseARNRegion,
UseAccelerate: .UseAccelerate,
EndpointResolver: .EndpointResolver,
EndpointResolverOptions: .EndpointResolverOptions,
DisableMultiRegionAccessPoints: .DisableMultiRegionAccessPoints,
}, , middleware.Before)
if != nil {
return
}
= .Serialize.Insert(&s3ObjectLambdaEndpoint{
UseEndpoint: .TargetS3ObjectLambda,
UseAccelerate: .UseAccelerate,
EndpointResolver: .EndpointResolver,
EndpointResolverOptions: .EndpointResolverOptions,
}, , middleware.Before)
if != nil {
return
}
= .Serialize.Insert(&removeBucketFromPathMiddleware{}, , middleware.After)
if != nil {
return
}
= .Serialize.Insert(&updateEndpoint{
usePathStyle: .UsePathStyle,
getBucketFromInput: .Accessor.GetBucketFromInput,
useAccelerate: .UseAccelerate,
supportsAccelerate: .SupportsAccelerate,
}, , middleware.After)
if != nil {
return
}
return
}
type updateEndpoint struct {
usePathStyle bool
getBucketFromInput func(interface{}) (*string, bool)
useAccelerate bool
supportsAccelerate bool
}
func (*updateEndpoint) () string {
return "S3:UpdateEndpoint"
}
func ( *updateEndpoint) (
context.Context, middleware.SerializeInput, middleware.SerializeHandler,
) (
middleware.SerializeOutput, middleware.Metadata, error,
) {
if , := s3shared.GetARNResourceFromContext(); {
return .HandleSerialize(, )
}
if smithyhttp.GetHostnameImmutable() {
return .HandleSerialize(, )
}
, := .Request.(*smithyhttp.Request)
if ! {
return , , fmt.Errorf("unknown request type %T", )
}
if .useAccelerate && !.supportsAccelerate {
log.Println("Transfer acceleration is not supported for the operation, ignoring UseAccelerate.")
.useAccelerate = false
}
if .useAccelerate && .usePathStyle {
log.Println("UseAccelerate is not compatible with UsePathStyle, ignoring UsePathStyle.")
.usePathStyle = false
}
if .getBucketFromInput != nil {
, := .getBucketFromInput(.Parameters)
if && != nil {
:= awsmiddleware.GetRegion()
if := .updateEndpointFromConfig(, *, ); != nil {
return , ,
}
}
}
return .HandleSerialize(, )
}
func ( updateEndpoint) ( *smithyhttp.Request, string, string) error {
if .usePathStyle {
return nil
}
if !hostCompatibleBucketName(.URL, ) {
var error
if .useAccelerate {
= fmt.Errorf("bucket name %s is not compatible with S3", )
}
return
}
if .useAccelerate {
:= strings.Split(.URL.Host, ".")
if len() < 3 {
return fmt.Errorf("unable to update endpoint host for S3 accelerate, hostname invalid, %s", .URL.Host)
}
if [0] == "s3" || strings.HasPrefix([0], "s3-") {
[0] = "s3-accelerate"
}
for := 1; +1 < len(); ++ {
if strings.EqualFold([], ) {
= append([:], [+1:]...)
break
}
}
.URL.Host = strings.Join(, ".")
}
moveBucketNameToHost(.URL, )
return nil
}
func ( *url.URL, string) {
.Host = + "." + .Host
removeBucketFromPath(, )
}
func ( *url.URL, string) {
if strings.HasPrefix(.Path, "/"+) {
.Path = strings.Replace(.Path, "/"+, "", 1)
.RawPath = strings.Replace(.RawPath, "/"+httpbinding.EscapePath(, true), "", 1)
}
if .Path == "" {
.Path = "/"
}
if .RawPath == "" {
.RawPath = "/"
}
}
func ( *url.URL, string) bool {
if .Scheme == "https" && strings.Contains(, ".") {
return false
}
return dnsCompatibleBucketName()
}
func ( string) bool {
if strings.Contains(, "..") {
return false
}
if !(([0] > 96 && [0] < 123) || ([0] > 47 && [0] < 58)) {
return false
}
for , := range [1:] {
if !(( > 96 && < 123) || ( > 47 && < 58) || == 46 || == 45) {
return false
}
}
:= strings.SplitN(, ".", -1)
if len() == 4 {
for , := range {
if !(( > 47 && < 58) || == 46) {
return true
}
}
return false
}
return true
}