Skip to content

Commit ae2ca19

Browse files
committed
Ensure KeyMarker is URL decoded before sending to AWS
Fixes issue #66
1 parent a7312da commit ae2ca19

File tree

2 files changed

+69
-2
lines changed

2 files changed

+69
-2
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using Genbox.ProviderTests.Misc;
2+
using Genbox.SimpleS3.Core.Abstracts;
3+
using Genbox.SimpleS3.Core.Enums;
4+
using Genbox.SimpleS3.Core.Extensions;
5+
using Genbox.SimpleS3.Core.Network.Responses.S3Types;
6+
using Genbox.SimpleS3.Utility.Shared;
7+
8+
namespace Genbox.ProviderTests.Issues;
9+
10+
public class AmazonIssues : TestBase
11+
{
12+
/// <summary>https://github.com/Genbox/SimpleS3/issues/66</summary>
13+
[Theory]
14+
[MultipleProviders(S3Provider.AmazonS3)]
15+
public async Task Issue66(S3Provider provider, string bucket, ISimpleClient client)
16+
{
17+
//Issue: When setting EncodingType to Url, it creates an infinite loop
18+
//Investigation: TODO
19+
//Resolution: TODO
20+
21+
string[] names = ["a%20.txt", "a&1.txt", "a(1).exe", "folder1/a%20.txt"];
22+
23+
await CreateTempBucketAsync(provider, client, async tempBucket =>
24+
{
25+
//Create objects
26+
foreach (string name in names)
27+
await client.PutObjectStringAsync(tempBucket, name, "");
28+
29+
//List them while forcing pagination
30+
List<S3Version> objects = await ToListAsync(client.ListAllObjectVersionsAsync(tempBucket, r =>
31+
{
32+
r.MaxKeys = 2;
33+
r.EncodingType = EncodingType.Url;
34+
}));
35+
36+
Assert.Equal(4, objects.Count);
37+
});
38+
}
39+
40+
private static async Task<List<T>> ToListAsync<T>(IAsyncEnumerable<T> list)
41+
{
42+
List<T> res = new List<T>();
43+
44+
await foreach (var item in list)
45+
res.Add(item);
46+
47+
return res;
48+
}
49+
}

Src/SimpleS3.Core/Extensions/ObjectClientExtensions.cs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
using System.Runtime.CompilerServices;
22
using System.Text;
3+
using System.Web;
34
using Genbox.SimpleS3.Core.Abstracts.Clients;
45
using Genbox.SimpleS3.Core.Builders;
56
using Genbox.SimpleS3.Core.Common.Exceptions;
67
using Genbox.SimpleS3.Core.Common.Misc;
78
using Genbox.SimpleS3.Core.Common.Validation;
9+
using Genbox.SimpleS3.Core.Enums;
810
using Genbox.SimpleS3.Core.Internals.Pools;
911
using Genbox.SimpleS3.Core.Network.Requests.Objects;
1012
using Genbox.SimpleS3.Core.Network.Requests.S3Types;
@@ -98,10 +100,14 @@ public static async IAsyncEnumerable<S3DeleteError> DeleteAllObjectsAsync(this I
98100

99101
if (response.IsTruncated)
100102
{
101-
string localToken = response.NextContinuationToken;
103+
string cToken = response.NextContinuationToken;
104+
105+
if (response.EncodingType == EncodingType.Url)
106+
cToken = HttpUtility.UrlDecode(cToken);
107+
102108
responseTask = client.ListObjectsAsync(bucketName, req =>
103109
{
104-
req.ContinuationToken = localToken;
110+
req.ContinuationToken = cToken;
105111
configure?.Invoke(req);
106112
}, token);
107113
}
@@ -163,6 +169,10 @@ public static async IAsyncEnumerable<S3DeleteError> DeleteAllObjectVersionsAsync
163169
if (response.IsTruncated)
164170
{
165171
string keyMarker = response.NextKeyMarker;
172+
173+
if (response.EncodingType == EncodingType.Url)
174+
keyMarker = HttpUtility.UrlDecode(keyMarker);
175+
166176
responseTask = client.ListObjectVersionsAsync(bucketName, req =>
167177
{
168178
req.KeyMarker = keyMarker;
@@ -264,6 +274,10 @@ public static async IAsyncEnumerable<S3Object> ListAllObjectsAsync(this IObjectC
264274
if (response.IsTruncated)
265275
{
266276
string cToken = response.NextContinuationToken;
277+
278+
if (response.EncodingType == EncodingType.Url)
279+
cToken = HttpUtility.UrlDecode(cToken);
280+
267281
responseTask = client.ListObjectsAsync(bucketName, req =>
268282
{
269283
req.ContinuationToken = cToken;
@@ -315,6 +329,10 @@ public static async IAsyncEnumerable<S3Version> ListAllObjectVersionsAsync(this
315329
if (response.IsTruncated)
316330
{
317331
string keyMarker = response.NextKeyMarker;
332+
333+
if (response.EncodingType == EncodingType.Url)
334+
keyMarker = HttpUtility.UrlDecode(keyMarker);
335+
318336
responseTask = client.ListObjectVersionsAsync(bucketName, req =>
319337
{
320338
req.KeyMarker = keyMarker;

0 commit comments

Comments
 (0)