Closed
Description
Describe the bug
I've tracked it down to this was working in 3.7.411.7 but broken in any future release. Due to how you tag releases and different client versions it's pretty hard to track down...
System.Net.Http.HttpRequestException
Sent 298 request content bytes, but Content-Length promised 305.
at System.Net.Http.HttpConnection.SendRequestContentAsync(HttpRequestMessage request, HttpContentWriteStream stream, Boolean async, CancellationToken cancellationToken)
at System.Net.Http.HttpConnection.SendRequestContentWithExpect100ContinueAsync(HttpRequestMessage request, Task`1 allowExpect100ToContinueTask, HttpContentWriteStream stream, Timer expect100Timer, Boolean async, CancellationToken cancellationToken)
at System.Net.Http.HttpConnection.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.<SendAsync>g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken)
at Amazon.Runtime.HttpWebRequestMessage.GetResponseAsync(CancellationToken cancellationToken)
at Amazon.Runtime.Internal.HttpHandler`1.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.RedirectHandler.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.Unmarshaller.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.S3.Internal.AmazonS3ResponseHandler.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.ErrorHandler.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.ErrorHandler.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.CallbackHandler.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.Signer.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.S3.Internal.S3Express.S3ExpressPreSigner.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.EndpointDiscoveryHandler.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.EndpointDiscoveryHandler.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.CredentialsRetriever.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.RetryHandler.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.RetryHandler.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.CallbackHandler.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.CallbackHandler.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.S3.Internal.AmazonS3ExceptionHandler.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.ErrorCallbackHandler.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.MetricsHandler.InvokeAsync[T](IExecutionContext executionContext)
at Foundatio.Storage.S3FileStorage.SaveFileAsync(String path, Stream stream, CancellationToken cancellationToken) in /Users/blakeniemyjski/code/Foundatio.AWS/src/Foundatio.AWS/Storage/S3FileStorage.cs:line 220
Regression Issue
- Select this option if this issue appears to be a regression.
Expected Behavior
I should be able to post a partial stream.
Current Behavior
Crashes with an error
System.Net.Http.HttpRequestException
Sent 298 request content bytes, but Content-Length promised 305.
Reproduction Steps
string path = "blake.txt";
using (var memoryStream = new MemoryStream())
{
long offset;
await using (var writer = new StreamWriter(memoryStream, Encoding.UTF8, 1024, true))
{
writer.AutoFlush = true;
await writer.WriteAsync("Eric");
offset = memoryStream.Position;
await writer.WriteAsync("Blake");
await writer.FlushAsync();
}
memoryStream.Seek(offset, SeekOrigin.Begin);
await SaveFileAsync(path, memoryStream);
}
public async Task<bool> SaveFileAsync(string path, Stream stream, CancellationToken cancellationToken = default(CancellationToken))
{
if (String.IsNullOrEmpty(path))
throw new ArgumentNullException(nameof(path));
if (stream == null)
throw new ArgumentNullException(nameof(stream));
var req = new PutObjectRequest
{
CannedACL = _cannedAcl,
BucketName = _bucket,
Key = NormalizePath(path),
AutoResetStreamPosition = false,
AutoCloseStream = !stream.CanSeek,
InputStream = stream.CanSeek ? stream : AmazonS3Util.MakeStreamSeekable(stream),
UseChunkEncoding = _useChunkEncoding
};
_logger.LogTrace("Saving {Path}", req.Key);
var response = await _client.PutObjectAsync(req, cancellationToken).AnyContext();
return response.HttpStatusCode.IsSuccessful();
}
Possible Solution
Set the content length header to stream length - stream position instead of stream length
Additional Information/Context
No response
AWS .NET SDK and/or Package version used
AWSSDK.S3 3.7.412.0 +
Targeted .NET Platform
.NET Core 8
Operating System and version
Mac Os