/// <summary>
/// Marshalls the parameters for a presigned url for a preferred signing protocol.
/// </summary>
/// <param name="getPreSignedUrlRequest"></param>
/// <param name="accessKey"></param>
/// <param name="token"></param>
/// <param name="aws4Signing">
/// True if AWS4 signing will be used; if the expiry period in the request exceeds the
/// maximum allowed for AWS4 (one week), an ArgumentException is thrown.
/// </param>
/// <returns></returns>
private static IRequest Marshall(GetPreSignedUrlRequest getPreSignedUrlRequest,
string accessKey,
string token,
bool aws4Signing)
{
IRequest request = new DefaultRequest(getPreSignedUrlRequest, "AmazonS3");
request.HttpMethod = getPreSignedUrlRequest.Verb.ToString();
var headers = getPreSignedUrlRequest.Headers;
foreach (var key in headers.Keys)
request.Headers[key] = headers[key];
AmazonS3Util.SetMetadataHeaders(request, getPreSignedUrlRequest.Metadata);
if (!string.IsNullOrEmpty(token))
request.Headers[HeaderKeys.XAmzSecurityTokenHeader] = token;
if (getPreSignedUrlRequest.ServerSideEncryptionMethod != null && getPreSignedUrlRequest.ServerSideEncryptionMethod != ServerSideEncryptionMethod.None)
request.Headers.Add(HeaderKeys.XAmzServerSideEncryptionHeader, S3Transforms.ToStringValue(getPreSignedUrlRequest.ServerSideEncryptionMethod));
if (getPreSignedUrlRequest.IsSetServerSideEncryptionCustomerMethod())
request.Headers.Add(HeaderKeys.XAmzSSECustomerAlgorithmHeader, getPreSignedUrlRequest.ServerSideEncryptionCustomerMethod);
if (getPreSignedUrlRequest.IsSetServerSideEncryptionKeyManagementServiceKeyId())
request.Headers.Add(HeaderKeys.XAmzServerSideEncryptionAwsKmsKeyIdHeader, getPreSignedUrlRequest.ServerSideEncryptionKeyManagementServiceKeyId);
var queryParameters = request.Parameters;
var uriResourcePath = new StringBuilder("/");
if (!string.IsNullOrEmpty(getPreSignedUrlRequest.BucketName))
uriResourcePath.Append(S3Transforms.ToStringValue(getPreSignedUrlRequest.BucketName));
if (!string.IsNullOrEmpty(getPreSignedUrlRequest.Key))
{
if (uriResourcePath.Length > 1)
uriResourcePath.Append("/");
uriResourcePath.Append(S3Transforms.ToStringValue(getPreSignedUrlRequest.Key));
}
var baselineTime = aws4Signing ? DateTime.UtcNow : new DateTime(1970, 1, 1);
var expires = Convert.ToInt64((getPreSignedUrlRequest.Expires.ToUniversalTime() - baselineTime).TotalSeconds);
if (aws4Signing && expires > AWS4PreSignedUrlSigner.MaxAWS4PreSignedUrlExpiry)
{
var msg = string.Format(CultureInfo.InvariantCulture, "The maximum expiry period for a presigned url using AWS4 signing is {0} seconds",
AWS4PreSignedUrlSigner.MaxAWS4PreSignedUrlExpiry);
throw new ArgumentException(msg);
}
queryParameters.Add(aws4Signing ? "X-Amz-Expires" : "Expires", expires.ToString(CultureInfo.InvariantCulture));
if (!string.IsNullOrEmpty(token))
queryParameters.Add("x-amz-security-token", token);
if (!aws4Signing)
queryParameters.Add("AWSAccessKeyId", accessKey);
if (getPreSignedUrlRequest.IsSetVersionId())
request.AddSubResource("versionId", S3Transforms.ToStringValue(getPreSignedUrlRequest.VersionId));
var responseHeaderOverrides = getPreSignedUrlRequest.ResponseHeaderOverrides;
if (!string.IsNullOrEmpty(responseHeaderOverrides.CacheControl))
queryParameters.Add("response-cache-control", responseHeaderOverrides.CacheControl);
if (!string.IsNullOrEmpty(responseHeaderOverrides.ContentType))
queryParameters.Add("response-content-type", responseHeaderOverrides.ContentType);
if (!string.IsNullOrEmpty(responseHeaderOverrides.ContentLanguage))
queryParameters.Add("response-content-language", responseHeaderOverrides.ContentLanguage);
if (!string.IsNullOrEmpty(responseHeaderOverrides.Expires))
queryParameters.Add("response-expires", responseHeaderOverrides.Expires);
if (!string.IsNullOrEmpty(responseHeaderOverrides.ContentDisposition))
queryParameters.Add("response-content-disposition", responseHeaderOverrides.ContentDisposition);
if (!string.IsNullOrEmpty(responseHeaderOverrides.ContentEncoding))
queryParameters.Add("response-content-encoding", responseHeaderOverrides.ContentEncoding);
request.ResourcePath = uriResourcePath.ToString();
request.UseQueryString = true;
return request;
}