Skip to content

Commit

Permalink
Fix presign operations to honor request params (#216)
Browse files Browse the repository at this point in the history
  • Loading branch information
poornas authored and kannappanr committed Mar 18, 2018
1 parent b7f628f commit ad23851
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 6 deletions.
9 changes: 7 additions & 2 deletions Minio.Functional.Tests/FunctionalTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,6 @@ public static void Main(string[] args)

// Test Presigned Get/Put operations
PresignedGetObject_Test1(minioClient).Wait();
PresignedGetObject_Test1(minioClient).Wait();
PresignedGetObject_Test2(minioClient).Wait();
PresignedGetObject_Test3(minioClient).Wait();
PresignedPutObject_Test1(minioClient).Wait();
Expand Down Expand Up @@ -1779,7 +1778,7 @@ private async static Task PresignedGetObject_Test3(MinioClient minio)
{"bucketName", bucketName},
{"objectName", objectName},
{"expiresInt", expiresInt.ToString()},
{"reqParams", "response-content-type:application/json"}
{"reqParams", "response-content-type:application/json,response-content-disposition:attachment;filename=MyDocument.json;"}
};
try
{
Expand All @@ -1792,15 +1791,21 @@ await minio.PutObjectAsync(bucketName,
ObjectStat stats = await minio.StatObjectAsync(bucketName, objectName);
Dictionary<string, string> reqParams = new Dictionary<string,string>();
reqParams["response-content-type"] = "application/json";
reqParams["response-content-disposition"] = "attachment;filename=MyDocument.json;";
string presigned_url = await minio.PresignedGetObjectAsync(bucketName, objectName, 1000, reqParams);
WebRequest httpRequest = WebRequest.Create(presigned_url);
var response = (HttpWebResponse)(await Task<WebResponse>.Factory.FromAsync(httpRequest.BeginGetResponse, httpRequest.EndGetResponse, null));
Assert.AreEqual(response.ContentType,reqParams["response-content-type"]);
Assert.AreEqual(response.Headers["Content-Disposition"],"attachment;filename=MyDocument.json;");
Assert.AreEqual(response.Headers["Content-Type"],"application/json");
Assert.AreEqual(response.Headers["Content-Length"],stats.Size.ToString());
Stream stream = response.GetResponseStream();
var fileStream = File.Create(downloadFile);
stream.CopyTo(fileStream);
fileStream.Dispose();
FileInfo writtenInfo = new FileInfo(downloadFile);
long file_read_size = writtenInfo.Length;

// Compare size of file downloaded with presigned curl request and actual object size on server
Assert.AreEqual(file_read_size, stats.Size);

Expand Down
11 changes: 7 additions & 4 deletions Minio/V4Authenticator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,9 @@ public string PresignURL(IRestClient client, IRestRequest request, int expires)
+ "&";
requestQuery += "X-Amz-SignedHeaders=host";

string canonicalRequest = GetPresignCanonicalRequest(client, request, requestQuery);
SortedDictionary<string,string> headersToSign = GetHeadersToSign(request);
string canonicalRequest = GetPresignCanonicalRequest(client, request, requestQuery, headersToSign);
string headers = string.Join("&", headersToSign.Select(p => p.Key + "=" + utils.UrlEncode(p.Value)));
byte[] canonicalRequestBytes = System.Text.Encoding.UTF8.GetBytes(canonicalRequest);
string canonicalRequestHash = BytesToHex(ComputeSha256(canonicalRequestBytes));
string stringToSign = GetStringToSign(this.Region, signingDate, canonicalRequestHash);
Expand All @@ -288,7 +290,7 @@ public string PresignURL(IRestClient client, IRestRequest request, int expires)
string signature = BytesToHex(signatureBytes);

// Return presigned url.
return client.BaseUrl + path + "?" + requestQuery + "&X-Amz-Signature=" + signature;
return client.BaseUrl + path + "?" + requestQuery + "&" + headers + "&X-Amz-Signature=" + signature;
}

/// <summary>
Expand All @@ -298,7 +300,7 @@ public string PresignURL(IRestClient client, IRestRequest request, int expires)
/// <param name="request">Instantiated request object</param>
/// <param name="requestQuery">Additional request query params</param>
/// <returns>Presigned canonical request</returns>
private string GetPresignCanonicalRequest(IRestClient client, IRestRequest request, string requestQuery)
private string GetPresignCanonicalRequest(IRestClient client, IRestRequest request, string requestQuery, SortedDictionary<string,string> headersToSign)
{
LinkedList<string> canonicalStringList = new LinkedList<string>();
// METHOD
Expand All @@ -310,7 +312,8 @@ private string GetPresignCanonicalRequest(IRestClient client, IRestRequest reque
path = "/" + path;
}
canonicalStringList.AddLast(path);
canonicalStringList.AddLast(requestQuery);
String query = headersToSign.Aggregate(requestQuery, (pv, cv) => $"{pv}&{utils.UrlEncode((string)cv.Key)}={utils.UrlEncode((string)cv.Value)}");
canonicalStringList.AddLast(query);
if (client.BaseUrl.Port > 0 && (client.BaseUrl.Port != 80 && client.BaseUrl.Port != 443))
{
canonicalStringList.AddLast("host:" + client.BaseUrl.Host + ":" + client.BaseUrl.Port);
Expand Down

0 comments on commit ad23851

Please sign in to comment.