diff --git a/generator/.DevConfigs/19ed68ce-9f46-4e1e-a0ff-45a2b3641947.json b/generator/.DevConfigs/19ed68ce-9f46-4e1e-a0ff-45a2b3641947.json new file mode 100644 index 000000000000..9fab5c41cb87 --- /dev/null +++ b/generator/.DevConfigs/19ed68ce-9f46-4e1e-a0ff-45a2b3641947.json @@ -0,0 +1,11 @@ +{ + "services": [ + { + "serviceName": "S3", + "type": "patch", + "changeLogMessages": [ + "Fix signature calculation error when using the Content-Language header in S3 requests (e.g., PutObjectRequest)" + ] + } + ] +} diff --git a/generator/ServiceModels/s3/s3.customizations.json b/generator/ServiceModels/s3/s3.customizations.json index 6dc8337d042c..0503fedea7e1 100644 --- a/generator/ServiceModels/s3/s3.customizations.json +++ b/generator/ServiceModels/s3/s3.customizations.json @@ -693,7 +693,8 @@ "SSECustomerAlgorithm", "ServerSideEncryption", "Expires", - "Restore" + "Restore", + "ContentLanguage" ], "excludeFromUnmarshalling" : [ "Expiration" diff --git a/sdk/src/Core/Amazon.Runtime/Pipeline/HttpHandler/_netstandard/HttpRequestMessageFactory.cs b/sdk/src/Core/Amazon.Runtime/Pipeline/HttpHandler/_netstandard/HttpRequestMessageFactory.cs index 5290e77ce96b..c155de68059c 100644 --- a/sdk/src/Core/Amazon.Runtime/Pipeline/HttpHandler/_netstandard/HttpRequestMessageFactory.cs +++ b/sdk/src/Core/Amazon.Runtime/Pipeline/HttpHandler/_netstandard/HttpRequestMessageFactory.cs @@ -400,6 +400,7 @@ public class HttpWebRequestMessage : IHttpRequest HeaderKeys.ContentRangeHeader, HeaderKeys.ContentMD5Header, HeaderKeys.ContentEncodingHeader, + HeaderKeys.ContentLanguageHeader, HeaderKeys.ContentDispositionHeader, HeaderKeys.Expires }; @@ -731,6 +732,10 @@ private void WriteContentHeaders(IDictionary contentHeaders) _request.Content.Headers.TryAddWithoutValidation(HeaderKeys.ContentEncodingHeader, contentEncodingHeader); + if (contentHeaders.TryGetValue(HeaderKeys.ContentLanguageHeader, out var contentLanguageHeader)) + _request.Content.Headers.TryAddWithoutValidation(HeaderKeys.ContentLanguageHeader, + contentLanguageHeader); + if (contentHeaders.TryGetValue(HeaderKeys.ContentDispositionHeader, out var contentDispositionHeader)) _request.Content.Headers.TryAddWithoutValidation(HeaderKeys.ContentDispositionHeader, contentDispositionHeader); diff --git a/sdk/src/Core/Amazon.Util/HeaderKeys.cs b/sdk/src/Core/Amazon.Util/HeaderKeys.cs index 093e1c979318..614986672222 100644 --- a/sdk/src/Core/Amazon.Util/HeaderKeys.cs +++ b/sdk/src/Core/Amazon.Util/HeaderKeys.cs @@ -37,6 +37,7 @@ public abstract class HeaderKeys public const string ContentMD5Header = "Content-MD5"; public const string ContentEncodingHeader = "Content-Encoding"; public const string ContentDispositionHeader = "Content-Disposition"; + public const string ContentLanguageHeader = "Content-Language"; public const string ETagHeader = "ETag"; public const string Expires = "Expires"; public const string AuthorizationHeader = "Authorization"; diff --git a/sdk/src/Services/S3/Custom/Model/GetObjectMetadataResponse.cs b/sdk/src/Services/S3/Custom/Model/GetObjectMetadataResponse.cs index 5e5c2a53f138..ee947272a2a8 100644 --- a/sdk/src/Services/S3/Custom/Model/GetObjectMetadataResponse.cs +++ b/sdk/src/Services/S3/Custom/Model/GetObjectMetadataResponse.cs @@ -67,6 +67,24 @@ public MetadataCollection Metadata } } + /// + /// Gets and sets the property ContentLanguage. + /// + /// The language the content is in. + /// + /// + public string ContentLanguage + { + get { return this.Headers.ContentLanguage; } + set { this.Headers.ContentLanguage = value; } + } + + // Check to see if ContentLanguage property is set + internal bool IsSetContentLanguage() + { + return this.Headers.ContentLanguage != null; + } + /// /// Gets and sets the property DeleteMarker. /// @@ -182,4 +200,3 @@ internal bool IsSetServerSideEncryptionCustomerMethod() } } } - diff --git a/sdk/src/Services/S3/Custom/Model/Internal/MarshallTransformations/GetObjectMetadataResponseUnmarshaller.cs b/sdk/src/Services/S3/Custom/Model/Internal/MarshallTransformations/GetObjectMetadataResponseUnmarshaller.cs index abd79e3c842e..a5b9d768efd0 100644 --- a/sdk/src/Services/S3/Custom/Model/Internal/MarshallTransformations/GetObjectMetadataResponseUnmarshaller.cs +++ b/sdk/src/Services/S3/Custom/Model/Internal/MarshallTransformations/GetObjectMetadataResponseUnmarshaller.cs @@ -61,6 +61,8 @@ partial void PostUnmarshallCustomization(XmlUnmarshallerContext context, GetObje response.Headers.ContentDisposition = S3Transforms.ToString(responseData.GetHeaderValue("Content-Disposition")); if (responseData.IsHeaderPresent("Content-Encoding")) response.Headers.ContentEncoding = S3Transforms.ToString(responseData.GetHeaderValue("Content-Encoding")); + if (responseData.IsHeaderPresent("Content-Language")) + response.Headers.ContentLanguage = S3Transforms.ToString(responseData.GetHeaderValue("Content-Language")); if (responseData.IsHeaderPresent("Content-Length")) response.Headers.ContentLength = long.Parse(responseData.GetHeaderValue("Content-Length"), CultureInfo.InvariantCulture); if (responseData.IsHeaderPresent("Content-Type")) @@ -74,4 +76,3 @@ partial void PostUnmarshallCustomization(XmlUnmarshallerContext context, GetObje } } } - diff --git a/sdk/src/Services/S3/Generated/Model/GetObjectMetadataResponse.cs b/sdk/src/Services/S3/Generated/Model/GetObjectMetadataResponse.cs index 4e323ceab963..ff75f55474b5 100644 --- a/sdk/src/Services/S3/Generated/Model/GetObjectMetadataResponse.cs +++ b/sdk/src/Services/S3/Generated/Model/GetObjectMetadataResponse.cs @@ -46,7 +46,6 @@ public partial class GetObjectMetadataResponse : AmazonWebServiceResponse private ChecksumType _checksumType; private string _contentDisposition; private string _contentEncoding; - private string _contentLanguage; private string _contentRange; private string _contentType; private string _eTag; @@ -320,24 +319,6 @@ internal bool IsSetContentEncoding() return this._contentEncoding != null; } - /// - /// Gets and sets the property ContentLanguage. - /// - /// The language the content is in. - /// - /// - public string ContentLanguage - { - get { return this._contentLanguage; } - set { this._contentLanguage = value; } - } - - // Check to see if ContentLanguage property is set - internal bool IsSetContentLanguage() - { - return this._contentLanguage != null; - } - /// /// Gets and sets the property ContentRange. /// diff --git a/sdk/src/Services/S3/Generated/Model/Internal/MarshallTransformations/GetObjectMetadataResponseUnmarshaller.cs b/sdk/src/Services/S3/Generated/Model/Internal/MarshallTransformations/GetObjectMetadataResponseUnmarshaller.cs index edb00da0b342..2f893e6fc082 100644 --- a/sdk/src/Services/S3/Generated/Model/Internal/MarshallTransformations/GetObjectMetadataResponseUnmarshaller.cs +++ b/sdk/src/Services/S3/Generated/Model/Internal/MarshallTransformations/GetObjectMetadataResponseUnmarshaller.cs @@ -70,8 +70,6 @@ public override AmazonWebServiceResponse Unmarshall(XmlUnmarshallerContext conte response.ContentDisposition = context.ResponseData.GetHeaderValue("Content-Disposition"); if (context.ResponseData.IsHeaderPresent("Content-Encoding")) response.ContentEncoding = context.ResponseData.GetHeaderValue("Content-Encoding"); - if (context.ResponseData.IsHeaderPresent("Content-Language")) - response.ContentLanguage = context.ResponseData.GetHeaderValue("Content-Language"); if (context.ResponseData.IsHeaderPresent("Content-Length")) response.ContentLength = long.Parse(context.ResponseData.GetHeaderValue("Content-Length"), CultureInfo.InvariantCulture); if (context.ResponseData.IsHeaderPresent("Content-Range")) diff --git a/sdk/test/Services/S3/IntegrationTests/PutObjectTests.cs b/sdk/test/Services/S3/IntegrationTests/PutObjectTests.cs index 95147d0358c2..44148ccc1f42 100644 --- a/sdk/test/Services/S3/IntegrationTests/PutObjectTests.cs +++ b/sdk/test/Services/S3/IntegrationTests/PutObjectTests.cs @@ -628,6 +628,39 @@ public void PutObjectWithContentEncodingTests() PutObjectWithoutContentEncoding(); } + [TestMethod] + [TestCategory("S3")] + public void TestPutObjectWithContentLanguage() + { + var key = "contentLanguageTest" + random.Next(); + var contentLanguage = "en-US"; + + var request = new PutObjectRequest + { + BucketName = bucketName, + Key = key, + ContentBody = testContent + }; + request.Headers.ContentLanguage = contentLanguage; + + // Put the object + var putResponse = Client.PutObject(request); + Assert.IsTrue(putResponse.ETag.Length > 0); + + // Verify via GetObject + using (var getResponse = Client.GetObject(bucketName, key)) + { + Assert.AreEqual(contentLanguage, getResponse.Headers.ContentLanguage); + Assert.AreEqual(contentLanguage, getResponse.ContentLanguage); + + } + + // Verify via GetObjectMetadata + var metadata = Client.GetObjectMetadata(bucketName, key); + Assert.AreEqual(contentLanguage, metadata.Headers.ContentLanguage); + Assert.AreEqual(contentLanguage, metadata.ContentLanguage); + } + private void PutObjectWithContentEncoding() { var request = CreatePutObjectRequest(); @@ -1538,4 +1571,4 @@ public override bool CanSeek } } } -} \ No newline at end of file +}