Skip to content

Commit 9b3576f

Browse files
authored
[V3] Update HTTP handler to handle scenario where content stream position is not zero (#3944)
1 parent ad2bfa7 commit 9b3576f

File tree

3 files changed

+91
-2
lines changed

3 files changed

+91
-2
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"core": {
3+
"updateMinimum": true,
4+
"type": "patch",
5+
"changeLogMessages": [
6+
"Update HTTP handler to handle scenario where content stream position is not zero (https://github.com/aws/aws-sdk-net/issues/3941)"
7+
]
8+
}
9+
}

sdk/src/Core/Amazon.Runtime/Pipeline/HttpHandler/HttpHandler.cs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,17 @@ private void WriteContentToRequestBody(TRequestContent requestContent,
445445
}
446446
else
447447
{
448-
originalStream = wrappedRequest.ContentStream;
448+
// If the current position for the ContentStream is not at the beginning, we need to handle it
449+
// before wrapping it during GetInputStream.
450+
if (wrappedRequest.ContentStream.CanSeek && wrappedRequest.ContentStream.Position != 0)
451+
{
452+
var size = wrappedRequest.ContentStream.Length - wrappedRequest.ContentStream.Position;
453+
originalStream = new PartialReadOnlyWrapperStream(wrappedRequest.ContentStream, size);
454+
}
455+
else
456+
{
457+
originalStream = wrappedRequest.ContentStream;
458+
}
449459
}
450460

451461
var callback = ((Amazon.Runtime.Internal.IAmazonWebServiceRequest)wrappedRequest.OriginalRequest).StreamUploadProgressCallback;
@@ -492,7 +502,17 @@ private async System.Threading.Tasks.Task WriteContentToRequestBodyAsync(TReques
492502
}
493503
else
494504
{
495-
originalStream = wrappedRequest.ContentStream;
505+
// If the current position for the ContentStream is not at the beginning, we need to handle it
506+
// before wrapping it during GetInputStream.
507+
if (wrappedRequest.ContentStream.CanSeek && wrappedRequest.ContentStream.Position != 0)
508+
{
509+
var size = wrappedRequest.ContentStream.Length - wrappedRequest.ContentStream.Position;
510+
originalStream = new PartialReadOnlyWrapperStream(wrappedRequest.ContentStream, size);
511+
}
512+
else
513+
{
514+
originalStream = wrappedRequest.ContentStream;
515+
}
496516
}
497517

498518
var callback = ((Amazon.Runtime.Internal.IAmazonWebServiceRequest)wrappedRequest.OriginalRequest).StreamUploadProgressCallback;

sdk/test/NetStandard/IntegrationTests/IntegrationTests/S3/PutObjectTests.cs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,66 @@ public async Task PutObjectWithoutContentEncoding(bool useChunkEncoding)
186186
Assert.Null(headers.ContentEncoding);
187187
}
188188

189+
/// <summary>
190+
/// Reported in https://github.com/aws/aws-sdk-net/issues/3941
191+
/// </summary>
192+
[Fact]
193+
public async Task HandlesFileStreamWithoutAutoReset()
194+
{
195+
var tempFile = Path.GetTempFileName();
196+
try
197+
{
198+
using (var writeFs = new FileStream(tempFile, FileMode.Create, FileAccess.Write))
199+
{
200+
var data = new byte[]
201+
{
202+
0x01, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
203+
0x00, 0x00, 0x00, 0x00, 0x01, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
204+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
205+
};
206+
207+
await writeFs.WriteAsync(data, 0, data.Length);
208+
}
209+
210+
using var fileStream = File.Open(tempFile, FileMode.Open, FileAccess.Read, FileShare.Read);
211+
using var reader = new BinaryReader(fileStream);
212+
213+
fileStream.Position = 10;
214+
var compression = reader.ReadInt16();
215+
216+
fileStream.Seek(8, SeekOrigin.Current);
217+
var bIsLast = reader.ReadBoolean();
218+
219+
fileStream.Seek(4, SeekOrigin.Current);
220+
221+
var putRequest = new PutObjectRequest
222+
{
223+
BucketName = bucketName,
224+
Key = "upload-test/0D-0",
225+
ContentType = "application/octet-stream",
226+
InputStream = fileStream,
227+
AutoResetStreamPosition = false,
228+
};
229+
putRequest.Metadata.Add("compression", compression.ToString());
230+
putRequest.Metadata.Add("islast", bIsLast ? "T" : "F");
231+
232+
var putResponse = await Client.PutObjectAsync(putRequest);
233+
Assert.Equal(HttpStatusCode.OK, putResponse.HttpStatusCode);
234+
235+
var getResponse = await Client.GetObjectMetadataAsync(bucketName, putRequest.Key);
236+
Assert.Equal(HttpStatusCode.OK, getResponse.HttpStatusCode);
237+
Assert.NotNull(getResponse.Metadata);
238+
Assert.True(getResponse.Metadata.Count > 0);
239+
}
240+
finally
241+
{
242+
if (File.Exists(tempFile))
243+
{
244+
File.Delete(tempFile);
245+
}
246+
}
247+
}
248+
189249
/// <summary>
190250
/// Reported in https://github.com/aws/aws-sdk-net/issues/3629
191251
/// </summary>

0 commit comments

Comments
 (0)