Skip to content

Commit fb6fe9d

Browse files
committed
Fixed issue calling UploadPart with an unseekable stream and disabling checksum failing.
1 parent f8af87d commit fb6fe9d

File tree

3 files changed

+142
-1
lines changed

3 files changed

+142
-1
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"services": [
3+
{
4+
"serviceName": "S3",
5+
"type": "patch",
6+
"changeLogMessages": [
7+
"Fixed issue calling UploadPart with an unseekable stream and disabling checksum failing."
8+
]
9+
}
10+
]
11+
}

sdk/src/Services/S3/Custom/Internal/AmazonS3PostMarshallHandler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ private static void SetStreamChecksum(UploadPartRequest uploadPartRequest, IRequ
125125
if (uploadPartRequest.InputStream != null)
126126
{
127127
// Wrap input stream in partial wrapper (to upload only part of the stream)
128-
var partialStream = new PartialWrapperStream(uploadPartRequest.InputStream, uploadPartRequest.PartSize.GetValueOrDefault());
128+
var partialStream = GetStreamWithLength(uploadPartRequest.InputStream, uploadPartRequest.PartSize.GetValueOrDefault());
129129
if (partialStream.Length > 0 && !(uploadPartRequest.DisablePayloadSigning ?? false))
130130
request.UseChunkEncoding = uploadPartRequest.UseChunkEncoding;
131131
if (!request.Headers.ContainsKey(HeaderKeys.ContentLengthHeader))
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
using System.IO;
2+
using System.Text;
3+
using Microsoft.VisualStudio.TestTools.UnitTesting;
4+
5+
using Amazon.S3;
6+
using Amazon.S3.Model;
7+
using Amazon.S3.Util;
8+
using System.Threading.Tasks;
9+
10+
namespace AWSSDK_DotNet.IntegrationTests.Tests.S3
11+
{
12+
[TestClass]
13+
public class PutUnseekableStreamTests : TestBase<AmazonS3Client>
14+
{
15+
private static string bucketName;
16+
17+
[ClassInitialize()]
18+
public static void Initialize(TestContext a)
19+
{
20+
StreamWriter writer = File.CreateText("PutObjectFile.txt");
21+
writer.Write("This is some sample text.!!");
22+
writer.Close();
23+
24+
bucketName = S3TestUtils.CreateBucketWithWait(Client, true);
25+
}
26+
27+
[ClassCleanup]
28+
public static void ClassCleanup()
29+
{
30+
AmazonS3Util.DeleteS3BucketWithObjects(Client, bucketName);
31+
BaseClean();
32+
}
33+
34+
[TestMethod]
35+
[TestCategory("S3")]
36+
public async Task TestPutObject()
37+
{
38+
var stream = new CustomStream(Encoding.UTF8.GetBytes("Hello, S3!"));
39+
var putRequest = new PutObjectRequest
40+
{
41+
BucketName = bucketName,
42+
Key = "put-object-unseekable-test.txt",
43+
InputStream = stream,
44+
DisablePayloadSigning = true
45+
};
46+
47+
await Client.PutObjectAsync(putRequest);
48+
49+
var getRequest = new GetObjectRequest
50+
{
51+
BucketName = bucketName,
52+
Key = "put-object-unseekable-test.txt"
53+
};
54+
using (var getResponse = await Client.GetObjectAsync(getRequest))
55+
{
56+
using (var reader = new StreamReader(getResponse.ResponseStream))
57+
{
58+
var content = reader.ReadToEnd();
59+
Assert.AreEqual("Hello, S3!", content);
60+
}
61+
}
62+
}
63+
64+
[TestMethod]
65+
[TestCategory("S3")]
66+
public async Task TestUploadPart()
67+
{
68+
var stream = new CustomStream(Encoding.UTF8.GetBytes("Hello, S3!"));
69+
70+
var initiateMultipartUploadRequest = new InitiateMultipartUploadRequest
71+
{
72+
BucketName = bucketName,
73+
Key = "upload-part-unseekable-test.txt"
74+
};
75+
76+
var initiateMultipartUploadResponse = await Client.InitiateMultipartUploadAsync(initiateMultipartUploadRequest);
77+
78+
var uploadPartRequest = new UploadPartRequest
79+
{
80+
BucketName = bucketName,
81+
Key = "upload-part-unseekable-test.txt",
82+
UploadId = initiateMultipartUploadResponse.UploadId,
83+
PartNumber = 1,
84+
PartSize = stream.Length,
85+
InputStream = stream,
86+
DisablePayloadSigning = true,
87+
IsLastPart = true,
88+
};
89+
90+
91+
var uploadPartResponse = await Client.UploadPartAsync(uploadPartRequest);
92+
93+
var completeMultipartUploadRequest = new CompleteMultipartUploadRequest
94+
{
95+
BucketName = bucketName,
96+
Key = "upload-part-unseekable-test.txt",
97+
UploadId = initiateMultipartUploadResponse.UploadId
98+
};
99+
100+
completeMultipartUploadRequest.AddPartETags(uploadPartResponse);
101+
102+
await Client.CompleteMultipartUploadAsync(completeMultipartUploadRequest);
103+
104+
var getRequest = new GetObjectRequest
105+
{
106+
BucketName = bucketName,
107+
Key = "upload-part-unseekable-test.txt"
108+
};
109+
using (var getResponse = await Client.GetObjectAsync(getRequest))
110+
{
111+
using (var reader = new StreamReader(getResponse.ResponseStream))
112+
{
113+
var content = reader.ReadToEnd();
114+
Assert.AreEqual("Hello, S3!", content);
115+
}
116+
}
117+
}
118+
119+
120+
public class CustomStream : MemoryStream
121+
{
122+
public CustomStream(byte[] buffer) : base(buffer)
123+
{
124+
}
125+
126+
public override bool CanSeek => false;
127+
128+
}
129+
}
130+
}

0 commit comments

Comments
 (0)