diff --git a/src/aws-cpp-sdk-core/source/http/URI.cpp b/src/aws-cpp-sdk-core/source/http/URI.cpp index daf5554b7a4a..cf967c75237d 100644 --- a/src/aws-cpp-sdk-core/source/http/URI.cpp +++ b/src/aws-cpp-sdk-core/source/http/URI.cpp @@ -306,8 +306,14 @@ QueryStringParameterCollection URI::GetQueryStringParameters(bool decode) const //split on = size_t locationOfEquals = keyValuePair.find('='); - Aws::String key = keyValuePair.substr(0, locationOfEquals); - Aws::String value = keyValuePair.substr(locationOfEquals + 1); + Aws::String key, value; + if (locationOfEquals != std::string::npos) { + key = keyValuePair.substr(0, locationOfEquals); + value = keyValuePair.substr(locationOfEquals + 1); + } + else { + key = keyValuePair; + } if(decode) { diff --git a/tests/aws-cpp-sdk-core-tests/http/URITest.cpp b/tests/aws-cpp-sdk-core-tests/http/URITest.cpp index 05a4eee8613f..772f7d0276fc 100644 --- a/tests/aws-cpp-sdk-core-tests/http/URITest.cpp +++ b/tests/aws-cpp-sdk-core-tests/http/URITest.cpp @@ -415,3 +415,32 @@ TEST_F(URITest, TestHostParsesCorrectly) { uri = "https://127.0.0.1:9000"; EXPECT_STREQ("127.0.0.1", uri.GetHost().c_str()); } + +TEST_F(URITest, TestCanonicalizeValuelessQueryParameters) +{ + // S3 Annotations case: ?annotation + annotationName=classification + URI annotationUri("https://bucket.s3.us-east-2.amazonaws.com/key"); + annotationUri.SetQueryString("?annotation"); + annotationUri.AddQueryStringParameter("annotationName", "classification"); + annotationUri.CanonicalizeQueryString(); + EXPECT_EQ("?annotation=&annotationName=classification", annotationUri.GetQueryString()); + + // S3 Analytics case: ?analytics + id=my-config + URI analyticsUri("https://bucket.s3.us-east-1.amazonaws.com"); + analyticsUri.SetQueryString("?analytics"); + analyticsUri.AddQueryStringParameter("id", "my-config"); + analyticsUri.CanonicalizeQueryString(); + EXPECT_EQ("?analytics=&id=my-config", analyticsUri.GetQueryString()); + + // Value-less marker alone (no extra params) should remain unchanged + URI markerOnlyUri("https://bucket.s3.us-east-1.amazonaws.com?tagging"); + markerOnlyUri.CanonicalizeQueryString(); + EXPECT_EQ("?tagging", markerOnlyUri.GetQueryString()); + + // Value-less marker with explicit empty value should preserve = + URI emptyValueUri("https://bucket.s3.us-east-1.amazonaws.com"); + emptyValueUri.SetQueryString("?annotation="); + emptyValueUri.AddQueryStringParameter("annotationName", "classification"); + emptyValueUri.CanonicalizeQueryString(); + EXPECT_EQ("?annotation=&annotationName=classification", emptyValueUri.GetQueryString()); +} \ No newline at end of file diff --git a/tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/generators/cpp/s3/S3RestXmlCppClientGenerator.java b/tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/generators/cpp/s3/S3RestXmlCppClientGenerator.java index 40a30970937d..17bf260a0e2a 100644 --- a/tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/generators/cpp/s3/S3RestXmlCppClientGenerator.java +++ b/tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/generators/cpp/s3/S3RestXmlCppClientGenerator.java @@ -174,11 +174,6 @@ public class S3RestXmlCppClientGenerator extends RestXmlCppClientGenerator { s3CrtEnabledOps.add("PutObject"); s3CrtEnabledOps.add("CopyObject"); - emptyValueQueryMarkerOps.add("PutObjectAnnotation"); - emptyValueQueryMarkerOps.add("GetObjectAnnotation"); - emptyValueQueryMarkerOps.add("ListObjectAnnotations"); - emptyValueQueryMarkerOps.add("DeleteObjectAnnotation"); - bucketLocationConstraints.add("us-east-1"); bucketLocationConstraints.add("us-east-2"); bucketLocationConstraints.add("us-west-1");