github.com/aavshr/aws-sdk-go@v1.41.3/service/s3control/endpoint_builder.go (about)

     1  package s3control
     2  
     3  import (
     4  	"net/url"
     5  	"strings"
     6  
     7  	"github.com/aavshr/aws-sdk-go/aws"
     8  	"github.com/aavshr/aws-sdk-go/aws/awserr"
     9  	"github.com/aavshr/aws-sdk-go/aws/endpoints"
    10  	"github.com/aavshr/aws-sdk-go/aws/request"
    11  	"github.com/aavshr/aws-sdk-go/internal/s3shared"
    12  	"github.com/aavshr/aws-sdk-go/internal/s3shared/arn"
    13  	"github.com/aavshr/aws-sdk-go/private/protocol"
    14  )
    15  
    16  const (
    17  	accessPointPrefixLabel = "accesspoint"
    18  	accountIDPrefixLabel   = "accountID"
    19  
    20  	outpostPrefixLabel = "outpost"
    21  )
    22  
    23  // hasCustomEndpoint returns true if endpoint is a custom endpoint
    24  func hasCustomEndpoint(r *request.Request) bool {
    25  	return len(aws.StringValue(r.Config.Endpoint)) > 0
    26  }
    27  
    28  // outpostAccessPointEndpointBuilder represents the endpoint builder for outpost access point arn.
    29  type outpostAccessPointEndpointBuilder arn.OutpostAccessPointARN
    30  
    31  // build builds an endpoint corresponding to the outpost access point arn.
    32  //
    33  // For building an endpoint from outpost access point arn, format used is:
    34  // - Outpost access point endpoint format : s3-outposts.{region}.{dnsSuffix}
    35  // - example : s3-outposts.us-west-2.amazonaws.com
    36  //
    37  // Outpost AccessPoint Endpoint request are signed using "s3-outposts" as signing name.
    38  //
    39  func (o outpostAccessPointEndpointBuilder) build(req *request.Request) error {
    40  	resolveRegion := o.Region
    41  	resolveService := o.Service
    42  
    43  	endpointsID := resolveService
    44  	if resolveService == "s3-outposts" {
    45  		endpointsID = "s3"
    46  	}
    47  
    48  	endpoint, err := resolveRegionalEndpoint(req, resolveRegion, endpointsID)
    49  	if err != nil {
    50  		return s3shared.NewFailedToResolveEndpointError(o,
    51  			req.ClientInfo.PartitionID, resolveRegion, err)
    52  	}
    53  
    54  	endpoint.URL = endpoints.AddScheme(endpoint.URL, aws.BoolValue(req.Config.DisableSSL))
    55  
    56  	if !hasCustomEndpoint(req) {
    57  		if err = updateRequestEndpoint(req, endpoint.URL); err != nil {
    58  			return err
    59  		}
    60  		// add url host as s3-outposts
    61  		cfgHost := req.HTTPRequest.URL.Host
    62  		if strings.HasPrefix(cfgHost, endpointsID) {
    63  			req.HTTPRequest.URL.Host = resolveService + cfgHost[len(endpointsID):]
    64  		}
    65  	}
    66  
    67  	// set the signing region, name to resolved names from ARN
    68  	redirectSigner(req, resolveService, resolveRegion)
    69  
    70  	err = protocol.ValidateEndpointHost(req.Operation.Name, req.HTTPRequest.URL.Host)
    71  	if err != nil {
    72  		return s3shared.NewInvalidARNError(o, err)
    73  	}
    74  
    75  	return nil
    76  }
    77  
    78  func (o outpostAccessPointEndpointBuilder) hostPrefixLabelValues() map[string]string {
    79  	return map[string]string{
    80  		accessPointPrefixLabel: o.AccessPointName,
    81  		accountIDPrefixLabel:   o.AccountID,
    82  		outpostPrefixLabel:     o.OutpostID,
    83  	}
    84  }
    85  
    86  // outpostBucketResourceEndpointBuilder represents the endpoint builder for outpost bucket resource arn
    87  type outpostBucketResourceEndpointBuilder arn.OutpostBucketARN
    88  
    89  // build builds the endpoint for corresponding outpost bucket arn
    90  //
    91  // For building an endpoint from outpost bucket arn, format used is:
    92  // - Outpost bucket arn endpoint format : s3-outposts.{region}.{dnsSuffix}
    93  // - example : s3-outposts.us-west-2.amazonaws.com
    94  //
    95  // Outpost bucket arn endpoint request are signed using "s3-outposts" as signing name
    96  //
    97  func (o outpostBucketResourceEndpointBuilder) build(req *request.Request) error {
    98  	resolveService := arn.OutpostBucketARN(o).Service
    99  	resolveRegion := arn.OutpostBucketARN(o).Region
   100  	cfgRegion := aws.StringValue(req.Config.Region)
   101  
   102  	// Outpost bucket resource uses `s3-control` as serviceEndpointLabel
   103  	endpointsID := "s3-control"
   104  
   105  	endpoint, err := resolveRegionalEndpoint(req, resolveRegion, endpointsID)
   106  	if err != nil {
   107  		return s3shared.NewFailedToResolveEndpointError(arn.OutpostBucketARN(o),
   108  			req.ClientInfo.PartitionID, cfgRegion, err)
   109  	}
   110  
   111  	endpoint.URL = endpoints.AddScheme(endpoint.URL, aws.BoolValue(req.Config.DisableSSL))
   112  
   113  	if !hasCustomEndpoint(req) {
   114  		if err = updateRequestEndpoint(req, endpoint.URL); err != nil {
   115  			return err
   116  		}
   117  
   118  		// add url host as s3-outposts
   119  		cfgHost := req.HTTPRequest.URL.Host
   120  		if strings.HasPrefix(cfgHost, endpointsID) {
   121  			req.HTTPRequest.URL.Host = resolveService + cfgHost[len(endpointsID):]
   122  		}
   123  	}
   124  
   125  	// signer redirection
   126  	redirectSigner(req, resolveService, resolveRegion)
   127  
   128  	err = protocol.ValidateEndpointHost(req.Operation.Name, req.HTTPRequest.URL.Host)
   129  	if err != nil {
   130  		return s3shared.NewInvalidARNError(arn.OutpostBucketARN(o), err)
   131  	}
   132  	return nil
   133  }
   134  
   135  func resolveRegionalEndpoint(r *request.Request, region string, endpointsID string) (endpoints.ResolvedEndpoint, error) {
   136  	return r.Config.EndpointResolver.EndpointFor(endpointsID, region, func(opts *endpoints.Options) {
   137  		opts.DisableSSL = aws.BoolValue(r.Config.DisableSSL)
   138  		opts.UseDualStack = aws.BoolValue(r.Config.UseDualStack)
   139  		opts.S3UsEast1RegionalEndpoint = endpoints.RegionalS3UsEast1Endpoint
   140  	})
   141  }
   142  
   143  func updateRequestEndpoint(r *request.Request, endpoint string) (err error) {
   144  	r.HTTPRequest.URL, err = url.Parse(endpoint + r.Operation.HTTPPath)
   145  	if err != nil {
   146  		return awserr.New(request.ErrCodeSerialization,
   147  			"failed to parse endpoint URL", err)
   148  	}
   149  
   150  	return nil
   151  }
   152  
   153  // redirectSigner sets signing name, signing region for a request
   154  func redirectSigner(req *request.Request, signingName string, signingRegion string) {
   155  	req.ClientInfo.SigningName = signingName
   156  	req.ClientInfo.SigningRegion = signingRegion
   157  }