<PackageReference Include="Azure.Storage.Common" Version="12.23.0" />

StorageConnectionString

using System; using System.Collections.Generic; using System.Globalization; using System.Linq; namespace Azure.Storage { internal class StorageConnectionString { private static readonly KeyValuePair<string, Func<string, bool>> s_useDevelopmentStorageSetting = Setting("UseDevelopmentStorage", "true"); private static readonly KeyValuePair<string, Func<string, bool>> s_developmentStorageProxyUriSetting = Setting("DevelopmentStorageProxyUri", IsValidUri); private static readonly KeyValuePair<string, Func<string, bool>> s_defaultEndpointsProtocolSetting = Setting("DefaultEndpointsProtocol", "http", "https"); private static readonly KeyValuePair<string, Func<string, bool>> s_accountNameSetting = Setting("AccountName", Array.Empty<string>()); private static readonly KeyValuePair<string, Func<string, bool>> s_accountKeyNameSetting = Setting("AccountKeyName", Array.Empty<string>()); private static readonly KeyValuePair<string, Func<string, bool>> s_accountKeySetting = Setting("AccountKey", IsValidBase64String); private static readonly KeyValuePair<string, Func<string, bool>> s_blobEndpointSetting = Setting("BlobEndpoint", IsValidUri); private static readonly KeyValuePair<string, Func<string, bool>> s_queueEndpointSetting = Setting("QueueEndpoint", IsValidUri); private static readonly KeyValuePair<string, Func<string, bool>> s_fileEndpointSetting = Setting("FileEndpoint", IsValidUri); private static readonly KeyValuePair<string, Func<string, bool>> s_tableEndpointSetting = Setting("TableEndpoint", IsValidUri); private static readonly KeyValuePair<string, Func<string, bool>> s_blobSecondaryEndpointSetting = Setting("BlobSecondaryEndpoint", IsValidUri); private static readonly KeyValuePair<string, Func<string, bool>> s_queueSecondaryEndpointSetting = Setting("QueueSecondaryEndpoint", IsValidUri); private static readonly KeyValuePair<string, Func<string, bool>> s_fileSecondaryEndpointSetting = Setting("FileSecondaryEndpoint", IsValidUri); private static readonly KeyValuePair<string, Func<string, bool>> s_tableSecondaryEndpointSetting = Setting("TableSecondaryEndpoint", IsValidUri); private static readonly KeyValuePair<string, Func<string, bool>> s_endpointSuffixSetting = Setting("EndpointSuffix", IsValidDomain); private static readonly KeyValuePair<string, Func<string, bool>> s_sharedAccessSignatureSetting = Setting("SharedAccessSignature", Array.Empty<string>()); private static StorageConnectionString s_devStoreAccount; public string AccountName; private static readonly Func<IDictionary<string, string>, IDictionary<string, string>> s_validCredentials = MatchesOne(MatchesAll(AllRequired(s_accountNameSetting, s_accountKeySetting), Optional(s_accountKeyNameSetting), None(s_sharedAccessSignatureSetting)), MatchesAll(AllRequired(s_sharedAccessSignatureSetting), Optional(s_accountNameSetting), None(s_accountKeySetting, s_accountKeyNameSetting)), None(s_accountNameSetting, s_accountKeySetting, s_accountKeyNameSetting, s_sharedAccessSignatureSetting)); internal static bool UseV1MD5 => true; public static StorageConnectionString DevelopmentStorageAccount { get { if (s_devStoreAccount == null) s_devStoreAccount = GetDevelopmentStorageAccount(null); return s_devStoreAccount; } } internal bool IsDevStoreAccount { get; set; } internal string EndpointSuffix { get; set; } internal IDictionary<string, string> Settings { get; set; } internal bool DefaultEndpoints { get; set; } public Uri BlobEndpoint => BlobStorageUri.PrimaryUri; public Uri QueueEndpoint => QueueStorageUri.PrimaryUri; public Uri TableEndpoint => TableStorageUri.PrimaryUri; public Uri FileEndpoint => FileStorageUri.PrimaryUri; public (Uri PrimaryUri, Uri SecondaryUri) BlobStorageUri { get; set; } public (Uri PrimaryUri, Uri SecondaryUri) QueueStorageUri { get; set; } public (Uri PrimaryUri, Uri SecondaryUri) TableStorageUri { get; set; } public (Uri PrimaryUri, Uri SecondaryUri) FileStorageUri { get; set; } public object Credentials { get; set; } public StorageConnectionString(object storageCredentials, (Uri Primary, Uri Secondary) blobStorageUri = default((Uri Primary, Uri Secondary)), (Uri Primary, Uri Secondary) queueStorageUri = default((Uri Primary, Uri Secondary)), (Uri Primary, Uri Secondary) tableStorageUri = default((Uri Primary, Uri Secondary)), (Uri Primary, Uri Secondary) fileStorageUri = default((Uri Primary, Uri Secondary))) { Credentials = storageCredentials; BlobStorageUri = blobStorageUri; QueueStorageUri = queueStorageUri; TableStorageUri = tableStorageUri; FileStorageUri = fileStorageUri; DefaultEndpoints = false; } public static StorageConnectionString Parse(string connectionString) { if (string.IsNullOrEmpty(connectionString)) throw Errors.ArgumentNull("connectionString"); StorageConnectionString accountInformation = default(StorageConnectionString); if (ParseCore(connectionString, out accountInformation, delegate(string err) { throw Errors.InvalidFormat(err); })) return accountInformation; throw Errors.ParsingConnectionStringFailed(); } public static bool TryParse(string connectionString, out StorageConnectionString account) { if (!string.IsNullOrEmpty(connectionString)) try { return ParseCore(connectionString, out account, delegate { }); } catch (Exception) { account = null; return false; } account = null; return false; } private static StorageConnectionString GetDevelopmentStorageAccount(Uri proxyUri) { UriBuilder obj = (proxyUri != (Uri)null) ? new UriBuilder(proxyUri.Scheme, proxyUri.Host) : new UriBuilder("http", "127.0.0.1"); obj.Path = "devstoreaccount1"; obj.Port = 10000; Uri uri = obj.Uri; obj.Port = 10002; Uri uri2 = obj.Uri; obj.Port = 10001; Uri uri3 = obj.Uri; obj.Path = "devstoreaccount1-secondary"; obj.Port = 10000; Uri uri4 = obj.Uri; obj.Port = 10001; Uri uri5 = obj.Uri; obj.Port = 10002; Uri uri6 = obj.Uri; StorageConnectionString storageConnectionString = new StorageConnectionString(new StorageSharedKeyCredential("devstoreaccount1", "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="), (uri, uri4), (uri3, uri5), (uri2, uri6), (null, null)); storageConnectionString.Settings = new Dictionary<string, string>(); storageConnectionString.Settings.Add("UseDevelopmentStorage", "true"); if (proxyUri != (Uri)null) storageConnectionString.Settings.Add("DevelopmentStorageProxyUri", proxyUri.AbsoluteUri); storageConnectionString.IsDevStoreAccount = true; return storageConnectionString; } internal static bool ParseCore(string connectionString, out StorageConnectionString accountInformation, Action<string> error) { <>c__DisplayClass70_0 <>c__DisplayClass70_ = default(<>c__DisplayClass70_0); <>c__DisplayClass70_.settings = ParseStringIntoSettings(connectionString, error); if (<>c__DisplayClass70_.settings == null) { accountInformation = null; return false; } if (MatchesSpecification(<>c__DisplayClass70_.settings, AllRequired(s_useDevelopmentStorageSetting), Optional(s_developmentStorageProxyUriSetting))) { accountInformation = (<>c__DisplayClass70_.settings.TryGetValue("DevelopmentStorageProxyUri", out string value) ? GetDevelopmentStorageAccount(new Uri(value)) : DevelopmentStorageAccount); accountInformation.Settings = s_validCredentials(<>c__DisplayClass70_.settings); return true; } Func<IDictionary<string, string>, IDictionary<string, string>> func = Optional(s_blobEndpointSetting, s_blobSecondaryEndpointSetting, s_queueEndpointSetting, s_queueSecondaryEndpointSetting, s_fileEndpointSetting, s_fileSecondaryEndpointSetting, s_tableEndpointSetting, s_tableSecondaryEndpointSetting); Func<IDictionary<string, string>, IDictionary<string, string>> func2 = AtLeastOne(s_blobEndpointSetting, s_queueEndpointSetting, s_fileEndpointSetting, s_tableEndpointSetting); Func<IDictionary<string, string>, IDictionary<string, string>> func3 = Optional(s_blobSecondaryEndpointSetting, s_queueSecondaryEndpointSetting, s_fileSecondaryEndpointSetting, s_tableSecondaryEndpointSetting); Func<IDictionary<string, string>, IDictionary<string, string>> func4 = MatchesExactly(MatchesAll(MatchesOne(MatchesAll(AllRequired(s_accountKeySetting), Optional(s_accountKeyNameSetting)), AllRequired(s_sharedAccessSignatureSetting)), AllRequired(s_accountNameSetting), func, Optional(s_defaultEndpointsProtocolSetting, s_endpointSuffixSetting))); Func<IDictionary<string, string>, IDictionary<string, string>> func5 = MatchesExactly(MatchesAll(s_validCredentials, func2, func3)); <>c__DisplayClass70_.matchesAutomaticEndpointsSpec = MatchesSpecification(<>c__DisplayClass70_.settings, func4); bool flag = MatchesSpecification(<>c__DisplayClass70_.settings, func5); if (<>c__DisplayClass70_.matchesAutomaticEndpointsSpec | flag) { if (<>c__DisplayClass70_.matchesAutomaticEndpointsSpec && !<>c__DisplayClass70_.settings.ContainsKey("DefaultEndpointsProtocol")) <>c__DisplayClass70_.settings.Add("DefaultEndpointsProtocol", "https"); string primary = <ParseCore>g__settingOrDefault|70_0("BlobEndpoint", ref <>c__DisplayClass70_); string primary2 = <ParseCore>g__settingOrDefault|70_0("QueueEndpoint", ref <>c__DisplayClass70_); string primary3 = <ParseCore>g__settingOrDefault|70_0("TableEndpoint", ref <>c__DisplayClass70_); string primary4 = <ParseCore>g__settingOrDefault|70_0("FileEndpoint", ref <>c__DisplayClass70_); string secondary = <ParseCore>g__settingOrDefault|70_0("BlobSecondaryEndpoint", ref <>c__DisplayClass70_); string secondary2 = <ParseCore>g__settingOrDefault|70_0("QueueSecondaryEndpoint", ref <>c__DisplayClass70_); string secondary3 = <ParseCore>g__settingOrDefault|70_0("TableSecondaryEndpoint", ref <>c__DisplayClass70_); string secondary4 = <ParseCore>g__settingOrDefault|70_0("FileSecondaryEndpoint", ref <>c__DisplayClass70_); string sasToken = <ParseCore>g__settingOrDefault|70_0("SharedAccessSignature", ref <>c__DisplayClass70_); if (<ParseCore>g__s_isValidEndpointPair|70_1(primary, secondary) && <ParseCore>g__s_isValidEndpointPair|70_1(primary2, secondary2) && <ParseCore>g__s_isValidEndpointPair|70_1(primary3, secondary3) && <ParseCore>g__s_isValidEndpointPair|70_1(primary4, secondary4)) { accountInformation = new StorageConnectionString(GetCredentials(<>c__DisplayClass70_.settings), <ParseCore>g__createStorageUri|70_2(primary, secondary, sasToken, new Func<IDictionary<string, string>, (Uri, Uri)>(ConstructBlobEndpoint), ref <>c__DisplayClass70_), <ParseCore>g__createStorageUri|70_2(primary2, secondary2, sasToken, new Func<IDictionary<string, string>, (Uri, Uri)>(ConstructQueueEndpoint), ref <>c__DisplayClass70_), <ParseCore>g__createStorageUri|70_2(primary3, secondary3, sasToken, new Func<IDictionary<string, string>, (Uri, Uri)>(ConstructTableEndpoint), ref <>c__DisplayClass70_), <ParseCore>g__createStorageUri|70_2(primary4, secondary4, sasToken, new Func<IDictionary<string, string>, (Uri, Uri)>(ConstructFileEndpoint), ref <>c__DisplayClass70_)) { EndpointSuffix = <ParseCore>g__settingOrDefault|70_0("EndpointSuffix", ref <>c__DisplayClass70_), Settings = s_validCredentials(<>c__DisplayClass70_.settings) }; accountInformation.AccountName = <ParseCore>g__settingOrDefault|70_0("AccountName", ref <>c__DisplayClass70_); return true; } } accountInformation = null; error("No valid combination of account information found."); return false; } private static IDictionary<string, string> ParseStringIntoSettings(string connectionString, Action<string> error) { IDictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); string[] array = connectionString.Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < array.Length; i++) { string[] array2 = array[i].Split(new char[1] { '=' }, 2); if (array2.Length != 2) { error("Settings must be of the form \"name=value\"."); return null; } if (dictionary.ContainsKey(array2[0])) { error(string.Format(CultureInfo.InvariantCulture, "Duplicate setting '{0}' found.", array2[0])); return null; } dictionary.Add(array2[0], array2[1]); } return dictionary; } private static KeyValuePair<string, Func<string, bool>> Setting(string name, params string[] validValues) { return new KeyValuePair<string, Func<string, bool>>(name, delegate(string settingValue) { if (validValues.Length != 0) return validValues.Contains(settingValue, StringComparer.OrdinalIgnoreCase); return true; }); } private static KeyValuePair<string, Func<string, bool>> Setting(string name, Func<string, bool> isValid) { return new KeyValuePair<string, Func<string, bool>>(name, isValid); } private static bool IsValidBase64String(string settingValue) { try { Convert.FromBase64String(settingValue); return true; } catch (FormatException) { return false; } } private static bool IsValidUri(string settingValue) { return Uri.IsWellFormedUriString(settingValue, UriKind.Absolute); } private static bool IsValidDomain(string settingValue) { return Uri.CheckHostName(settingValue).Equals(UriHostNameType.Dns); } private static Func<IDictionary<string, string>, IDictionary<string, string>> AllRequired(params KeyValuePair<string, Func<string, bool>>[] requiredSettings) { return delegate(IDictionary<string, string> settings) { IDictionary<string, string> dictionary = new Dictionary<string, string>(settings, StringComparer.OrdinalIgnoreCase); KeyValuePair<string, Func<string, bool>>[] array = requiredSettings; for (int i = 0; i < array.Length; i++) { KeyValuePair<string, Func<string, bool>> keyValuePair = array[i]; if (!dictionary.TryGetValue(keyValuePair.Key, out string value) || !keyValuePair.Value(value)) return null; dictionary.Remove(keyValuePair.Key); } return dictionary; }; } private static Func<IDictionary<string, string>, IDictionary<string, string>> Optional(params KeyValuePair<string, Func<string, bool>>[] optionalSettings) { return delegate(IDictionary<string, string> settings) { IDictionary<string, string> dictionary = new Dictionary<string, string>(settings, StringComparer.OrdinalIgnoreCase); KeyValuePair<string, Func<string, bool>>[] array = optionalSettings; for (int i = 0; i < array.Length; i++) { KeyValuePair<string, Func<string, bool>> keyValuePair = array[i]; if (dictionary.TryGetValue(keyValuePair.Key, out string value) && keyValuePair.Value(value)) dictionary.Remove(keyValuePair.Key); } return dictionary; }; } private static Func<IDictionary<string, string>, IDictionary<string, string>> AtLeastOne(params KeyValuePair<string, Func<string, bool>>[] atLeastOneSettings) { return delegate(IDictionary<string, string> settings) { IDictionary<string, string> dictionary = new Dictionary<string, string>(settings, StringComparer.OrdinalIgnoreCase); bool flag = false; KeyValuePair<string, Func<string, bool>>[] array = atLeastOneSettings; for (int i = 0; i < array.Length; i++) { KeyValuePair<string, Func<string, bool>> keyValuePair = array[i]; if (dictionary.TryGetValue(keyValuePair.Key, out string value) && keyValuePair.Value(value)) { dictionary.Remove(keyValuePair.Key); flag = true; } } if (!flag) return null; return dictionary; }; } private static Func<IDictionary<string, string>, IDictionary<string, string>> None(params KeyValuePair<string, Func<string, bool>>[] atLeastOneSettings) { return delegate(IDictionary<string, string> settings) { IDictionary<string, string> dictionary = new Dictionary<string, string>(settings, StringComparer.OrdinalIgnoreCase); bool flag = false; KeyValuePair<string, Func<string, bool>>[] array = atLeastOneSettings; for (int i = 0; i < array.Length; i++) { KeyValuePair<string, Func<string, bool>> keyValuePair = array[i]; if (dictionary.TryGetValue(keyValuePair.Key, out string value) && keyValuePair.Value(value)) flag = true; } if (!flag) return dictionary; return null; }; } private static Func<IDictionary<string, string>, IDictionary<string, string>> MatchesAll(params Func<IDictionary<string, string>, IDictionary<string, string>>[] filters) { return delegate(IDictionary<string, string> settings) { IDictionary<string, string> dictionary = new Dictionary<string, string>(settings, StringComparer.OrdinalIgnoreCase); Func<IDictionary<string, string>, IDictionary<string, string>>[] array = filters; foreach (Func<IDictionary<string, string>, IDictionary<string, string>> func in array) { if (dictionary == null) break; dictionary = func(dictionary); } return dictionary; }; } private static Func<IDictionary<string, string>, IDictionary<string, string>> MatchesOne(params Func<IDictionary<string, string>, IDictionary<string, string>>[] filters) { return delegate(IDictionary<string, string> settings) { IDictionary<string, string>[] array = (from filter in filters select filter(new Dictionary<string, string>(settings)) into result where result != null select result).Take(2).ToArray(); if (array.Length == 1) return array.First(); return null; }; } private static Func<IDictionary<string, string>, IDictionary<string, string>> MatchesExactly(Func<IDictionary<string, string>, IDictionary<string, string>> filter) { return delegate(IDictionary<string, string> settings) { IDictionary<string, string> dictionary = filter(settings); if (dictionary != null && !dictionary.Any()) return dictionary; return null; }; } private static bool MatchesSpecification(IDictionary<string, string> settings, params Func<IDictionary<string, string>, IDictionary<string, string>>[] constraints) { for (int i = 0; i < constraints.Length; i++) { IDictionary<string, string> dictionary = constraints[i](settings); if (dictionary == null) return false; settings = dictionary; } return !settings.Any(); } private static object GetCredentials(IDictionary<string, string> settings) { settings.TryGetValue("AccountName", out string value); settings.TryGetValue("AccountKey", out string value2); settings.TryGetValue("SharedAccessSignature", out string value3); if (value == null || value2 == null || value3 != null) { if (value2 != null || value3 == null) return null; return new SharedAccessSignatureCredentials(value3); } return new StorageSharedKeyCredential(value, value2); } private static (Uri Primary, Uri Secondary) ConstructBlobEndpoint(IDictionary<string, string> settings) { return ConstructBlobEndpoint(settings["DefaultEndpointsProtocol"], settings["AccountName"], settings.ContainsKey("EndpointSuffix") ? settings["EndpointSuffix"] : null, settings.ContainsKey("SharedAccessSignature") ? settings["SharedAccessSignature"] : null); } internal static (Uri Primary, Uri Secondary) ConstructBlobEndpoint(string scheme, string accountName, string endpointSuffix, string sasToken) { if (string.IsNullOrEmpty(scheme)) throw Errors.ArgumentNull("scheme"); if (string.IsNullOrEmpty(accountName)) throw Errors.ArgumentNull("accountName"); if (string.IsNullOrEmpty(endpointSuffix)) endpointSuffix = "core.windows.net"; return ConstructUris(scheme, accountName, "blob", endpointSuffix, sasToken); } private static (Uri Primary, Uri Secondary) ConstructFileEndpoint(IDictionary<string, string> settings) { return ConstructFileEndpoint(settings["DefaultEndpointsProtocol"], settings["AccountName"], settings.ContainsKey("EndpointSuffix") ? settings["EndpointSuffix"] : null, settings.ContainsKey("SharedAccessSignature") ? settings["SharedAccessSignature"] : null); } internal static (Uri Primary, Uri Secondary) ConstructFileEndpoint(string scheme, string accountName, string endpointSuffix, string sasToken) { if (string.IsNullOrEmpty(scheme)) throw Errors.ArgumentNull("scheme"); if (string.IsNullOrEmpty(accountName)) throw Errors.ArgumentNull("accountName"); if (string.IsNullOrEmpty(endpointSuffix)) endpointSuffix = "core.windows.net"; return ConstructUris(scheme, accountName, "file", endpointSuffix, sasToken); } private static (Uri Primary, Uri Secondary) ConstructQueueEndpoint(IDictionary<string, string> settings) { return ConstructQueueEndpoint(settings["DefaultEndpointsProtocol"], settings["AccountName"], settings.ContainsKey("EndpointSuffix") ? settings["EndpointSuffix"] : null, settings.ContainsKey("SharedAccessSignature") ? settings["SharedAccessSignature"] : null); } internal static (Uri Primary, Uri Secondary) ConstructQueueEndpoint(string scheme, string accountName, string endpointSuffix, string sasToken) { if (string.IsNullOrEmpty(scheme)) throw Errors.ArgumentNull("scheme"); if (string.IsNullOrEmpty(accountName)) throw Errors.ArgumentNull("accountName"); if (string.IsNullOrEmpty(endpointSuffix)) endpointSuffix = "core.windows.net"; return ConstructUris(scheme, accountName, "queue", endpointSuffix, sasToken); } private static (Uri Primary, Uri Secondary) ConstructTableEndpoint(IDictionary<string, string> settings) { return ConstructTableEndpoint(settings["DefaultEndpointsProtocol"], settings["AccountName"], settings.ContainsKey("EndpointSuffix") ? settings["EndpointSuffix"] : null, settings.ContainsKey("SharedAccessSignature") ? settings["SharedAccessSignature"] : null); } internal static (Uri Primary, Uri Secondary) ConstructTableEndpoint(string scheme, string accountName, string endpointSuffix, string sasToken) { if (string.IsNullOrEmpty(scheme)) throw Errors.ArgumentNull("scheme"); if (string.IsNullOrEmpty(accountName)) throw Errors.ArgumentNull("accountName"); if (string.IsNullOrEmpty(endpointSuffix)) endpointSuffix = "core.windows.net"; return ConstructUris(scheme, accountName, "table", endpointSuffix, sasToken); } private static (Uri Primary, Uri Secondary) ConstructUris(string scheme, string accountName, string hostNamePrefix, string endpointSuffix, string sasToken) { UriBuilder uriBuilder = new UriBuilder { Scheme = scheme, Host = string.Format(CultureInfo.InvariantCulture, "{0}.{1}.{2}", accountName, hostNamePrefix, endpointSuffix), Query = sasToken }; UriBuilder uriBuilder2 = new UriBuilder(); uriBuilder2.Scheme = scheme; uriBuilder2.Host = string.Format(CultureInfo.InvariantCulture, "{0}{1}.{2}.{3}", accountName, "-secondary", hostNamePrefix, endpointSuffix); uriBuilder2.Query = sasToken; UriBuilder uriBuilder3 = uriBuilder2; return (uriBuilder.Uri, uriBuilder3.Uri); } } }