diff --git a/Duplicati/Library/Backend/S3/S3Backend.cs b/Duplicati/Library/Backend/S3/S3Backend.cs index 833192262..90e2bdecd 100644 --- a/Duplicati/Library/Backend/S3/S3Backend.cs +++ b/Duplicati/Library/Backend/S3/S3Backend.cs @@ -17,7 +17,7 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // #endregion -using Duplicati.Library.Common.IO; +using Duplicati.Library.Common.IO; using Duplicati.Library.Interface; using System; using System.Collections.Generic; @@ -41,90 +41,96 @@ namespace Duplicati.Library.Backend public const string LOCATION_OPTION = "s3-location-constraint"; public const string SSL_OPTION = "use-ssl"; - public static readonly KeyValuePair[] KNOWN_S3_PROVIDERS = new KeyValuePair[] { - new KeyValuePair("Amazon S3", "s3.amazonaws.com"), - new KeyValuePair("Hosteurope", "cs.hosteurope.de"), - new KeyValuePair("Dunkel", "dcs.dunkel.de"), - new KeyValuePair("DreamHost", "objects.dreamhost.com"), - new KeyValuePair("dinCloud - Chicago", "d3-ord.dincloud.com"), - new KeyValuePair("dinCloud - Los Angeles", "d3-lax.dincloud.com"), - new KeyValuePair("IBM COS (S3) Public US", "s3-api.us-geo.objectstorage.softlayer.net"), - new KeyValuePair("Wasabi Hot Storage", "s3.wasabisys.com"), - new KeyValuePair("Wasabi Hot Storage (US West)", "s3.us-west-1.wasabisys.com"), - new KeyValuePair("Wasabi Hot Storage (EU Central)", "s3.eu-central-1.wasabisys.com"), + public static readonly Dictionary KNOWN_S3_PROVIDERS = new Dictionary(StringComparer.OrdinalIgnoreCase) { + { "Amazon S3", "s3.amazonaws.com" }, + { "Hosteurope", "cs.hosteurope.de" }, + { "Dunkel", "dcs.dunkel.de" }, + { "DreamHost", "objects.dreamhost.com" }, + { "dinCloud - Chicago", "d3-ord.dincloud.com" }, + { "dinCloud - Los Angeles", "d3-lax.dincloud.com" }, + { "IBM COS (S3) Public US", "s3-api.us-geo.objectstorage.softlayer.net" }, + { "Wasabi Hot Storage", "s3.wasabisys.com" }, + { "Wasabi Hot Storage (US West)", "s3.us-west-1.wasabisys.com" }, + { "Wasabi Hot Storage (EU Central)", "s3.eu-central-1.wasabisys.com" }, }; //Updated list: http://docs.amazonwebservices.com/general/latest/gr/rande.html#s3_region - public static readonly KeyValuePair[] KNOWN_S3_LOCATIONS = new KeyValuePair[] { - new KeyValuePair("(default)", ""), - new KeyValuePair("Europe (EU)", "EU"), - new KeyValuePair("Europe (EU, Frankfurt)", "eu-central-1"), - new KeyValuePair("Europe (EU, Ireland)", "eu-west-1"), - new KeyValuePair("Europe (EU, London)", "eu-west-2"), - new KeyValuePair("Europe (EU, Paris)", "eu-west-3"), - new KeyValuePair("Europe (EU, Stockholm)", "eu-north-1"), - new KeyValuePair("US East (Northern Virginia)", "us-east-1"), - new KeyValuePair("US East (Ohio)", "us-east-2"), - new KeyValuePair("US West (Northern California)", "us-west-1"), - new KeyValuePair("US West (Oregon)", "us-west-2"), - new KeyValuePair("Canada (Central)", "ca-central-1"), - new KeyValuePair("Asia Pacific (Mumbai)", "ap-south-1"), - new KeyValuePair("Asia Pacific (Singapore)", "ap-southeast-1"), - new KeyValuePair("Asia Pacific (Sydney)", "ap-southeast-2"), - new KeyValuePair("Asia Pacific (Tokyo)", "ap-northeast-1"), - new KeyValuePair("Asia Pacific (Seoul)", "ap-northeast-2"), - new KeyValuePair("Asia Pacific (Osaka-Local)", "ap-northeast-3"), - new KeyValuePair("South America (São Paulo)", "sa-east-1"), - new KeyValuePair("China (Beijing)", "cn-north-1"), - new KeyValuePair("China (Ningxia)", "cn-northwest-1"), + public static readonly Dictionary KNOWN_S3_LOCATIONS = new Dictionary(StringComparer.OrdinalIgnoreCase){ + { "(default)", "" }, + { "Europe (EU)", "EU" }, + { "Europe (EU, Frankfurt)", "eu-central-1" }, + { "Europe (EU, Ireland)", "eu-west-1" }, + { "Europe (EU, London)", "eu-west-2" }, + { "Europe (EU, Paris)", "eu-west-3" }, + { "Europe (EU, Stockholm)", "eu-north-1" }, + { "US East (Northern Virginia)", "us-east-1" }, + { "US East (Ohio)", "us-east-2" }, + { "US West (Northern California)", "us-west-1" }, + { "US West (Oregon)", "us-west-2" }, + { "Canada (Central)", "ca-central-1" }, + { "Asia Pacific (Hong Kong)", "ap-east-1" }, + { "Asia Pacific (Mumbai)", "ap-south-1" }, + { "Asia Pacific (Singapore)", "ap-southeast-1" }, + { "Asia Pacific (Sydney)", "ap-southeast-2" }, + { "Asia Pacific (Tokyo)", "ap-northeast-1" }, + { "Asia Pacific (Seoul)", "ap-northeast-2" }, + { "Asia Pacific (Osaka-Local)", "ap-northeast-3" }, + { "South America (São Paulo)", "sa-east-1" }, + { "China (Beijing)", "cn-north-1" }, + { "China (Ningxia)", "cn-northwest-1" }, + { "Middle East (Bahrain)", "me-south-1" }, }; - public static readonly KeyValuePair[] DEFAULT_S3_LOCATION_BASED_HOSTS = new KeyValuePair[] { - new KeyValuePair("EU", "s3-eu-west-1.amazonaws.com"), - new KeyValuePair("ca-central-1", "s3-ca-central-1.amazonaws.com"), - new KeyValuePair("eu-west-1", "s3-eu-west-1.amazonaws.com"), - new KeyValuePair("eu-west-2", "s3-eu-west-2.amazonaws.com"), - new KeyValuePair("eu-west-3", "s3-eu-west-3.amazonaws.com"), - new KeyValuePair("eu-north-1", "s3-eu-north-1.amazonaws.com"), - new KeyValuePair("eu-central-1", "s3-eu-central-1.amazonaws.com"), - new KeyValuePair("us-east-1", "s3.amazonaws.com"), - new KeyValuePair("us-east-2", "s3.us-east-2.amazonaws.com"), - new KeyValuePair("us-west-1", "s3-us-west-1.amazonaws.com"), - new KeyValuePair("us-west-2", "s3-us-west-2.amazonaws.com"), - new KeyValuePair("ap-south-1", "s3-ap-south-1.amazonaws.com"), - new KeyValuePair("ap-southeast-1", "s3-ap-southeast-1.amazonaws.com"), - new KeyValuePair("ap-southeast-2", "s3-ap-southeast-2.amazonaws.com"), - new KeyValuePair("ap-northeast-1", "s3-ap-northeast-1.amazonaws.com"), - new KeyValuePair("ap-northeast-2", "s3-ap-northeast-2.amazonaws.com"), - new KeyValuePair("ap-northeast-3", "s3-ap-northeast-3.amazonaws.com"), - new KeyValuePair("sa-east-1", "s3-sa-east-1.amazonaws.com"), - new KeyValuePair("cn-north-1", "s3.cn-north-1.amazonaws.com.cn"), - new KeyValuePair("cn-northwest-1", "s3.cn-northwest-1.amazonaws.com.cn"), + public static readonly Dictionary DEFAULT_S3_LOCATION_BASED_HOSTS = new Dictionary(StringComparer.OrdinalIgnoreCase){ + { "EU", "s3.eu-west-1.amazonaws.com" }, + { "ca-central-1", "s3.ca-central-1.amazonaws.com" }, + { "eu-west-1", "s3.eu-west-1.amazonaws.com" }, + { "eu-west-2", "s3.eu-west-2.amazonaws.com" }, + { "eu-west-3", "s3.eu-west-3.amazonaws.com" }, + { "eu-north-1", "s3.eu-north-1.amazonaws.com" }, + { "eu-central-1", "s3.eu-central-1.amazonaws.com" }, + { "us-east-1", "s3.amazonaws.com" }, + { "us-east-2", "s3.us-east-2.amazonaws.com" }, + { "us-west-1", "s3.us-west-1.amazonaws.com" }, + { "us-west-2", "s3.us-west-2.amazonaws.com" }, + { "ap-east-1", "s3.ap-east-1.amazonaws.com" }, + { "ap-south-1", "s3.ap-south-1.amazonaws.com" }, + { "ap-southeast-1", "s3.ap-southeast-1.amazonaws.com" }, + { "ap-southeast-2", "s3.ap-southeast-2.amazonaws.com" }, + { "ap-northeast-1", "s3.ap-northeast-1.amazonaws.com" }, + { "ap-northeast-2", "s3.ap-northeast-2.amazonaws.com" }, + { "ap-northeast-3", "s3.ap-northeast-3.amazonaws.com" }, + { "sa-east-1", "s3.sa-east-1.amazonaws.com" }, + { "cn-north-1", "s3.cn-north-1.amazonaws.com.cn" }, + { "cn-northwest-1", "s3.cn-northwest-1.amazonaws.com.cn" }, + { "me-south-1", "s3.me-south-1.amazonaws.com.cn" }, }; - public static readonly KeyValuePair[] KNOWN_S3_STORAGE_CLASSES; + public static readonly Dictionary KNOWN_S3_STORAGE_CLASSES; static S3() { - var ns = new List> { - new KeyValuePair("(default)", ""), - new KeyValuePair("Standard", "STANDARD"), - new KeyValuePair("Infrequent Access (IA)", "STANDARD_IA"), - new KeyValuePair("Glacier", "GLACIER"), - new KeyValuePair("Reduced Redundancy Storage (RRS)", "REDUCED_REDUNDANCY"), + var ns = new Dictionary(StringComparer.OrdinalIgnoreCase) { + { "(default)", "" }, + { "Standard", "STANDARD" }, + { "Infrequent Access (IA)", "STANDARD_IA" }, + { "One Zone Infrequent Access (One Zone IA)", "ONEZONE_IA" }, + { "Glacier", "GLACIER" }, + { "Deep Archive", "DEEP_ARCHIVE" }, + { "Reduced Redundancy Storage (RRS)", "REDUCED_REDUNDANCY" }, }; try { foreach (var sc in ReadStorageClasses()) - if (!ns.Select(x => x.Value).Contains(sc.Value)) - ns.Add(sc); + if (!ns.Select(x => x.Value).Contains(sc.Value, StringComparer.OrdinalIgnoreCase)) + ns.Add(sc.Key, sc.Value); } catch { } - KNOWN_S3_STORAGE_CLASSES = ns.ToArray(); + KNOWN_S3_STORAGE_CLASSES = ns; } /// @@ -218,12 +224,10 @@ namespace Duplicati.Library.Backend //Change in S3, now requires that you use location specific endpoint if (!string.IsNullOrEmpty(locationConstraint)) - foreach (KeyValuePair kvp in DEFAULT_S3_LOCATION_BASED_HOSTS) - if (kvp.Key.Equals(locationConstraint, StringComparison.OrdinalIgnoreCase)) - { - s3host = kvp.Value; - break; - } + { + if (DEFAULT_S3_LOCATION_BASED_HOSTS.TryGetValue(locationConstraint, out var s3hostmatch)) + s3host = s3hostmatch; + } } //Fallback to previous formats @@ -406,10 +410,10 @@ namespace Duplicati.Library.Backend { StringBuilder hostnames = new StringBuilder(); StringBuilder locations = new StringBuilder(); - foreach (KeyValuePair s in KNOWN_S3_PROVIDERS) + foreach (var s in KNOWN_S3_PROVIDERS) hostnames.AppendLine(string.Format("{0}: {1}", s.Key, s.Value)); - foreach (KeyValuePair s in KNOWN_S3_LOCATIONS) + foreach (var s in KNOWN_S3_LOCATIONS) locations.AppendLine(string.Format("{0}: {1}", s.Key, s.Value)); var defaults = new Amazon.S3.AmazonS3Config(); diff --git a/Duplicati/Library/Backend/S3/S3Config.cs b/Duplicati/Library/Backend/S3/S3Config.cs index 19fc1f914..181edfb5f 100644 --- a/Duplicati/Library/Backend/S3/S3Config.cs +++ b/Duplicati/Library/Backend/S3/S3Config.cs @@ -56,13 +56,13 @@ namespace Duplicati.Library.Backend switch (ct) { case ConfigType.RegionHosts: - return S3.DEFAULT_S3_LOCATION_BASED_HOSTS.ToDictionary((x) => x.Key, (y) => y.Value); + return S3.DEFAULT_S3_LOCATION_BASED_HOSTS; case ConfigType.Regions: - return S3.KNOWN_S3_LOCATIONS.ToDictionary((x) => x.Key, (y) => y.Value); + return S3.KNOWN_S3_LOCATIONS; case ConfigType.StorageClasses: - return S3.KNOWN_S3_STORAGE_CLASSES.ToDictionary((x) => x.Key, (y) => y.Value); + return S3.KNOWN_S3_STORAGE_CLASSES; default: - return S3.KNOWN_S3_PROVIDERS.ToDictionary((x) => x.Key, (y) => y.Value); + return S3.KNOWN_S3_PROVIDERS; } }