Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,9 @@ public AwsSigningConfig PrepareCRTSigningConfig(AwsSignatureType signatureType,
Encoding.ASCII.GetBytes(HeaderKeys.XAmznTraceIdHeader),
Encoding.ASCII.GetBytes(HeaderKeys.TransferEncodingHeader),
Encoding.ASCII.GetBytes(HeaderKeys.AmzSdkInvocationId),
Encoding.ASCII.GetBytes(HeaderKeys.AmzSdkRequest)
Encoding.ASCII.GetBytes(HeaderKeys.AmzSdkRequest),
Encoding.ASCII.GetBytes(HeaderKeys.UserAgentHeader),
Encoding.ASCII.GetBytes(HeaderKeys.XAmzUserAgentHeader)
};

/// <summary>
Expand Down
18 changes: 18 additions & 0 deletions generator/.DevConfigs/40b3493b-5041-4ba8-b5b9-75442cfd4fe6.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"core": {
"updateMinimum": true,
"type": "patch",
"changeLogMessages": [
"Fix issue with signature mismatch during retries"
]
},
"extensions": [
{
"extensionName": "Extensions.CrtIntegration",
"type": "patch",
"changeLogMessages": [
"Fix issue with signature mismatch during retries"
]
}
]
}
4 changes: 3 additions & 1 deletion sdk/src/Core/Amazon.Runtime/Internal/Auth/AWS4Signer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ public class AWS4Signer : AbstractAWSSigner
HeaderKeys.XAmznTraceIdHeader,
HeaderKeys.TransferEncodingHeader,
HeaderKeys.AmzSdkInvocationId,
HeaderKeys.AmzSdkRequest
HeaderKeys.AmzSdkRequest,
HeaderKeys.UserAgentHeader,
HeaderKeys.XAmzUserAgentHeader
};

public AWS4Signer()
Expand Down
78 changes: 67 additions & 11 deletions sdk/test/Services/S3/IntegrationTests/PutObjectTests.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
using Amazon;
using Amazon.Runtime;
using Amazon.Runtime.Internal.Util;
using Amazon.S3;
using Amazon.S3.Model;
using Amazon.S3.Util;
using Amazon.Util;
using AWSSDK_DotNet.IntegrationTests.Utils;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.IO;
Expand All @@ -6,17 +15,6 @@
using System.Net;
using System.Text;
using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting;

using Amazon;
using Amazon.S3;
using Amazon.S3.Model;
using Amazon.S3.Util;
using Amazon.Runtime;
using Amazon.Runtime.Internal.Util;
using AWSSDK_DotNet.IntegrationTests.Utils;
using System.Diagnostics;
using Amazon.Util;
using System.Threading.Tasks;

namespace AWSSDK_DotNet.IntegrationTests.Tests.S3
Expand Down Expand Up @@ -1372,6 +1370,64 @@ public void TestResetStreamPosition()

}

[TestMethod]
[TestCategory("S3")]
public async Task ConfirmRetrySignature()
{
var config = new AmazonS3Config
{
RegionEndpoint = Client.Config.RegionEndpoint,
ResignRetries = true
};
var s3Client = new AmazonS3Client(config);
// This test is response to this PR https://github.com/aws/aws-sdk-net/pull/4050
// where retries started failing with signature mismatch due to user agent modifications.
// In this test we are confirming all retries are attempted and not failing with signature mismatch.
var stream = new FailOnceStream(new MemoryStream(Encoding.UTF8.GetBytes("ConfirmRetrySignature")));
PutObjectRequest request = new PutObjectRequest()
{
BucketName = bucketName,
Key = "thestream",
InputStream = stream,
AutoCloseStream = false,
DisablePayloadSigning = true
};

((Amazon.Runtime.Internal.IAmazonWebServiceRequest)request).UserAgentDetails.AddUserAgentComponent("Modifications");

await Client.PutObjectAsync(request);
}

private class FailOnceStream : WrapperStream
{
public FailOnceStream(MemoryStream memoryStream)
: base(memoryStream)
{
}

bool _firstRead = true;


public override int Read(byte[] buffer, int offset, int count)
{
if (_firstRead)
{
_firstRead = false;
throw new IOException("Fake Exception");
}
return base.Read(buffer, offset, count);
}
public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
if (_firstRead)
{
_firstRead = false;
throw new IOException("Fake Exception");
}
return base.ReadAsync(buffer, offset, count, cancellationToken);
}
}

private class ErrorStream : WrapperStream
{
private ErrorStream(Stream stream)
Expand Down