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; }
}
}