package endpoints
import (
)
type DefaultKey struct {
Variant EndpointVariant
ServiceVariant ServiceVariant
}
type EndpointKey struct {
Region string
Variant EndpointVariant
ServiceVariant ServiceVariant
}
type EndpointVariant uint64
const (
FIPSVariant EndpointVariant = 1 << (64 - 1 - iota)
DualStackVariant
)
type ServiceVariant uint64
const (
defaultProtocol = "https"
defaultSigner = "v4"
)
var (
protocolPriority = []string{"https", "http"}
signerPriority = []string{"v4", "s3v4"}
)
type Options struct {
Logger logging.Logger
LogDeprecated bool
ResolvedRegion string
DisableHTTPS bool
UseDualStackEndpoint aws.DualStackEndpointState
UseFIPSEndpoint aws.FIPSEndpointState
ServiceVariant ServiceVariant
}
func ( Options) () ( EndpointVariant) {
if .UseDualStackEndpoint == aws.DualStackEndpointStateEnabled {
|= DualStackVariant
}
if .UseFIPSEndpoint == aws.FIPSEndpointStateEnabled {
|= FIPSVariant
}
return
}
type Partitions []Partition
func ( Partitions) ( string, Options) (aws.Endpoint, error) {
if len() == 0 {
return aws.Endpoint{}, fmt.Errorf("no partitions found")
}
if .Logger == nil {
.Logger = logging.Nop{}
}
if len(.ResolvedRegion) > 0 {
= .ResolvedRegion
}
for := 0; < len(); ++ {
if ![].canResolveEndpoint(, ) {
continue
}
return [].ResolveEndpoint(, )
}
return [0].ResolveEndpoint(, )
}
type Partition struct {
ID string
RegionRegex *regexp.Regexp
PartitionEndpoint string
IsRegionalized bool
Defaults map[DefaultKey]Endpoint
Endpoints Endpoints
}
func ( Partition) ( string, Options) bool {
, := .Endpoints[EndpointKey{
Region: ,
Variant: .GetEndpointVariant(),
}]
return || .RegionRegex.MatchString()
}
func ( Partition) ( string, Options) ( aws.Endpoint, error) {
if len() == 0 && len(.PartitionEndpoint) != 0 {
= .PartitionEndpoint
}
:= .Endpoints
:= .GetEndpointVariant()
:= .ServiceVariant
:= .Defaults[DefaultKey{
Variant: ,
ServiceVariant: ,
}]
return .endpointForRegion(, , , ).resolve(.ID, , , )
}
func ( Partition) ( string, EndpointVariant, ServiceVariant, Endpoints) Endpoint {
:= EndpointKey{
Region: ,
Variant: ,
}
if , := []; {
return
}
if !.IsRegionalized {
return [EndpointKey{
Region: .PartitionEndpoint,
Variant: ,
ServiceVariant: ,
}]
}
return Endpoint{}
}
type Endpoints map[EndpointKey]Endpoint
type CredentialScope struct {
Region string
Service string
}
type Endpoint struct {
Unresolveable aws.Ternary
Hostname string
Protocols []string
CredentialScope CredentialScope
SignatureVersions []string
Deprecated aws.Ternary
}
func ( Endpoint) () bool {
switch {
case .Unresolveable != aws.UnknownTernary:
return false
case len(.Hostname) != 0:
return false
case len(.Protocols) != 0:
return false
case .CredentialScope != (CredentialScope{}):
return false
case len(.SignatureVersions) != 0:
return false
}
return true
}
func ( Endpoint) (, string, Endpoint, Options) (aws.Endpoint, error) {
var Endpoint
.mergeIn()
.mergeIn()
=
if .IsZero() {
return aws.Endpoint{}, fmt.Errorf("unable to resolve endpoint for region: %v", )
}
var string
if .Unresolveable != aws.TrueTernary {
:= strings.Replace(.Hostname, "{region}", , 1)
:= getEndpointScheme(.Protocols, .DisableHTTPS)
= + "://" +
}
:= .CredentialScope.Region
if len() == 0 {
=
}
:= .CredentialScope.Service
if .Deprecated == aws.TrueTernary && .LogDeprecated {
.Logger.Logf(logging.Warn, "endpoint identifier %q, url %q marked as deprecated", , )
}
return aws.Endpoint{
URL: ,
PartitionID: ,
SigningRegion: ,
SigningName: ,
SigningMethod: getByPriority(.SignatureVersions, signerPriority, defaultSigner),
}, nil
}
func ( *Endpoint) ( Endpoint) {
if .Unresolveable != aws.UnknownTernary {
.Unresolveable = .Unresolveable
}
if len(.Hostname) > 0 {
.Hostname = .Hostname
}
if len(.Protocols) > 0 {
.Protocols = .Protocols
}
if len(.CredentialScope.Region) > 0 {
.CredentialScope.Region = .CredentialScope.Region
}
if len(.CredentialScope.Service) > 0 {
.CredentialScope.Service = .CredentialScope.Service
}
if len(.SignatureVersions) > 0 {
.SignatureVersions = .SignatureVersions
}
if .Deprecated != aws.UnknownTernary {
.Deprecated = .Deprecated
}
}
func ( []string, bool) string {
if {
return "http"
}
return getByPriority(, protocolPriority, defaultProtocol)
}
func ( []string, []string, string) string {
if len() == 0 {
return
}
for := 0; < len(); ++ {
for := 0; < len(); ++ {
if [] == [] {
return []
}
}
}
return [0]
}