private async Task <HttpRequestMessage> PreparePutRequestAsync(byte[] byteArr, string filename) { AwsV4SignatureCalculator calculator = new AwsV4SignatureCalculator(_secretKey, _service, _region); HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Put, new Uri($"{_protocol}://{_endpoint}/{_bucketName}/{_supPath}/{filename}")); DateTime now = DateTime.UtcNow; var dateTimeStamp = now.ToString(AwsV4SignatureCalculator.Iso8601DateTimeFormat, CultureInfo.InvariantCulture); var dateStamp = now.ToString(AwsV4SignatureCalculator.Iso8601DateFormat, CultureInfo.InvariantCulture); ByteArrayContent content = new ByteArrayContent(byteArr); requestMessage.Content = content; var hash = await AwsV4SignatureCalculator.GetPayloadHashAsync(requestMessage); string[] headers = AddStandardHeadersToRequest(requestMessage, dateTimeStamp, hash); string signature = await calculator.CalculateSignatureAsync(requestMessage, headers, now); string authHeader = GetAuthHeader(dateStamp, headers, signature); requestMessage.Headers.TryAddWithoutValidation("Authorization", authHeader); return(requestMessage); }
/// <summary> /// Returns presigned URL with defined expire time /// </summary> /// <param name="v"></param> /// <returns></returns> public string GetPresignedUrl(string filename, TimeSpan expirationTime = default) { if (expirationTime == default) { expirationTime = TimeSpan.FromHours(_presignedUrlExpirationInHours); } var formatedPath = FormatePath(filename); var expiresOn = DateTime.UtcNow + expirationTime; var period = Convert.ToInt64((expiresOn.ToUniversalTime() - DateTime.UtcNow).TotalSeconds); var requestDateTime = DateTime.UtcNow; var dateTimeStamp = requestDateTime.ToString(AwsV4SignatureCalculator.Iso8601DateTimeFormat, CultureInfo.InvariantCulture); var requestDateTimeStamp = requestDateTime.ToString(AwsV4SignatureCalculator.Iso8601DateFormat, CultureInfo.InvariantCulture); var queryParams = new StringBuilder(); queryParams.AppendFormat("{0}={1}", AwsV4SignatureCalculator.X_Amz_Algorithm, UrlHelper.UrlEncode("AWS4-HMAC-SHA256")); queryParams.AppendFormat( "&{0}={1}", AwsV4SignatureCalculator.X_Amz_Credential, UrlHelper.UrlEncode($"{_accessKey}/{requestDateTimeStamp}/{_region}/{_service}/aws4_request")); queryParams.AppendFormat("&{0}={1}", AwsV4SignatureCalculator.X_Amz_Date, UrlHelper.UrlEncode(dateTimeStamp)); queryParams.AppendFormat("&{0}={1}", AwsV4SignatureCalculator.X_Amz_Expires, UrlHelper.UrlEncode(period.ToString())); queryParams.AppendFormat("&{0}={1}", AwsV4SignatureCalculator.X_Amz_SignedHeaders, UrlHelper.UrlEncode("host")); var endpointUri = new UriBuilder($"{_protocol}://{_endpoint}/{_bucketName}/{_supPath}/{formatedPath}") { Query = queryParams.ToString() }; HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, endpointUri.Uri); requestMessage.Headers.Add("Host", _endpoint); string[] headers = { "host" }; AwsV4SignatureCalculator calculator = new AwsV4SignatureCalculator(_secretKey, _service, _region); string signature = calculator.CalculateSignatureAsync(requestMessage, headers, requestDateTime, true).Result; // remove unnecessary port endpointUri.Port = -1; var urlStringBuilder = new StringBuilder(endpointUri.ToString()); urlStringBuilder.AppendFormat("&{0}={1}", AwsV4SignatureCalculator.X_Amz_Signature, UrlHelper.UrlEncode(signature)); var presignedUrl = urlStringBuilder.ToString(); return(presignedUrl); }