StorageConnectionString
class 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>> = 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((object)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 (object)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);
}
}
}