internal virtual async Task <string> PresignedObjectAsync(string bucketName , string objectName , int expiresInt , PresignedObjectType type , Func <string, string, int, Task <string> > PresignedFunc) { try { if (string.IsNullOrEmpty(bucketName)) { throw new ArgumentNullException(nameof(bucketName)); } objectName = FormatObjectName(objectName); if (expiresInt <= 0) { throw new Exception("ExpiresIn time can not less than 0."); } if (expiresInt > 7 * 24 * 3600) { throw new Exception("ExpiresIn time no more than 7 days."); } const int minExpiresInt = 600; if (Options.IsEnableCache && expiresInt > minExpiresInt) { string key = BuildPresignedObjectCacheKey(bucketName, objectName, type); var cacheResult = _cache.Get <PresignedUrlCache>(key); PresignedUrlCache cache = cacheResult != null ? cacheResult : null; //Unix时间 long nowTime = TimeUtil.Timestamp(); //缓存中存在,且有效时间不低于10分钟 if (cache != null && cache.Type == type && cache.CreateTime > 0 && (cache.CreateTime + expiresInt - nowTime) > minExpiresInt && cache.Name == objectName && cache.BucketName == bucketName) { return(cache.Url); } else { string presignedUrl = await PresignedFunc(bucketName, objectName, expiresInt); if (string.IsNullOrEmpty(presignedUrl)) { throw new Exception("Presigned object url failed."); } PresignedUrlCache urlCache = new PresignedUrlCache() { Url = presignedUrl, CreateTime = nowTime, Name = objectName, BucketName = bucketName, Type = type }; int randomSec = new Random().Next(0, 10); _cache.Set(key, urlCache, TimeSpan.FromSeconds(expiresInt + randomSec)); return(urlCache.Url); } } else { string presignedUrl = await PresignedFunc(bucketName, objectName, expiresInt); if (string.IsNullOrEmpty(presignedUrl)) { throw new Exception("Presigned object url failed."); } return(presignedUrl); } } catch (Exception ex) { throw new Exception($"Presigned {(type == PresignedObjectType.Get ? "get" : "put")} url for object '{objectName}' from {bucketName} failed. {ex.Message}", ex); } }
private async Task <string> PresignedObjectAsync(string bucketName, string objectName, int expiresInt, PresignedObjectType type) { if (string.IsNullOrEmpty(bucketName)) { throw new ArgumentNullException(nameof(bucketName)); } if (string.IsNullOrEmpty(objectName)) { throw new ArgumentNullException(nameof(objectName)); } if (expiresInt <= 0) { throw new Exception("ExpiresIn time can not less than 0."); } if (expiresInt > 7 * 24 * 3600) { throw new Exception("ExpiresIn time no more than 7 days."); } long nowTime = (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000; const int minExpiresInt = 600; string key = Encrypt.MD5($"{bucketName}_{objectName}_{type.ToString().ToUpper()}"); string objectUrl = null; //查找缓存 if (Options.IsEnableCache && (expiresInt > minExpiresInt)) { var cacheResult = await _cache.GetAsync <PresignedUrlCache>(key); PresignedUrlCache cache = cacheResult.HasValue ? cacheResult.Value : null; //缓存中存在,且有效时间不低于10分钟 if (cache != null && cache.Type == type && cache.CreateTime > 0 && (cache.CreateTime + expiresInt - nowTime) > minExpiresInt && cache.Name == objectName && cache.BucketName == bucketName) { return(cache.Url); } } if (type == PresignedObjectType.Get) { //生成URL AccessMode accessMode = await this.GetObjectAclAsync(bucketName, objectName); if (accessMode == AccessMode.PublicRead || accessMode == AccessMode.PublicReadWrite) { string bucketUrl = await this.GetBucketEndpointAsync(bucketName); objectUrl = $"{bucketUrl}{(objectName.StartsWith("/") ? "" : "/")}{objectName}"; } else { var req = new GeneratePresignedUriRequest(bucketName, objectName, SignHttpMethod.Get) { Expiration = DateTime.Now.AddSeconds(expiresInt) }; var uri = _client.GeneratePresignedUri(req); if (uri != null) { objectUrl = uri.ToString(); } } } else { var req = new GeneratePresignedUriRequest(bucketName, objectName, SignHttpMethod.Put) { Expiration = DateTime.Now.AddSeconds(expiresInt) }; var uri = _client.GeneratePresignedUri(req); if (uri != null) { objectUrl = uri.ToString(); } } if (string.IsNullOrEmpty(objectUrl)) { throw new Exception("Presigned get object url failed."); } //save cache if (Options.IsEnableCache && expiresInt > minExpiresInt) { PresignedUrlCache urlCache = new PresignedUrlCache() { Url = objectUrl, CreateTime = nowTime, Name = objectName, BucketName = bucketName, Type = type }; int randomSec = new Random().Next(5, 30); await _cache.SetAsync(key, urlCache, TimeSpan.FromSeconds(expiresInt + randomSec)); } return(objectUrl); }
private async Task <string> PresignedObjectAsync(string bucketName, string objectName, int expiresInt, PresignedObjectType type) { if (string.IsNullOrEmpty(bucketName)) { throw new ArgumentNullException(nameof(bucketName)); } if (string.IsNullOrEmpty(objectName)) { throw new ArgumentNullException(nameof(objectName)); } if (expiresInt <= 0) { throw new Exception("ExpiresIn time can not less than 0."); } if (expiresInt > 7 * 24 * 3600) { throw new Exception("ExpiresIn time no more than 7 days."); } long nowTime = (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000; const int minExpiresInt = 600; string key = Encrypt.MD5($"{bucketName}_{objectName}_{type.ToString().ToUpper()}"); string objectUrl = null; string newBucketName = ConvertBucketName(bucketName); PreSignatureStruct preSignatureStruct = new PreSignatureStruct() { appid = Options.Endpoint, region = Options.Region, bucket = newBucketName, key = objectName, httpMethod = type.ToString().ToUpper(), isHttps = Options.IsEnableHttps, signDurationSecond = expiresInt, headers = null, queryParameters = null, }; //查找缓存 if (Options.IsEnableCache && (expiresInt > minExpiresInt)) { var cacheResult = await _cache.GetAsync <PresignedUrlCache>(key); PresignedUrlCache cache = cacheResult.HasValue ? cacheResult.Value : null; //缓存中存在,且有效时间不低于10分钟 if (cache != null && cache.Type == type && cache.CreateTime > 0 && (cache.CreateTime + expiresInt - nowTime) > minExpiresInt && cache.Name == objectName && cache.BucketName == bucketName) { return(cache.Url); } } if (type == PresignedObjectType.Get) { //生成URL AccessMode accessMode = await this.GetObjectAclAsync(bucketName, objectName); if (accessMode == AccessMode.PublicRead || accessMode == AccessMode.PublicReadWrite) { objectUrl = $"{(Options.IsEnableHttps ? "https" : "http")}://{newBucketName}.cos.{Options.Region}.myqcloud.com{(objectName.StartsWith("/") ? "" : "/")}{objectName}"; } else { string uri = _client.GenerateSignURL(preSignatureStruct); if (uri != null) { objectUrl = uri.ToString(); } } } else { string uri = _client.GenerateSignURL(preSignatureStruct); if (uri != null) { objectUrl = uri.ToString(); } } if (string.IsNullOrEmpty(objectUrl)) { throw new Exception("Presigned get object url failed."); } //save cache if (Options.IsEnableCache && expiresInt > minExpiresInt) { PresignedUrlCache urlCache = new PresignedUrlCache() { Url = objectUrl, CreateTime = nowTime, Name = objectName, BucketName = bucketName, Type = type }; int randomSec = new Random().Next(5, 30); await _cache.SetAsync(key, urlCache, TimeSpan.FromSeconds(expiresInt + randomSec)); } return(objectUrl); }