util/csharp/core/Common.cs (393 lines of code) (raw):

using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; using System.Web; using AlibabaCloud.OSSUtil.Models; using AlibabaCloud.OSSUtil.Streams; using AlibabaCloud.OSSUtil.Utils; using Tea; namespace AlibabaCloud.OSSUtil { public static class Common { private static readonly string _defaultUserAgent; private static readonly char[] characters = { '-', '_', '.', '~' }; static Common() { _defaultUserAgent = GetDefaultUserAgent(); } /// <summary> /// Get error message from msg /// </summary> /// <param name="body"></param> /// <returns></returns> public static Dictionary<string,object> GetErrMessage(string body) { return (Dictionary<string, object>)DictUtils.GetDicValue(XmlUtil.DeserializeXml(body, typeof(ServiceError)), "Error"); } public static Dictionary<string, string> ToQuery(Dictionary<string, object> dicRequest) { Dictionary<string, string> dicQuery = new Dictionary<string, string>(); foreach (KeyValuePair<string, object> item in dicRequest) { if (item.Value != null) { dicQuery.Add(item.Key, item.Value.ToString()); } } return dicQuery; } public static Dictionary<string, string> ToMeta(Dictionary<string, string> meta, string prefix) { Dictionary<string, string> result = new Dictionary<string, string>(); if (meta == null) { return result; } foreach (var keypair in meta) { string newKey = keypair.Key; if (!keypair.Key.ToLower().StartsWith(prefix)) { newKey = prefix + keypair.Key; } result.Add(newKey, keypair.Value.ToSafeString()); } return result; } public static Dictionary<string, string> ParseMeta(Dictionary<string, string> meta, string prefix) { Dictionary<string, string> result = new Dictionary<string, string>(); if (meta == null) { return result; } foreach (var keypair in meta) { string newKey = keypair.Key; if (keypair.Key.ToLower().StartsWith(prefix)) { newKey = keypair.Key.Replace(prefix, ""); } result.Add(newKey, keypair.Value.ToSafeString()); } return result; } public static string GetContentType(string filePath) { string type = Utils.MimeMapping.GetMimeMapping(filePath); if (string.IsNullOrWhiteSpace(type)) { type = DictUtils.GetDicValue(StaticConst.extToMimeType, Path.GetExtension(filePath).ToLower()); } return type; } public static string GetContentMD5(string str, bool? isEnableMD5) { if (isEnableMD5 == false) { return string.Empty; } try { System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider(); byte[] data = md5.ComputeHash(Encoding.UTF8.GetBytes(str)); return Convert.ToBase64String(data); } catch { return string.Empty; } } public static string Encode(string value, string encodeType) { string[] strs = value.Split('/'); switch (encodeType) { case "Base64": strs[strs.Length - 1] = Convert.ToBase64String(Encoding.UTF8.GetBytes(strs[strs.Length - 1])); break; case "UrlEncode": strs[strs.Length - 1] = HttpUtility.UrlEncode(strs[strs.Length - 1], Encoding.UTF8); break; } value = string.Join("/", strs); return value; } public static string GetUserAgent(string val) { if (!string.IsNullOrWhiteSpace(val)) { return _defaultUserAgent + " " + val; } return _defaultUserAgent; } public static string GetHost(string bucketName,string regionId,string endpoint,string hostModel) { string host = string.Empty; if (string.IsNullOrWhiteSpace(regionId)) { regionId = "cn-hangzhou"; } if (string.IsNullOrWhiteSpace(endpoint)) { endpoint = "oss-" + regionId + ".aliyuncs.com"; } if (!string.IsNullOrWhiteSpace(bucketName)) { hostModel = hostModel == null ? string.Empty : hostModel; if (hostModel.ToLower() == "ip") { host = endpoint + "/" + bucketName; } else if (hostModel.ToLower() == "cname") { host = endpoint; } else { host = bucketName + "." + endpoint; } } else { host = endpoint; } return host; } public static Stream Inject(Stream body, Dictionary<string, string> dict) { return new VerifyStream(body, dict); } public static string GetSignature(TeaRequest request, string bucketName,string accessKeyId,string accessKeySecret,string signatureVersion,List<string> addtionalHeaders) { if (signatureVersion.ToSafeString("").ToLower() == "v2") { if (addtionalHeaders == null || addtionalHeaders.Count == 0) { return "OSS2 AccessKeyId:" + accessKeyId + ",Signature:" + GetSignatureV2(request, bucketName, accessKeySecret, addtionalHeaders); } else { return "OSS2 AccessKeyId:" + accessKeyId + ",AdditionalHeaders:" + string.Join(";", addtionalHeaders) + ",Signature:" + GetSignatureV2(request, bucketName, accessKeySecret, addtionalHeaders); } } else { return "OSS " + accessKeyId + ":" + GetSignatureV1(request, bucketName, accessKeySecret); } } public static string Decode(string val, string decodeType) { switch(decodeType) { case "Base64Decode": return Base64Decode(val); case "UrlDecode": return UrlDecode(val); } return val; } internal static string Base64Decode(string str) { string[] strs = str.Split('/'); strs[strs.Length - 1] = Encoding.UTF8.GetString(Convert.FromBase64String(strs[strs.Length - 1])); return string.Join("/", strs); } internal static string UrlDecode(string str) { string[] strs = str.Split('/'); strs[strs.Length - 1] = HttpUtility.UrlDecode(strs[strs.Length - 1], Encoding.UTF8); return string.Join("/", strs); } internal static string GetSignatureV1(TeaRequest teaRequest, string bucketName, string accessKeySecret) { string resource = string.Empty; if (!string.IsNullOrWhiteSpace(bucketName)) { resource = "/" + bucketName; } resource = resource + teaRequest.Pathname; if (teaRequest.Query.Count > 0 && !resource.Contains('?')) { resource += "?"; } foreach (var keypair in teaRequest.Query) { if (StaticConst.signKeyList.Contains(keypair.Key) && !string.IsNullOrWhiteSpace(keypair.Value)) { if (resource.EndsWith("?")) { resource = resource + keypair.Key + "=" + keypair.Value; } else { resource = resource + "&" + keypair.Key + "=" + keypair.Value; } } } return GetSignedStrV1(teaRequest, resource, accessKeySecret); } internal static string GetSignedStrV1(TeaRequest teaRequest, string canonicalizedResource, string accessKeySecret) { Dictionary<string, string> temp = new Dictionary<string, string>(); foreach (var keypair in teaRequest.Headers) { if (keypair.Key.ToLower().StartsWith("x-oss-")) { temp.Add(keypair.Key.ToLower(), keypair.Value); } } Dictionary<string, string> hs = (from dic in temp orderby dic.Key ascending select dic).ToDictionary(p => p.Key, o => o.Value); string canonicalizedOSSHeaders = string.Empty; foreach (var keypair in hs) { canonicalizedOSSHeaders += keypair.Key + ":" + keypair.Value + "\n"; } string date = DictUtils.GetDicValue(teaRequest.Headers, "date"); string contentType = DictUtils.GetDicValue(teaRequest.Headers, "content-type"); string contentMd5 = DictUtils.GetDicValue(teaRequest.Headers, "content-md5"); string signStr = teaRequest.Method + "\n" + contentMd5 + "\n" + contentType + "\n" + date + "\n" + canonicalizedOSSHeaders + canonicalizedResource; System.Diagnostics.Debug.WriteLine(signStr); byte[] signData; using (KeyedHashAlgorithm algorithm = CryptoConfig.CreateFromName("HMACSHA1") as KeyedHashAlgorithm) { algorithm.Key = Encoding.UTF8.GetBytes(accessKeySecret); signData = algorithm.ComputeHash(Encoding.UTF8.GetBytes(signStr.ToCharArray())); } string signedStr = Convert.ToBase64String(signData); return signedStr; } internal static string GetSignatureV2(TeaRequest teaRequest, string bucketName, string accessKeySecret, List<string> additionalHeaders) { if (additionalHeaders == null) { additionalHeaders = new List<string>(); } string resource = string.Empty; string pathName = teaRequest.Pathname; if (!string.IsNullOrWhiteSpace(bucketName)) { pathName = "/" + bucketName + pathName; } Dictionary<string, string> sortDict = new Dictionary<string, string>(teaRequest.Query); string[] strs = pathName.Split('?'); resource += UriEncode(strs[0], true); if (strs.Length > 1 && !string.IsNullOrWhiteSpace(strs[1])) { sortDict.Add(strs[1], string.Empty); } Dictionary<string, string> hs = new Dictionary<string, string>(); hs = (from dic in sortDict orderby dic.Key ascending select dic).ToDictionary(p => p.Key, o => o.Value); if (hs.Count > 0 && !resource.Contains("?")) { resource += "?"; } foreach (var keypair in hs) { if (!resource.EndsWith("?")) { resource += "&"; } if (!string.IsNullOrEmpty(keypair.Value)) { resource += UriEncode(keypair.Key, true) + "=" + UriEncode(keypair.Value, true); } else { resource += UriEncode(keypair.Key, true); } } return GetSignedStrV2(teaRequest, resource, accessKeySecret, additionalHeaders); } internal static string GetSignedStrV2(TeaRequest teaRequest, string canonicalizedResource, string accessKeySecret, List<string> additionalHeaders) { Dictionary<string, string> temp = new Dictionary<string, string>(); foreach (var keypair in teaRequest.Headers) { if ((from k in additionalHeaders where k.ToLower() == keypair.Key.ToLower() select k).ToList().Count() > 0) { temp.Add(keypair.Key.ToLower(), keypair.Value); } else if (keypair.Key.ToLower().StartsWith("x-oss-")) { temp.Add(keypair.Key.ToLower(), keypair.Value); } } Dictionary<string, string> hs = (from dic in temp orderby dic.Key ascending select dic).ToDictionary(p => p.Key, o => o.Value); string canonicalizedOSSHeaders = string.Empty; foreach (var keypair in hs) { canonicalizedOSSHeaders += keypair.Key + ":" + keypair.Value + "\n"; } string date = DictUtils.GetDicValue(teaRequest.Headers, "date"); string contentType = DictUtils.GetDicValue(teaRequest.Headers, "content-type"); string contentMd5 = DictUtils.GetDicValue(teaRequest.Headers, "content-md5"); string signStr = teaRequest.Method + "\n" + contentMd5 + "\n" + contentType + "\n" + date + "\n" + canonicalizedOSSHeaders + string.Join(";", additionalHeaders) + "\n" + canonicalizedResource; byte[] signData; using (KeyedHashAlgorithm algorithm = CryptoConfig.CreateFromName("HMACSHA256") as KeyedHashAlgorithm) { algorithm.Key = Encoding.UTF8.GetBytes(accessKeySecret); signData = algorithm.ComputeHash(Encoding.UTF8.GetBytes(signStr.ToCharArray())); } string signedStr = Convert.ToBase64String(signData); return signedStr; } internal static string UriEncode(string rawStr, bool? encodeSlash) { string res = string.Empty; foreach (char ch in rawStr) { if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || characters.Contains(ch)) { res += ch; } else if (ch == '/') { if (encodeSlash == true) { res += "%2F"; } else { res += ch; } } else { res = res + "%" + ((int)ch).ToString("X2"); } } return res; } internal static string GetDefaultUserAgent() { string defaultUserAgent = string.Empty; string OSVersion = Environment.OSVersion.ToString(); string ClientVersion = GetRuntimeRegexValue(RuntimeEnvironment.GetRuntimeDirectory()); string CoreVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString(); defaultUserAgent = "Alibaba Cloud (" + OSVersion + ") "; defaultUserAgent += ClientVersion; defaultUserAgent += " Core/" + CoreVersion; return defaultUserAgent; } internal static string GetRuntimeRegexValue(string value) { var rx = new Regex(@"(\.NET).*(\\|\/).*(\d)", RegexOptions.Compiled | RegexOptions.IgnoreCase); var matches = rx.Match(value); char[] separator = { '\\', '/' }; if (matches.Success) { var clientValueArray = matches.Value.Split(separator); return BuildClientVersion(clientValueArray); } return "RuntimeNotFound"; } internal static string BuildClientVersion(string[] value) { var finalValue = ""; for (var i = 0; i < value.Length - 1; ++i) { finalValue += value[i].ToSafeString("").Replace(".", "").ToLower(); } finalValue += "/" + value[value.Length - 1]; return finalValue; } } }