/******************************************************************************* * Copyright 2008-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"). You may not use * this file except in compliance with the License. A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR * CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. * ***************************************************************************** * __ _ _ ___ * ( )( \/\/ )/ __) * /__\ \ / \__ \ * (_)(_) \/\/ (___/ * * AWS SDK for .NET * */ using Amazon.Internal; using Amazon.Runtime.Internal.Auth; using System; using System.Collections.Generic; using System.Globalization; #if UNITY using UnityEngine; using Amazon.Runtime.Internal; #endif namespace Amazon { /// /// This class contains region information used to lazily compute the service endpoints. The static constants representing the /// regions can be used while constructing the AWS client instead of looking up the exact endpoint URL. /// public partial class RegionEndpoint { #region Statics private static Dictionary _hashBySystemName = new Dictionary(StringComparer.OrdinalIgnoreCase); /// /// The US East (Virginia) endpoint. /// public static readonly RegionEndpoint USEast1 = GetEndpoint("us-east-1", "US East (Virginia)"); /// /// The US East (Virginia) regional endpoint. /// private static readonly RegionEndpoint USEast1Regional = GetEndpoint("us-east-1-regional", "US East (Virginia) regional"); /// /// The US East (Ohio) endpoint. /// public static readonly RegionEndpoint USEast2 = GetEndpoint("us-east-2", "US East (Ohio)"); /// /// The US West (N. California) endpoint. /// public static readonly RegionEndpoint USWest1 = GetEndpoint("us-west-1", "US West (N. California)"); /// /// The US West (Oregon) endpoint. /// public static readonly RegionEndpoint USWest2 = GetEndpoint("us-west-2", "US West (Oregon)"); /// /// The EU North (Stockholm) endpoint. /// public static readonly RegionEndpoint EUNorth1 = GetEndpoint("eu-north-1", "EU North (Stockholm)"); /// /// The EU West (Ireland) endpoint. /// public static readonly RegionEndpoint EUWest1 = GetEndpoint("eu-west-1", "EU West (Ireland)"); /// /// The EU West (London) endpoint. /// public static readonly RegionEndpoint EUWest2 = GetEndpoint("eu-west-2", "EU West (London)"); /// /// The EU West (Paris) endpoint. /// public static readonly RegionEndpoint EUWest3 = GetEndpoint("eu-west-3", "EU West (Paris)"); /// /// The EU Central (Frankfurt) endpoint. /// public static readonly RegionEndpoint EUCentral1 = GetEndpoint("eu-central-1", "EU Central (Frankfurt)"); /// /// The Asia Pacific (Hong Kong) endpoint. /// public static readonly RegionEndpoint APEast1 = GetEndpoint("ap-east-1", "Asia Pacific (Hong Kong)"); /// /// The Asia Pacific (Tokyo) endpoint. /// public static readonly RegionEndpoint APNortheast1 = GetEndpoint("ap-northeast-1", "Asia Pacific (Tokyo)"); /// /// The Asia Pacific (Seoul) endpoint. /// public static readonly RegionEndpoint APNortheast2 = GetEndpoint("ap-northeast-2", "Asia Pacific (Seoul)"); /// /// The Asia Pacific (Osaka-Local) endpoint. /// public static readonly RegionEndpoint APNortheast3 = GetEndpoint("ap-northeast-3", "Asia Pacific (Osaka-Local)"); /// /// The Asia Pacific (Mumbai) endpoint. /// public static readonly RegionEndpoint APSouth1 = GetEndpoint("ap-south-1", "Asia Pacific (Mumbai)"); /// /// The Asia Pacific (Singapore) endpoint. /// public static readonly RegionEndpoint APSoutheast1 = GetEndpoint("ap-southeast-1", "Asia Pacific (Singapore)"); /// /// The Asia Pacific (Sydney) endpoint. /// public static readonly RegionEndpoint APSoutheast2 = GetEndpoint("ap-southeast-2", "Asia Pacific (Sydney)"); /// /// The South America (Sao Paulo) endpoint. /// public static readonly RegionEndpoint SAEast1 = GetEndpoint("sa-east-1", "South America (Sao Paulo)"); /// /// The US GovCloud East (Virginia) endpoint. /// public static readonly RegionEndpoint USGovCloudEast1 = GetEndpoint("us-gov-east-1", "US GovCloud East (Virginia)"); /// /// The US GovCloud West (Oregon) endpoint. /// public static readonly RegionEndpoint USGovCloudWest1 = GetEndpoint("us-gov-west-1", "US GovCloud West (Oregon)"); /// /// The China (Beijing) endpoint. /// public static readonly RegionEndpoint CNNorth1 = GetEndpoint("cn-north-1", "China (Beijing)"); /// /// The China (Ningxia) endpoint. /// public static readonly RegionEndpoint CNNorthWest1 = GetEndpoint("cn-northwest-1", "China (Ningxia)"); /// /// The Canada (Central) endpoint. /// public static readonly RegionEndpoint CACentral1 = GetEndpoint("ca-central-1", "Canada (Central)"); /// /// The Middle East (Bahrain) endpoint. /// public static readonly RegionEndpoint MESouth1 = GetEndpoint("me-south-1", "Middle East (Bahrain)"); /// /// Represents the endpoint overridding rules in the endpoints.json /// Is used to map private region (ie us-east-1-regional) to public regions (us-east-1) /// For signing purposes. /// private static Dictionary _hashRegionEndpointOverride = new Dictionary() { { USEast1Regional, USEast1 } }; /// /// Enumerate through all the regions. /// public static IEnumerable EnumerableAllRegions { get { List list = new List(); foreach (IRegionEndpoint endpoint in RegionEndpointProvider.AllRegionEndpoints) { list.Add(GetEndpoint(endpoint.RegionName, endpoint.DisplayName)); } return list; } } /// /// Gets the region based on its system name like "us-west-1" /// /// The system name of the service like "us-west-1" /// public static RegionEndpoint GetBySystemName(string systemName) { return GetEndpoint(systemName, null); } /// /// Gets the region endpoint override if exists /// /// The region endpoint to find the possible override for /// public static RegionEndpoint GetRegionEndpointOverride(RegionEndpoint regionEndpoint) { return _hashRegionEndpointOverride.ContainsKey(regionEndpoint) ? _hashRegionEndpointOverride[regionEndpoint] : null; } private static RegionEndpoint GetEndpoint(string systemName, string displayName) { RegionEndpoint regionEndpoint = null; if (displayName == null) { lock (_hashBySystemName) { if (_hashBySystemName.TryGetValue(systemName, out regionEndpoint)) return regionEndpoint; } // GetRegionEndpoint will always return a non-null value. If the the region(systemName) is unknown, // the providers will create a fallback instance that will generate an endpoint to the best // of its knowledge. displayName = RegionEndpointProvider.GetRegionEndpoint(systemName).DisplayName; } lock (_hashBySystemName) { if (_hashBySystemName.TryGetValue(systemName, out regionEndpoint)) return regionEndpoint; regionEndpoint = new RegionEndpoint(systemName, displayName); _hashBySystemName.Add(regionEndpoint.SystemName, regionEndpoint); } return regionEndpoint; } private static IRegionEndpointProvider _regionEndpointProvider; private static IRegionEndpointProvider RegionEndpointProvider { get { if (_regionEndpointProvider == null) { // If the existing customer provided the endpoints.json file via // , it's in v2 format. We we will create // a v2 provider which does a fall through during LoadEndpointDefinitions() // and loads from the override file provided by the user. // // Else, we are loading from the assembly resource. In which case we use the // latest provider. // // It's actually a bug that _regionEndpointProvider is a static member variable // since the IEndpointProvider should respect the AWSConfigs.EndpointDefinition // _at_ the time of the service client instantiation. However, since this is // the existing behavior with v2 endpoint file format, we will preserve this behavior as is. if (!string.IsNullOrEmpty(AWSConfigs.EndpointDefinition)) { _regionEndpointProvider = new RegionEndpointProviderV2(); } else { _regionEndpointProvider = new RegionEndpointProviderV3(); } } return _regionEndpointProvider; } } #endregion private RegionEndpoint(string systemName, string displayName) { this.SystemName = systemName; this.DisplayName = displayName; } /// /// Gets the system name of a region. /// public string SystemName { get; private set; } /// /// Gets the display name of a region. /// public string DisplayName { get; private set; } /// /// Gets the partition name the region is in. For example for us-east-1 the partition name is aws. For cn-northwest-1 the partition name is aws-cn. /// public string PartitionName { get { var regionEndpointV3 = this.InternedRegionEndpoint as RegionEndpointV3; return regionEndpointV3?.PartitionName; } } /// /// Gets the dns suffix for the region endpoints in a partition. For example the aws partition's suffix is amazonaws.com. The aws-cn partition's suffix is amazonaws.com.cn. /// public string PartitionDnsSuffix { get { var regionEndpointV3 = this.InternedRegionEndpoint as RegionEndpointV3; return regionEndpointV3?.PartitionDnsSuffix; } } private IRegionEndpoint InternedRegionEndpoint { get { return RegionEndpointProvider.GetRegionEndpoint(SystemName); } } /// /// Gets the endpoint for a service in a region. /// /// /// The services system name. Service system names can be obtained from the /// RegionEndpointServiceName member of the ClientConfig-derived class for the service. /// /// /// For forwards compatibility, if the service being requested for isn't known in the region, this method /// will generate an endpoint using the AWS endpoint heuristics. In this case, it is not guaranteed the /// endpoint will point to a valid service endpoint. /// /// public Endpoint GetEndpointForService(string serviceName) { return GetEndpointForService(serviceName, false); } /// /// Gets the endpoint for a service in a region, optionally selecting a dualstack compatible endpoint. /// /// /// The services system name. Service system names can be obtained from the /// RegionEndpointServiceName member of the ClientConfig-derived class for the service. /// /// /// If true a dualstack endpoint is returned. It is the user's responsibility to verify that the given service /// supports a dualstack endpoint for the region. /// /// /// For forwards compatibility, if the service being requested for isn't known in the region, this method /// will generate an endpoint using the AWS endpoint heuristics. In this case, it is not guaranteed the /// endpoint will point to a valid service endpoint. /// /// public Endpoint GetEndpointForService(string serviceName, bool dualStack) { return InternedRegionEndpoint.GetEndpointForService(serviceName, dualStack); } public override string ToString() { return string.Format(CultureInfo.InvariantCulture, "{0} ({1})", this.DisplayName, this.SystemName); } /// /// This class defines an endpoints hostname and which protocols it supports. /// public class Endpoint { internal Endpoint(string hostname, string authregion, string signatureVersionOverride) { this.Hostname = hostname; this.AuthRegion = authregion; this.SignatureVersionOverride = signatureVersionOverride; } /// /// Gets the hostname for the service. /// public string Hostname { get; private set; } /// /// The authentication region to be used in request signing. /// public string AuthRegion { get; private set; } public override string ToString() { return this.Hostname; } /// /// This property is only set for S3 endpoints. For all other services this property returns null. /// For S3 endpoints, if the endpoint supports signature version 2 this property will be "2", otherwise it will be "4". /// public string SignatureVersionOverride { get; private set; } } } }