using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Net.Http; using System.Net.Http.Headers; using System.Security.Cryptography; using System.Text; using System.Web; using Vinno.vCloud.Common.Storage.ObjectStorageInfo; namespace Vinno.vCloud.Disk.Tencent { public class CosUploadHelper { private static TencentCosConfig _tencentCosConfig; public static void Init() { _tencentCosConfig = new TencentCosConfig("https://flyinsono-hk-1300984704.cos.ap-hongkong.myqcloud.com/", "AKIDMSIsADUUpvJGwJOKvsb5IDrGtGNBRzzi", "4sQhdJBl5HI7f3oLbZIlwqXOyILyLWP0");//Vinno //_tencentCosConfig = new TencentCosConfig("https://shanghai-1304323531.cos.ap-shanghai.myqcloud.com/", "AKIDF1C0g7VcfU6UirrB0ZN0QfgiYAaynG6g", "f9QVFpGaiqQ3ThARUKHQL1HI7j7QN8e3");//Loki上海节点 //_tencentCosConfig = new TencentCosConfig("https://shanghai-1305757778.cos.ap-nanjing.myqcloud.com/", "AKIDVt3ye6KNDqGfotqfMxMWR7YnmW0EDvOc", "3rPimbCYtFlCVg2B5kAKFuPgiU4QXO0N");//Jeremy账号,测试节点 } /// 下载文件 /// 文件下载地址 /// public static byte[] DownloadFile(string requestUrl) { return ObjectStorageSingle.Instance.GetFile(requestUrl); } /// 上传文件 /// /// /// /// public static string UploadFile(byte[] fileData, string fileName, string mimeType, Action progressCallback = null) { var contentType = MediaTypeHeaderValue.Parse(mimeType); var requestHeads = new Dictionary(); ProductInfoHeaderValue productInfoHeaderValue = null; var authorization = GetAuthorization(fileName, HttpMethod.Put); requestHeads.Add("Authorization", authorization); var requestUrl = $"{_tencentCosConfig.UrlBucket}{fileName}"; var result = ObjectStorageSingle.Instance.UploadFile(fileData, contentType, requestUrl, requestHeads, productInfoHeaderValue, progressCallback); if (result) { return requestUrl; } return string.Empty; } /// 删除文件 /// /// /// public static bool DeleteFile(string fileUrl) { var fileName = fileUrl; var lastKeyIndex = fileUrl.LastIndexOf("/"); if (lastKeyIndex >= 0 && lastKeyIndex < fileUrl.Length) { fileName = fileUrl.Substring(lastKeyIndex + 1); } var authorization = GetAuthorization(fileName, HttpMethod.Delete); var requestUrl = fileUrl; return ObjectStorageSingle.Instance.DeleteFile(requestUrl, authorization); } public static string GetAuthorization(string pathName, HttpMethod httpMethod) { var _requestParams = new List>(); var _headers = new List>(); //1. Generate KeyTime, KeyTime = [Now];[Expires] example:1557902800;1557910000 var now = DateTimeOffset.Now; long startTimeStamp = now.ToUnixTimeSeconds(); long endTimeStamp = now.AddDays(1).ToUnixTimeSeconds(); var keyTime = $"{startTimeStamp};{endTimeStamp}"; //2. Generate SignKey,SignKey = HMAC-SHA1([SecretKey], KeyTime) var signKey = HMACSHA1(_tencentCosConfig.SecretKey, keyTime); //3. Generate UrlParamList and HttpParameters HttpString = [HttpMethod]\n[HttpURI]\n[HttpParameters]\n[HttpHeaders]\n var urlParamListBuilder = new StringBuilder(); var stringParamBuilder = new StringBuilder(); var urlParamList = string.Empty; var httpParameters = string.Empty; if (_requestParams != null) { _requestParams.Sort();//TODO check foreach (var param in _requestParams) { var encodeKey = HttpUtility.UrlEncode(param.Key).ToLower(); urlParamListBuilder.Append($"{encodeKey};"); var encodeValue = HttpUtility.UrlEncode(param.Value); stringParamBuilder.Append($"{encodeKey}={encodeValue}&"); } urlParamList = urlParamListBuilder.ToString(); if (!string.IsNullOrEmpty(urlParamList)) { urlParamList = urlParamList.TrimEnd(';'); } httpParameters = stringParamBuilder.ToString(); if (!string.IsNullOrEmpty(httpParameters)) { httpParameters = httpParameters.TrimEnd('&'); } } var headerListBuilder = new StringBuilder(); var httpHeadersBuilder = new StringBuilder(); var headerList = string.Empty; var httpHeaders = string.Empty; if (_headers != null) { _headers.Sort();//TODO check foreach (var param in _headers) { var encodeKey = HttpUtility.UrlEncode(param.Key).ToLower(); headerListBuilder.Append($"{encodeKey};"); var encodeValue = HttpUtility.UrlEncode(param.Value); httpHeadersBuilder.Append($"{encodeKey}={encodeValue}&"); } headerList = headerListBuilder.ToString(); if (!string.IsNullOrEmpty(headerList)) { headerList = headerList.TrimEnd(';'); } httpHeaders = httpHeadersBuilder.ToString(); if (!string.IsNullOrEmpty(httpHeaders)) { httpHeaders = httpHeaders.TrimEnd('&'); } } //5. Generatet HttpString string httpString = string.Format($"{httpMethod.ToString().ToLower()}\n/{pathName}\n{httpParameters}\n{httpHeaders}\n"); //6. Generate StringToSign string stringToSign = string.Format("sha1\n{0}\n{1}\n", keyTime, SHA1(httpString)); //7. Generate Signature var signature = HMACSHA1(signKey, stringToSign); //return $"q-sign-algorithm=sha1&q-ak={SecretId}&q-sign-time={keyTime}&q-key-time={keyTime}&q-signature={signature}"; return $"q-sign-algorithm=sha1&q-ak={_tencentCosConfig.SecretId}&q-sign-time={keyTime}&q-key-time={keyTime}&q-header-list={headerList}&q-url-param-list={urlParamList}&q-signature={signature}"; } static string SHA1(string content) { var sha1 = new SHA1CryptoServiceProvider(); byte[] c = Encoding.Default.GetBytes(content); byte[] sc = sha1.ComputeHash(c); StringBuilder sb = new StringBuilder(""); foreach (byte b in sc) { sb.AppendFormat("{0:x2}", b); } return sb.ToString(); } static string HMACSHA1(string secretKey, string content) { byte[] keyByte = Encoding.Default.GetBytes(secretKey); HMACSHA1 hmacsha1 = new HMACSHA1(keyByte); byte[] messageBytes = Encoding.Default.GetBytes(content); byte[] hashmessage = hmacsha1.ComputeHash(messageBytes); StringBuilder sb = new StringBuilder(""); foreach (byte b in hashmessage) { sb.AppendFormat("{0:x2}", b); } return sb.ToString(); } } public class TencentCosConfig { public TencentCosConfig(string bucket, string secretId, string secretKey) { UrlBucket = bucket; SecretId = secretId; SecretKey = secretKey; } public string UrlBucket { get; set; } public string SecretId { get; set; } public string SecretKey { get; set; } } }