Skip to content

Commit

Permalink
RemoveIncompleteUpload with Args.
Browse files Browse the repository at this point in the history
  • Loading branch information
BigUstad committed Dec 3, 2020
2 parents a61432f + 1982b4b commit 0742543
Show file tree
Hide file tree
Showing 5 changed files with 230 additions and 79 deletions.
26 changes: 16 additions & 10 deletions Docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -1711,9 +1711,9 @@ catch(MinioException e)
```

<a name="presignedPutObject"></a>
### PresignedPutObjectAsync(string bucketName, string objectName, int expiresInt)
### PresignedPutObjectAsync(PresignedPutObjectArgs args)

`Task<string> PresignedPutObjectAsync(string bucketName, string objectName, int expiresInt)`
`Task<string> PresignedPutObjectAsync(PresignedPutObjectArgs args)`

Generates a presigned URL for HTTP PUT operations. Browsers/Mobile clients may point to this URL to upload objects directly to a bucket even if it is private. This presigned URL can have an associated expiration time in seconds after which it is no longer operational. The default expiry is set to 7 days.

Expand All @@ -1722,9 +1722,7 @@ __Parameters__

|Param | Type | Description |
|:--- |:--- |:--- |
| ``bucketName`` | _string_ | Name of the bucket |
| ``objectName`` | _string_ | Object name in the bucket |
| ``expiresInt`` | _int_ | Expiry in seconds. Default expiry is set to 7 days. |
| ``args`` | _PresignedPutObjectArgs_ | PresignedPutObjectArgs arguments object with bucket, object names & expiry |

| Return Type | Exceptions |
|:--- |:--- |
Expand All @@ -1740,7 +1738,11 @@ __Example__
```cs
try
{
String url = await minioClient.PresignedPutObjectAsync("mybucket", "myobject", 60 * 60 * 24);
PresignedPutObjectArgs args = PresignedPutObjectArgs()
.WithBucket("mybucket")
.WithObject("myobject")
.WithExpiry(60 * 60 * 24);
String url = await minioClient.PresignedPutObjectAsync(args);
Console.WriteLine(url);
}
catch(MinioException e)
Expand All @@ -1750,9 +1752,9 @@ catch(MinioException e)
```

<a name="presignedPostPolicy"></a>
### PresignedPostPolicy(PostPolicy policy)
### PresignedPostPolicy(PresignedPostPolicyArgs args)

`Task<Dictionary<string, string>> PresignedPostPolicyAsync(PostPolicy policy)`
`Task<Dictionary<string, string>> PresignedPostPolicyAsync(PresignedPostPolicyArgs args)`

Allows setting policy conditions to a presigned URL for POST operations. Policies such as bucket name to receive object uploads, key name prefixes, expiry policy may be set.

Expand All @@ -1761,7 +1763,7 @@ __Parameters__

|Param | Type | Description |
|:--- |:--- |:--- |
| ``PostPolicy`` | _PostPolicy_ | Post policy of an object. |
| ``args`` | _PresignedPostPolicyArgs_ | PresignedPostPolicyArgs Arguments object includes bucket, object names & Post policy of an object. |


| Return Type | Exceptions |
Expand All @@ -1786,8 +1788,12 @@ try
policy.SetExpires(expiration.AddDays(10));
policy.SetKey("my-objectname");
policy.SetBucket("my-bucketname");
PresignedPostPolicyArgs args = PresignedPostPolicyArgs()
.WithBucket("my-bucketname")
.WithObject("my-objectname")
.WithPolicy(policy);

Dictionary<string, string> formData = minioClient.Api.PresignedPostPolicy(policy);
Dictionary<string, string> formData = minioClient.Api.PresignedPostPolicy(args);
string curlCommand = "curl ";
foreach (KeyValuePair<string, string> pair in formData)
{
Expand Down
22 changes: 17 additions & 5 deletions Minio.Functional.Tests/FunctionalTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@ public class FunctionalTest
private const string removeObjectSignature1 = "Task RemoveObjectAsync(string bucketName, string objectName, CancellationToken cancellationToken = default(CancellationToken))";
private const string removeObjectSignature2 = "Task<IObservable<DeleteError>> RemoveObjectAsync(string bucketName, IEnumerable<string> objectsList, CancellationToken cancellationToken = default(CancellationToken))";
private const string removeIncompleteUploadSignature = "Task RemoveIncompleteUploadAsync(RemoveIncompleteUploadArgs args, CancellationToken cancellationToken = default(CancellationToken))";
private const string presignedPutObjectSignature = "Task<string> PresignedPutObjectAsync(PresignedPutObjectArgs args)";
private const string presignedGetObjectSignature = "Task<string> PresignedGetObjectAsync(PresignedGetObjectArgs args)";
private const string presignedPutObjectSignature = "Task<string> PresignedPutObjectAsync(string bucketName, string objectName, int expiresInt)";
private const string presignedPostPolicySignature = "Task<Dictionary<string, string>> PresignedPostPolicyAsync(PostPolicy policy)";
private const string presignedPostPolicySignature = "Task<Dictionary<string, string>> PresignedPostPolicyAsync(PresignedPostPolicyArgs args)";
private const string getBucketPolicySignature = "Task<string> GetPolicyAsync(GetPolicyArgs args, CancellationToken cancellationToken = default(CancellationToken))";
private const string setBucketPolicySignature = "Task SetPolicyAsync(SetPolicyArgs args, CancellationToken cancellationToken = default(CancellationToken))";
private const string getBucketNotificationSignature = "Task<BucketNotification> GetBucketNotificationAsync(GetBucketNotificationsArgs args, CancellationToken cancellationToken = default(CancellationToken))";
Expand Down Expand Up @@ -2574,7 +2574,11 @@ internal async static Task PresignedPutObject_Test1(MinioClient minio)
{
await Setup_Test(minio, bucketName);
// Upload with presigned url
string presigned_url = await minio.PresignedPutObjectAsync(bucketName, objectName, 1000);
PresignedPutObjectArgs presignedPutObjectArgs = new PresignedPutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithExpiry(1000);
string presigned_url = await minio.PresignedPutObjectAsync(presignedPutObjectArgs);
await UploadObjectAsync(presigned_url, fileName);
// Get stats for object from server
StatObjectArgs statObjectArgs = new StatObjectArgs()
Expand Down Expand Up @@ -2629,7 +2633,11 @@ await minio.PutObjectAsync(bucketName,
.WithBucket(bucketName)
.WithObject(objectName);
ObjectStat stats = await minio.StatObjectAsync(statObjectArgs);
string presigned_url = await minio.PresignedPutObjectAsync(bucketName, objectName, 0);
PresignedPutObjectArgs presignedPutObjectArgs = new PresignedPutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithExpiry(0);
string presigned_url = await minio.PresignedPutObjectAsync(presignedPutObjectArgs);
}
catch (InvalidExpiryRangeException)
{
Expand Down Expand Up @@ -2692,7 +2700,11 @@ await minio.PutObjectAsync(bucketName,
fileName);
var pairs = new List<KeyValuePair<string, string>>();
string url = "https://s3.amazonaws.com/" + bucketName;
Tuple<string, System.Collections.Generic.Dictionary<string, string>> policyTuple = await minio.PresignedPostPolicyAsync(form);
PresignedPostPolicyArgs polArgs = new PresignedPostPolicyArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithPolicy(form);
Tuple<string, System.Collections.Generic.Dictionary<string, string>> policyTuple = await minio.PresignedPostPolicyAsync(polArgs);
var httpClient = new HttpClient();

using (var stream = File.OpenRead(fileName))
Expand Down
128 changes: 65 additions & 63 deletions Minio/ApiEndpoints/ObjectOperations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,9 @@ public partial class MinioClient : IObjectOperations
{
uploads = await this.GetMultipartUploadsListAsync(getArgs, cancellationToken).ConfigureAwait(false);
}
catch (Exception ex)
catch (Exception)
{
if (ex.GetType() == typeof(BucketNotFoundException))
{
isRunning = false;
continue;
}
throw;
throw;
}
if (uploads == null)
{
Expand Down Expand Up @@ -136,12 +131,8 @@ private async Task<Tuple<ListMultipartUploadsResult, List<Upload>>> GetMultipart
RestRequest request = await this.CreateRequest(args).ConfigureAwait(false);
response = await this.ExecuteAsync(this.NoErrorHandlers, request, cancellationToken).ConfigureAwait(false);
}
catch (Exception ex)
catch (Exception)
{
if (ex.GetType() == typeof(BucketNotFoundException))
{
return null;
}
throw;
}
GetMultipartUploadsListResponse getUploadResponse = new GetMultipartUploadsListResponse(response.StatusCode, response.Content);
Expand Down Expand Up @@ -175,7 +166,24 @@ private async Task RemoveUploadAsync(RemoveUploadArgs args, CancellationToken ca
ListIncompleteUploadsArgs listUploadArgs = new ListIncompleteUploadsArgs()
.WithBucket(args.BucketName)
.WithPrefix(args.ObjectName);
var uploads = await this.ListIncompleteUploads(listUploadArgs, cancellationToken)?.ToArray();

Upload[] uploads = null;
try
{
uploads = await this.ListIncompleteUploads(listUploadArgs, cancellationToken)?.ToArray();
}
catch (Exception ex)
{
//Bucket Not found. So, incomplete uploads are removed.
if (ex.GetType() != typeof(BucketNotFoundException))
{
throw ex;
}
}
if (uploads == null)
{
return;
}
foreach (var upload in uploads)
{
if(upload.Key.ToLower().Equals(args.ObjectName.ToLower()))
Expand Down Expand Up @@ -203,6 +211,39 @@ public async Task<string> PresignedGetObjectAsync(PresignedGetObjectArgs args)
}


/// <summary>
/// Presigned post policy
/// </summary>
/// <param name="args">PresignedPostPolicyArgs Arguments object encapsulating Policy, Expiry, Region, </param>
/// <returns>Tuple of URI and Policy Form data</returns>
public async Task<Tuple<string, Dictionary<string, string>>> PresignedPostPolicyAsync(PresignedPostPolicyArgs args)
{
string region = await this.GetRegion(args.BucketName);
args.Validate();
args = args.WithSessionToken(this.SessionToken)
.WithCredential(this.authenticator.GetCredentialString(DateTime.UtcNow, region))
.WithSignature(this.authenticator.PresignPostSignature(region, DateTime.UtcNow, args.Policy.Base64()))
.WithRegion(region);
this.SetTargetURL(RequestUtil.MakeTargetURL(this.BaseUrl, this.Secure, args.BucketName, args.Region, usePathStyle: false));
PresignedPostPolicyResponse policyResponse = new PresignedPostPolicyResponse(args, this.restClient.BaseUrl.AbsoluteUri);
return policyResponse.URIPolicyTuple;
}


/// <summary>
/// Presigned Put url -returns a presigned url to upload an object without credentials.URL can have a maximum expiry of
/// upto 7 days or a minimum of 1 second.
/// </summary>
/// <param name="args">PresignedPutObjectArgs Arguments Object which encapsulates bucket, object names, expiry</param>
/// <returns></returns>
public async Task<string> PresignedPutObjectAsync(PresignedPutObjectArgs args)
{
args.Validate();
RestRequest request = await this.CreateRequest(args).ConfigureAwait(false);
return this.authenticator.PresignURL(this.restClient, request, args.Expiry, Region, this.SessionToken);
}


/// <summary>
/// Get an object. The object will be streamed to the callback given by the user.
/// </summary>
Expand Down Expand Up @@ -1250,14 +1291,14 @@ public async Task<string> PresignedGetObjectAsync(string bucketName, string obje
/// <param name="objectName">Key of object to retrieve</param>
/// <param name="expiresInt">Expiration time in seconds</param>
/// <returns></returns>
[Obsolete("Use PresignedPutObjectAsync method with PresignedPutObjectArgs object.")]
public async Task<string> PresignedPutObjectAsync(string bucketName, string objectName, int expiresInt)
{
if (!utils.IsValidExpiry(expiresInt))
{
throw new InvalidExpiryRangeException("expiry range should be between 1 and " + Constants.DefaultExpiryTime.ToString());
}
var request = await this.CreateRequest(Method.PUT, bucketName, objectName: objectName).ConfigureAwait(false);
return this.authenticator.PresignURL(this.restClient, request, expiresInt, Region, this.SessionToken);
PresignedPutObjectArgs args = new PresignedPutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithExpiry(expiresInt);
return await this.PresignedPutObjectAsync(args);
}

/// <summary>
Expand All @@ -1267,50 +1308,11 @@ public async Task<string> PresignedPutObjectAsync(string bucketName, string obje
/// <returns></returns>
public async Task<Tuple<string, Dictionary<string, string>>> PresignedPostPolicyAsync(PostPolicy policy)
{
string region = null;

if (!policy.IsBucketSet())
{
throw new ArgumentException("bucket should be set", nameof(policy));
}

if (!policy.IsKeySet())
{
throw new ArgumentException("key should be set", nameof(policy));
}

if (!policy.IsExpirationSet())
{
throw new ArgumentException("expiration should be set", nameof(policy));
}

// Initialize a new client.
if (!BucketRegionCache.Instance.Exists(policy.Bucket))
{
region = await BucketRegionCache.Instance.Update(this, policy.Bucket).ConfigureAwait(false);
}

if (region == null)
{
region = BucketRegionCache.Instance.Region(policy.Bucket);
}

// Set Target URL
Uri requestUrl = RequestUtil.MakeTargetURL(this.BaseUrl, this.Secure, bucketName: policy.Bucket, region: region, usePathStyle: false);
SetTargetURL(requestUrl);
DateTime signingDate = DateTime.UtcNow;

policy.SetAlgorithm("AWS4-HMAC-SHA256");
policy.SetCredential(this.authenticator.GetCredentialString(signingDate, region));
policy.SetDate(signingDate);
policy.SetSessionToken(this.SessionToken);
string policyBase64 = policy.Base64();
string signature = this.authenticator.PresignPostSignature(region, signingDate, policyBase64);

policy.SetPolicy(policyBase64);
policy.SetSignature(signature);

return Tuple.Create(this.restClient.BaseUrl.AbsoluteUri, policy.GetFormData());
PresignedPostPolicyArgs args = new PresignedPostPolicyArgs()
.WithBucket(policy.Bucket)
.WithObject(policy.Key)
.WithPolicy(policy);
return await this.PresignedPostPolicyAsync(args);
}
}
}
Loading

0 comments on commit 0742543

Please sign in to comment.