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