Repository: smithy-lang/smithy
Pull request #2315 (2024-06-11 15:22:37)

Add missing `Content-Type` headers to `@httpPayload` protocol tests
As per the specs for these protocols, a `Content-Type` header should be
set. Servers should reject requests when an expected `Content-Type`
header is not found (protocol tests for that are added in #2314).

- https://smithy.io/2.0/aws/protocols/aws-restjson1-protocol.html#content-type
- https://smithy.io/2.0/aws/protocols/aws-restxml-protocol.html#content-type

#### Testing

Ran tests in smithy-rs.

---
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.



Patch:
diff --git a/smithy-model/src/main/java/software/amazon/smithy/model/shapes/SmithyIdlModelSerializer.java b/smithy-model/src/main/java/software/amazon/smithy/model/shapes/SmithyIdlModelSerializer.java
index 8d0aec396..53000a44c 100644
--- a/smithy-model/src/main/java/software/amazon/smithy/model/shapes/SmithyIdlModelSerializer.java
+++ b/smithy-model/src/main/java/software/amazon/smithy/model/shapes/SmithyIdlModelSerializer.java
@@ -34,6 +34,7 @@ import java.util.function.Predicate;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 import software.amazon.smithy.model.Model;
+import software.amazon.smithy.model.knowledge.OperationIndex;
 import software.amazon.smithy.model.loader.Prelude;
 import software.amazon.smithy.model.node.ArrayNode;
 import software.amazon.smithy.model.node.BooleanNode;
@@ -74,6 +75,7 @@ public final class SmithyIdlModelSerializer {
     private final String inlineInputSuffix;
     private final String inlineOutputSuffix;
     private final boolean inferInlineIoSuffixes;
+    private final boolean shouldCoerceInlineIo;
 
     /**
      * Trait serialization features.
@@ -114,15 +116,21 @@ public final class SmithyIdlModelSerializer {
         traitFilter = builder.traitFilter.and(FunctionalUtils.not(Trait::isSynthetic));
         basePath = builder.basePath;
         if (basePath != null) {
-            Function<Shape, Path> shapePlacer = builder.shapePlacer;
-            this.shapePlacer = shape -> this.basePath.resolve(shapePlacer.apply(shape));
+            Function<Shape, Path> placer = builder.shapePlacer;
+            shapePlacer = shape -> basePath.resolve(placer.apply(shape));
         } else {
-            this.shapePlacer = builder.shapePlacer;
+            shapePlacer = builder.shapePlacer;
+        }
+        componentOrder = builder.componentOrder;
+        inlineInputSuffix = builder.inlineInputSuffix;
+        inlineOutputSuffix = builder.inlineOutputSuffix;
+        shouldCoerceInlineIo = builder.shouldCoerceInlineIo;
+        // Force inferring suffixes on if coercion is on.
+        if (shouldCoerceInlineIo) {
+            inferInlineIoSuffixes = true;
+        } else {
+            inferInlineIoSuffixes = builder.inferInlineIoSuffixes;
         }
-        this.componentOrder = builder.componentOrder;
-        this.inlineInputSuffix = builder.inlineInputSuffix;
-        this.inlineOutputSuffix = builder.inlineOutputSuffix;
-        this.inferInlineIoSuffixes = builder.inferInlineIoSuffixes;
     }
 
     /**
@@ -193,6 +201,7 @@ public final class SmithyIdlModelSerializer {
             String inputSuffix,
             String outputSuffix
     ) {
+        OperationIndex operationIndex = OperationIndex.of(fullModel);
         Set<ShapeId> inlineableShapes = new HashSet<>();
         for (Shape shape : shapes) {
             if (!shape.isOperationShape()) {
@@ -201,14 +210,14 @@ public final class SmithyIdlModelSerializer {
             OperationShape operation = shape.asOperationShape().get();
             if (!operation.getInputShape().equals(UnitTypeTrait.UNIT)) {
                 Shape inputShape = fullModel.expectShape(operation.getInputShape());
-                if (shapes.contains(inputShape) && inputShape.hasTrait(InputTrait.ID)
+                if (shapes.contains(inputShape) && shouldInlineInputShape(operationIndex, inputShape)
                         && inputShape.getId().getName().equals(operation.getId().getName() + inputSuffix)) {
                     inlineableShapes.add(operation.getInputShape());
                 }
             }
             if (!operation.getOutputShape().equals(UnitTypeTrait.UNIT)) {
                 Shape outputShape = fullModel.expectShape(operation.getOutputShape());
-                if (shapes.contains(outputShape) && outputShape.hasTrait(OutputTrait.ID)
+                if (shapes.contains(outputShape) && shouldInlineOutputShape(operationIndex, outputShape)
                         && outputShape.getId().getName().equals(operation.getId().getName() + outputSuffix)) {
                     inlineableShapes.add(operation.getOutputShape());
                 }
@@ -217,6 +226,18 @@ public final class SmithyIdlModelSerializer {
         return inlineableShapes;
     }
 
+    private boolean shouldInlineInputShape(OperationIndex operationIndex, Shape target) {
+        // Only allow coercion if the shape is only used as one input.
+        return target.hasTrait(InputTrait.ID)
+                || (shouldCoerceInlineIo && operationIndex.getInputBindings(target).size() == 1);
+    }
+
+    private boolean shouldInlineOutputShape(OperationIndex operationIndex, Shape target) {
+        // Only allow coercion if the shape is only used as one output.
+        return target.hasTrait(OutputTrait.ID)
+                || (shouldCoerceInlineIo && operationIndex.getOutputBindings(target).size() == 1);
+    }
+
     private Pair<String, String> determineInlineSuffixes(Model fullModel, Collection<Shape> shapes) {
         if (!inferInlineIoSuffixes) {
             return Pair.of(inlineInputSuffix, inlineOutputSuffix);
@@ -330,6 +351,7 @@ public final class SmithyIdlModelSerializer {
         private String inlineInputSuffix = DEFAULT_INLINE_INPUT_SUFFIX;
         private String inlineOutputSuffix = DEFAULT_INLINE_OUTPUT_SUFFIX;
         private boolean inferInlineIoSuffixes = false;
+        private boolean shouldCoerceInlineIo = false;
 
         public Builder() {}
 
@@ -457,11 +479,30 @@ public final class SmithyIdlModelSerializer {
          * <p>The suffixes set by {@link #inlineInputSuffix(String)} and {@link #inlineOutputSuffix(String)}
          * will be the default values.
          *
-         * @param shouldinferInlineIoSuffixes Whether inline IO suffixes should be inferred for each file.
+         * @param shouldInferInlineIoSuffixes Whether inline IO suffixes should be inferred for each file.
+         * @return Returns the builder.
+         */
+        public Builder inferInlineIoSuffixes(boolean shouldInferInlineIoSuffixes) {
+            this.inferInlineIoSuffixes = shouldInferInlineIoSuffixes;
+            return this;
+        }
+
+        /**
+         * Determines whether inline IO should be coerced for shapes operation input
+         * and output that does not have the {@code @input} or {@code @output} trait,
+         * respectively.
+         *
+         * <p>If true, this will determine any shared IO suffixes for each file. Only the
+         * shapes present within each file will impact what that file's suffixes will be.
+         *
+         * <p>The suffixes set by {@link #inlineInputSuffix(String)} and {@link #inlineOutputSuffix(String)}
+         * will be the default values.
+         *
+         * @param shouldCoerceInlineIo Whether inline IO should be coerced for each file.
          * @return Returns the builder.
          */
-        public Builder inferInlineIoSuffixes(boolean shouldinferInlineIoSuffixes) {
-            this.inferInlineIoSuffixes = shouldinferInlineIoSuffixes;
+        public Builder coerceInlineIo(boolean shouldCoerceInlineIo) {
+            this.shouldCoerceInlineIo = shouldCoerceInlineIo;
             return this;
         }
 
@@ -833,7 +874,7 @@ public final class SmithyIdlModelSerializer {
         }
 
         private boolean hasOnlyDefaultTrait(Shape shape, ShapeId defaultTrait) {
-            return shape.getAllTraits().size() == 1 && shape.hasTrait(defaultTrait);
+            return shape.getAllTraits().isEmpty() || (shape.getAllTraits().size() == 1 && shape.hasTrait(defaultTrait));
         }
     }
 


Test patch:
diff --git a/smithy-aws-protocol-tests/model/restJson1/http-string-payload.smithy b/smithy-aws-protocol-tests/model/restJson1/http-string-payload.smithy
index 8aa1f517b..52cab5cc9 100644
--- a/smithy-aws-protocol-tests/model/restJson1/http-string-payload.smithy
+++ b/smithy-aws-protocol-tests/model/restJson1/http-string-payload.smithy
@@ -10,6 +10,7 @@ use smithy.test#httpResponseTests
     {
         id: "RestJsonEnumPayloadRequest",
         uri: "/EnumPayload",
+        headers: { "Content-Type": "text/plain" },
         body: "enumvalue",
         params: { payload: "enumvalue" },
         method: "POST",
@@ -19,6 +20,7 @@ use smithy.test#httpResponseTests
 @httpResponseTests([
     {
         id: "RestJsonEnumPayloadResponse",
+        headers: { "Content-Type": "text/plain" },
         body: "enumvalue",
         params: { payload: "enumvalue" },
         protocol: "aws.protocols#restJson1",
@@ -44,6 +46,7 @@ enum StringEnum {
     {
         id: "RestJsonStringPayloadRequest",
         uri: "/StringPayload",
+        headers: { "Content-Type": "text/plain" },
         body: "rawstring",
         params: { payload: "rawstring" },
         method: "POST",
@@ -53,6 +56,7 @@ enum StringEnum {
 @httpResponseTests([
     {
         id: "RestJsonStringPayloadResponse",
+        headers: { "Content-Type": "text/plain" },
         body: "rawstring",
         params: { payload: "rawstring" },
         protocol: "aws.protocols#restJson1",
diff --git a/smithy-aws-protocol-tests/model/restXml/http-string-payload.smithy b/smithy-aws-protocol-tests/model/restXml/http-string-payload.smithy
index 851e34066..9b25b3af0 100644
--- a/smithy-aws-protocol-tests/model/restXml/http-string-payload.smithy
+++ b/smithy-aws-protocol-tests/model/restXml/http-string-payload.smithy
@@ -10,6 +10,7 @@ use smithy.test#httpResponseTests
     {
         id: "RestXmlEnumPayloadRequest",
         uri: "/EnumPayload",
+        headers: { "Content-Type": "text/plain" },
         body: "enumvalue",
         params: { payload: "enumvalue" },
         method: "POST",
@@ -19,6 +20,7 @@ use smithy.test#httpResponseTests
 @httpResponseTests([
     {
         id: "RestXmlEnumPayloadResponse",
+        headers: { "Content-Type": "text/plain" },
         body: "enumvalue",
         params: { payload: "enumvalue" },
         protocol: "aws.protocols#restXml",
@@ -44,6 +46,7 @@ enum StringEnum {
     {
         id: "RestXmlStringPayloadRequest",
         uri: "/StringPayload",
+        headers: { "Content-Type": "text/plain" },
         body: "rawstring",
         params: { payload: "rawstring" },
         method: "POST",
@@ -53,6 +56,7 @@ enum StringEnum {
 @httpResponseTests([
     {
         id: "RestXmlStringPayloadResponse",
+        headers: { "Content-Type": "text/plain" },
         body: "rawstring",
         params: { payload: "rawstring" },
         protocol: "aws.protocols#restXml",
diff --git a/smithy-model/src/test/java/software/amazon/smithy/model/shapes/SmithyIdlModelSerializerTest.java b/smithy-model/src/test/java/software/amazon/smithy/model/shapes/SmithyIdlModelSerializerTest.java
index 15431ecd5..27dea4cc8 100644
--- a/smithy-model/src/test/java/software/amazon/smithy/model/shapes/SmithyIdlModelSerializerTest.java
+++ b/smithy-model/src/test/java/software/amazon/smithy/model/shapes/SmithyIdlModelSerializerTest.java
@@ -8,6 +8,7 @@ import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.hasKey;
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.not;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import java.io.IOException;
 import java.net.URISyntaxException;
@@ -49,7 +50,7 @@ public class SmithyIdlModelSerializerTest {
         }
 
         String serializedString = serialized.entrySet().iterator().next().getValue();
-        Assertions.assertEquals(IoUtils.readUtf8File(path).replaceAll("\\R", "\n"), serializedString);
+        assertEquals(IoUtils.readUtf8File(path).replaceAll("\\R", "\n"), serializedString);
     }
 
     @Test
@@ -259,7 +260,7 @@ public class SmithyIdlModelSerializerTest {
         String expectedOutput = IoUtils.readUtf8Resource(getClass(), "idl-serialization/enum-mixin-output.smithy")
                 .replaceAll("\\R", "\n");
         String serializedString = serialized.entrySet().iterator().next().getValue();
-        Assertions.assertEquals(expectedOutput, serializedString);
+        assertEquals(expectedOutput, serializedString);
     }
 
     @Test
@@ -306,4 +307,21 @@ public class SmithyIdlModelSerializerTest {
             assertThat(actual, equalTo(expected));
         }
     }
+
+    @Test
+    public void coercesInlineIO() {
+        Model before = Model.assembler()
+                .addImport(getClass().getResource("idl-serialization/coerced-io/before.smithy"))
+                .assemble().unwrap();
+
+        Map<Path, String> reserialized = SmithyIdlModelSerializer.builder()
+                .coerceInlineIo(true)
+                .build()
+                .serialize(before);
+        String modelResult = reserialized.values().iterator().next().replace("\r\n", "\n");
+
+        String expected = IoUtils.readUtf8Url(getClass().getResource("idl-serialization/coerced-io/after.smithy"))
+                .replace("\r\n", "\n");
+        assertEquals(expected, modelResult);
+    }
 }
diff --git a/smithy-model/src/test/resources/software/amazon/smithy/model/shapes/idl-serialization/coerced-io/after.smithy b/smithy-model/src/test/resources/software/amazon/smithy/model/shapes/idl-serialization/coerced-io/after.smithy
new file mode 100644
index 000000000..7f76e438f
--- /dev/null
+++ b/smithy-model/src/test/resources/software/amazon/smithy/model/shapes/idl-serialization/coerced-io/after.smithy
@@ -0,0 +1,40 @@
+$version: "2.0"
+$operationInputSuffix: "Request"
+$operationOutputSuffix: "Response"
+
+namespace com.example
+
+service InlineService {
+    operations: [
+        MultipleBind1
+        MultipleBind2
+        WithoutTraits
+        WithTraits
+    ]
+}
+
+operation MultipleBind1 {
+    input: MultipleBindRequest
+    output: MultipleBindResponse
+}
+
+operation MultipleBind2 {
+    input: MultipleBindRequest
+    output: MultipleBindResponse
+}
+
+operation WithoutTraits {
+    input := {}
+    output := {}
+}
+
+operation WithTraits {
+    input := {
+        a: String
+    }
+    output := {}
+}
+
+structure MultipleBindRequest {}
+
+structure MultipleBindResponse {}
diff --git a/smithy-model/src/test/resources/software/amazon/smithy/model/shapes/idl-serialization/coerced-io/before.smithy b/smithy-model/src/test/resources/software/amazon/smithy/model/shapes/idl-serialization/coerced-io/before.smithy
new file mode 100644
index 000000000..c4d9a2a59
--- /dev/null
+++ b/smithy-model/src/test/resources/software/amazon/smithy/model/shapes/idl-serialization/coerced-io/before.smithy
@@ -0,0 +1,48 @@
+$version: "2.0"
+
+namespace com.example
+
+service InlineService {
+    operations: [
+        MultipleBind1
+        MultipleBind2
+        WithoutTraits
+        WithTraits
+    ]
+}
+
+operation MultipleBind1 {
+    input: MultipleBindRequest
+    output: MultipleBindResponse
+}
+
+operation MultipleBind2 {
+    input: MultipleBindRequest
+    output: MultipleBindResponse
+}
+
+operation WithoutTraits {
+    input: WithoutTraitsRequest
+    output: WithoutTraitsResponse
+}
+
+operation WithTraits {
+    input: WithTraitsRequest
+    output: WithTraitsResponse
+}
+
+structure MultipleBindRequest {}
+
+structure MultipleBindResponse {}
+
+structure WithoutTraitsRequest {}
+
+structure WithoutTraitsResponse {}
+
+@input
+structure WithTraitsRequest {
+    a: String
+}
+
+@output
+structure WithTraitsResponse {}
diff --git a/smithy-protocol-tests/model/rpcv2Cbor/cbor-maps.smithy b/smithy-protocol-tests/model/rpcv2Cbor/cbor-maps.smithy
index 93e05e026..0f4a5223d 100644
--- a/smithy-protocol-tests/model/rpcv2Cbor/cbor-maps.smithy
+++ b/smithy-protocol-tests/model/rpcv2Cbor/cbor-maps.smithy
@@ -171,8 +171,7 @@ apply RpcV2CborDenseMaps @httpResponseTests([
         params: {
             "denseSetMap": {
                 "x": [],
-                "y": ["a", "b"],
-                "z": null
+                "y": ["a", "b"]
             }
         }
     }
diff --git a/smithy-protocol-tests/model/rpcv2Cbor/cbor-structs.smithy b/smithy-protocol-tests/model/rpcv2Cbor/cbor-structs.smithy
index 3bb58462a..afa4891fe 100644
--- a/smithy-protocol-tests/model/rpcv2Cbor/cbor-structs.smithy
+++ b/smithy-protocol-tests/model/rpcv2Cbor/cbor-structs.smithy
@@ -21,12 +21,14 @@ use smithy.test#httpResponseTests
         method: "POST",
         bodyMediaType: "application/cbor",
         uri: "/service/RpcV2Protocol/operation/SimpleScalarProperties",
-        body: "v2lieXRlVmFsdWUFa2RvdWJsZVZhbHVl+z/+OVgQYk3TcWZhbHNlQm9vbGVhblZhbHVl9GpmbG9hdFZhbHVl+kDz989saW50ZWdlclZhbHVlGQEAaWxvbmdWYWx1ZRkmkWpzaG9ydFZhbHVlGSaqa3N0cmluZ1ZhbHVlZnNpbXBsZXB0cnVlQm9vbGVhblZhbHVl9WlibG9iVmFsdWVDZm9v/w=="
+        // Before: http://ec2-54-84-9-83.compute-1.amazonaws.com/hex?value=v2lieXRlVmFsdWUFa2RvdWJsZVZhbHVl%2Bz%2F%2BOVgQYk3TcWZhbHNlQm9vbGVhblZhbHVl9GpmbG9hdFZhbHVl%2BkDz989saW50ZWdlclZhbHVlGQEAaWxvbmdWYWx1ZRkmkWpzaG9ydFZhbHVlGSaqa3N0cmluZ1ZhbHVlZnNpbXBsZXB0cnVlQm9vbGVhblZhbHVl9WlibG9iVmFsdWVDZm9v%2Fw%3D%3D
+        // Now: http://ec2-54-84-9-83.compute-1.amazonaws.com/hex?value=v2lieXRlVmFsdWUFa2RvdWJsZVZhbHVl%2Bz%2F%2BOVgQYk3TcWZhbHNlQm9vbGVhblZhbHVl9GpmbG9hdFZhbHVl%2BkD0AABsaW50ZWdlclZhbHVlGQEAaWxvbmdWYWx1ZRkmkWpzaG9ydFZhbHVlGSaqa3N0cmluZ1ZhbHVlZnNpbXBsZXB0cnVlQm9vbGVhblZhbHVl9WlibG9iVmFsdWVDZm9v%2Fw%3D%3D
+        body: "v2lieXRlVmFsdWUFa2RvdWJsZVZhbHVl+z/+OVgQYk3TcWZhbHNlQm9vbGVhblZhbHVl9GpmbG9hdFZhbHVl+kD0AABsaW50ZWdlclZhbHVlGQEAaWxvbmdWYWx1ZRkmkWpzaG9ydFZhbHVlGSaqa3N0cmluZ1ZhbHVlZnNpbXBsZXB0cnVlQm9vbGVhblZhbHVl9WlibG9iVmFsdWVDZm9v/w==",
         params: {
             byteValue: 5,
             doubleValue: 1.889,
             falseBooleanValue: false,
-            floatValue: 7.624,
+            floatValue: 7.625,
             integerValue: 256,
             longValue: 9873,
             shortValue: 9898,
@@ -52,12 +54,14 @@ use smithy.test#httpResponseTests
         method: "POST",
         bodyMediaType: "application/cbor",
         uri: "/service/RpcV2Protocol/operation/SimpleScalarProperties",
-        body: "qmlieXRlVmFsdWUFf2Zkb3VibGVlVmFsdWX/+z/+OVgQYk3Tf2VmYWxzZWdCb29sZWFuZVZhbHVl//RqZmxvYXRWYWx1ZfpA8/fPbGludGVnZXJWYWx1ZRkBAGlsb25nVmFsdWUZJpFqc2hvcnRWYWx1ZRkmqn9mc3RyaW5nZVZhbHVl/2ZzaW1wbGVwdHJ1ZUJvb2xlYW5WYWx1ZfVpYmxvYlZhbHVlQ2Zvbw=="
+        // Before: http://ec2-54-84-9-83.compute-1.amazonaws.com/hex?value=qmlieXRlVmFsdWUFf2Zkb3VibGVlVmFsdWX%2F%2Bz%2F%2BOVgQYk3Tf2VmYWxzZWdCb29sZWFuZVZhbHVl%2F%2FRqZmxvYXRWYWx1ZfpA8%2FfPbGludGVnZXJWYWx1ZRkBAGlsb25nVmFsdWUZJpFqc2hvcnRWYWx1ZRkmqn9mc3RyaW5nZVZhbHVl%2F2ZzaW1wbGVwdHJ1ZUJvb2xlYW5WYWx1ZfVpYmxvYlZhbHVlQ2Zvbw%3D%3D        -e doubleValue/double,Value;falseBooleanValue/false,Boolean,Value;stringValue/string,Value
+        // Now: http://ec2-54-84-9-83.compute-1.amazonaws.com/hex?value=qmlieXRlVmFsdWUFf2Zkb3VibGVlVmFsdWX%2F%2Bz%2F%2BOVgQYk3Tf2VmYWxzZWdCb29sZWFuZVZhbHVl%2F%2FRqZmxvYXRWYWx1ZfpA9AAAbGludGVnZXJWYWx1ZRkBAGlsb25nVmFsdWUZJpFqc2hvcnRWYWx1ZRkmqn9mc3RyaW5nZVZhbHVl%2F2ZzaW1wbGVwdHJ1ZUJvb2xlYW5WYWx1ZfVpYmxvYlZhbHVlQ2Zvbw%3D%3D
+        body: "qmlieXRlVmFsdWUFf2Zkb3VibGVlVmFsdWX/+z/+OVgQYk3Tf2VmYWxzZWdCb29sZWFuZVZhbHVl//RqZmxvYXRWYWx1ZfpA9AAAbGludGVnZXJWYWx1ZRkBAGlsb25nVmFsdWUZJpFqc2hvcnRWYWx1ZRkmqn9mc3RyaW5nZVZhbHVl/2ZzaW1wbGVwdHJ1ZUJvb2xlYW5WYWx1ZfVpYmxvYlZhbHVlQ2Zvbw==",
         params: {
             byteValue: 5,
             doubleValue: 1.889,
             falseBooleanValue: false,
-            floatValue: 7.624,
+            floatValue: 7.625,
             integerValue: 256,
             longValue: 9873,
             shortValue: 9898,
@@ -246,12 +250,14 @@ use smithy.test#httpResponseTests
         method: "POST",
         bodyMediaType: "application/cbor",
         uri: "/service/RpcV2Protocol/operation/SimpleScalarProperties",
-        body: "v2lieXRlVmFsdWUFa2RvdWJsZVZhbHVl+z/+OVgQYk3TcWZhbHNlQm9vbGVhblZhbHVl9GpmbG9hdFZhbHVl+kDz989rZXh0cmFPYmplY3S/c2luZGVmaW5pdGVMZW5ndGhNYXC/a3dpdGhBbkFycmF5nwECA///cWRlZmluaXRlTGVuZ3RoTWFwo3J3aXRoQURlZmluaXRlQXJyYXmDAQIDeB1hbmRTb21lSW5kZWZpbml0ZUxlbmd0aFN0cmluZ3gfdGhhdCBoYXMsIGJlZW4gY2h1bmtlZCBvbiBjb21tYWxub3JtYWxTdHJpbmdjZm9vanNob3J0VmFsdWUZJw9uc29tZU90aGVyRmllbGR2dGhpcyBzaG91bGQgYmUgc2tpcHBlZP9saW50ZWdlclZhbHVlGQEAaWxvbmdWYWx1ZRkmkWpzaG9ydFZhbHVlGSaqa3N0cmluZ1ZhbHVlZnNpbXBsZXB0cnVlQm9vbGVhblZhbHVl9WlibG9iVmFsdWVDZm9v/w==",
+        // Before: http://ec2-54-84-9-83.compute-1.amazonaws.com/hex?value=v2lieXRlVmFsdWUFa2RvdWJsZVZhbHVl%2Bz%2F%2BOVgQYk3TcWZhbHNlQm9vbGVhblZhbHVl9GpmbG9hdFZhbHVl%2BkDz989rZXh0cmFPYmplY3S%2Fc2luZGVmaW5pdGVMZW5ndGhNYXC%2Fa3dpdGhBbkFycmF5nwECA%2F%2F%2FcWRlZmluaXRlTGVuZ3RoTWFwo3J3aXRoQURlZmluaXRlQXJyYXmDAQIDeB1hbmRTb21lSW5kZWZpbml0ZUxlbmd0aFN0cmluZ3gfdGhhdCBoYXMsIGJlZW4gY2h1bmtlZCBvbiBjb21tYWxub3JtYWxTdHJpbmdjZm9vanNob3J0VmFsdWUZJw9uc29tZU90aGVyRmllbGR2dGhpcyBzaG91bGQgYmUgc2tpcHBlZP9saW50ZWdlclZhbHVlGQEAaWxvbmdWYWx1ZRkmkWpzaG9ydFZhbHVlGSaqa3N0cmluZ1ZhbHVlZnNpbXBsZXB0cnVlQm9vbGVhblZhbHVl9WlibG9iVmFsdWVDZm9v%2Fw%3D%3D
+        // Now: http://ec2-54-84-9-83.compute-1.amazonaws.com/hex?value=v2lieXRlVmFsdWUFa2RvdWJsZVZhbHVl%2Bz%2F%2BOVgQYk3TcWZhbHNlQm9vbGVhblZhbHVl9GpmbG9hdFZhbHVl%2BkD0AABrZXh0cmFPYmplY3S%2Fc2luZGVmaW5pdGVMZW5ndGhNYXC%2Fa3dpdGhBbkFycmF5nwECA%2F%2F%2FcWRlZmluaXRlTGVuZ3RoTWFwo3J3aXRoQURlZmluaXRlQXJyYXmDAQIDeB1hbmRTb21lSW5kZWZpbml0ZUxlbmd0aFN0cmluZ3gfdGhhdCBoYXMsIGJlZW4gY2h1bmtlZCBvbiBjb21tYWxub3JtYWxTdHJpbmdjZm9vanNob3J0VmFsdWUZJw9uc29tZU90aGVyRmllbGR2dGhpcyBzaG91bGQgYmUgc2tpcHBlZP9saW50ZWdlclZhbHVlGQEAaWxvbmdWYWx1ZRkmkWpzaG9ydFZhbHVlGSaqa3N0cmluZ1ZhbHVlZnNpbXBsZXB0cnVlQm9vbGVhblZhbHVl9WlibG9iVmFsdWVDZm9v%2Fw%3D%3D
+        body: "v2lieXRlVmFsdWUFa2RvdWJsZVZhbHVl+z/+OVgQYk3TcWZhbHNlQm9vbGVhblZhbHVl9GpmbG9hdFZhbHVl+kD0AABrZXh0cmFPYmplY3S/c2luZGVmaW5pdGVMZW5ndGhNYXC/a3dpdGhBbkFycmF5nwECA///cWRlZmluaXRlTGVuZ3RoTWFwo3J3aXRoQURlZmluaXRlQXJyYXmDAQIDeB1hbmRTb21lSW5kZWZpbml0ZUxlbmd0aFN0cmluZ3gfdGhhdCBoYXMsIGJlZW4gY2h1bmtlZCBvbiBjb21tYWxub3JtYWxTdHJpbmdjZm9vanNob3J0VmFsdWUZJw9uc29tZU90aGVyRmllbGR2dGhpcyBzaG91bGQgYmUgc2tpcHBlZP9saW50ZWdlclZhbHVlGQEAaWxvbmdWYWx1ZRkmkWpzaG9ydFZhbHVlGSaqa3N0cmluZ1ZhbHVlZnNpbXBsZXB0cnVlQm9vbGVhblZhbHVl9WlibG9iVmFsdWVDZm9v/w==",
         params: {
             byteValue: 5,
             doubleValue: 1.889,
             falseBooleanValue: false,
-            floatValue: 7.624,
+            floatValue: 7.625,
             integerValue: 256,
             longValue: 9873,
             shortValue: 9898,
@@ -272,14 +278,16 @@ use smithy.test#httpResponseTests
             "Content-Type": "application/cbor"
         }
         bodyMediaType: "application/cbor",
-        body: "v3B0cnVlQm9vbGVhblZhbHVl9XFmYWxzZUJvb2xlYW5WYWx1ZfRpYnl0ZVZhbHVlBWtkb3VibGVWYWx1Zfs//jlYEGJN02pmbG9hdFZhbHVl+kDz989saW50ZWdlclZhbHVlGQEAanNob3J0VmFsdWUZJqprc3RyaW5nVmFsdWVmc2ltcGxlaWJsb2JWYWx1ZUNmb2//"
+        // Before: http://ec2-54-84-9-83.compute-1.amazonaws.com/hex?value=v3B0cnVlQm9vbGVhblZhbHVl9XFmYWxzZUJvb2xlYW5WYWx1ZfRpYnl0ZVZhbHVlBWtkb3VibGVWYWx1Zfs%2F%2FjlYEGJN02pmbG9hdFZhbHVl%2BkDz989saW50ZWdlclZhbHVlGQEAanNob3J0VmFsdWUZJqprc3RyaW5nVmFsdWVmc2ltcGxlaWJsb2JWYWx1ZUNmb2%2F%2F
+        // Now: http://ec2-54-84-9-83.compute-1.amazonaws.com/hex?value=v3B0cnVlQm9vbGVhblZhbHVl9XFmYWxzZUJvb2xlYW5WYWx1ZfRpYnl0ZVZhbHVlBWtkb3VibGVWYWx1Zfs%2F%2FjlYEGJN02pmbG9hdFZhbHVl%2BkD0AABsaW50ZWdlclZhbHVlGQEAanNob3J0VmFsdWUZJqprc3RyaW5nVmFsdWVmc2ltcGxlaWJsb2JWYWx1ZUNmb2%2F%2F
+        body: "v3B0cnVlQm9vbGVhblZhbHVl9XFmYWxzZUJvb2xlYW5WYWx1ZfRpYnl0ZVZhbHVlBWtkb3VibGVWYWx1Zfs//jlYEGJN02pmbG9hdFZhbHVl+kD0AABsaW50ZWdlclZhbHVlGQEAanNob3J0VmFsdWUZJqprc3RyaW5nVmFsdWVmc2ltcGxlaWJsb2JWYWx1ZUNmb2//",
         code: 200,
         params: {
             trueBooleanValue: true,
             falseBooleanValue: false,
             byteValue: 5,
             doubleValue: 1.889,
-            floatValue: 7.624,
+            floatValue: 7.625,
             integerValue: 256,
             shortValue: 9898,
             stringValue: "simple",
@@ -295,14 +303,16 @@ use smithy.test#httpResponseTests
             "Content-Type": "application/cbor"
         }
         bodyMediaType: "application/cbor",
-        body: "qXB0cnVlQm9vbGVhblZhbHVl9XFmYWxzZUJvb2xlYW5WYWx1ZfRpYnl0ZVZhbHVlBWtkb3VibGVWYWx1Zfs//jlYEGJN02pmbG9hdFZhbHVl+kDz989saW50ZWdlclZhbHVlGQEAanNob3J0VmFsdWUZJqprc3RyaW5nVmFsdWVmc2ltcGxlaWJsb2JWYWx1ZUNmb28="
+        // http://ec2-54-84-9-83.compute-1.amazonaws.com/hex?value=qXB0cnVlQm9vbGVhblZhbHVl9XFmYWxzZUJvb2xlYW5WYWx1ZfRpYnl0ZVZhbHVlBWtkb3VibGVWYWx1Zfs%2F%2FjlYEGJN02pmbG9hdFZhbHVl%2BkDz989saW50ZWdlclZhbHVlGQEAanNob3J0VmFsdWUZJqprc3RyaW5nVmFsdWVmc2ltcGxlaWJsb2JWYWx1ZUNmb28%3D
+        // http://ec2-54-84-9-83.compute-1.amazonaws.com/hex?value=qXB0cnVlQm9vbGVhblZhbHVl9XFmYWxzZUJvb2xlYW5WYWx1ZfRpYnl0ZVZhbHVlBWtkb3VibGVWYWx1Zfs%2F%2FjlYEGJN02pmbG9hdFZhbHVl%2BkD0AABsaW50ZWdlclZhbHVlGQEAanNob3J0VmFsdWUZJqprc3RyaW5nVmFsdWVmc2ltcGxlaWJsb2JWYWx1ZUNmb28%3D
+        body: "qXB0cnVlQm9vbGVhblZhbHVl9XFmYWxzZUJvb2xlYW5WYWx1ZfRpYnl0ZVZhbHVlBWtkb3VibGVWYWx1Zfs//jlYEGJN02pmbG9hdFZhbHVl+kD0AABsaW50ZWdlclZhbHVlGQEAanNob3J0VmFsdWUZJqprc3RyaW5nVmFsdWVmc2ltcGxlaWJsb2JWYWx1ZUNmb28=",
         code: 200,
         params: {
             trueBooleanValue: true,
             falseBooleanValue: false,
             byteValue: 5,
             doubleValue: 1.889,
-            floatValue: 7.624,
+            floatValue: 7.625,
             integerValue: 256,
             shortValue: 9898,
             stringValue: "simple",
@@ -421,12 +431,14 @@ use smithy.test#httpResponseTests
         }
         code: 200,
         bodyMediaType: "application/cbor",
-        body: "v2lieXRlVmFsdWUFa2RvdWJsZVZhbHVl+z/+OVgQYk3TcWZhbHNlQm9vbGVhblZhbHVl9GpmbG9hdFZhbHVl+kDz989rZXh0cmFPYmplY3S/c2luZGVmaW5pdGVMZW5ndGhNYXC/a3dpdGhBbkFycmF5nwECA///cWRlZmluaXRlTGVuZ3RoTWFwo3J3aXRoQURlZmluaXRlQXJyYXmDAQIDeB1hbmRTb21lSW5kZWZpbml0ZUxlbmd0aFN0cmluZ3gfdGhhdCBoYXMsIGJlZW4gY2h1bmtlZCBvbiBjb21tYWxub3JtYWxTdHJpbmdjZm9vanNob3J0VmFsdWUZJw9uc29tZU90aGVyRmllbGR2dGhpcyBzaG91bGQgYmUgc2tpcHBlZP9saW50ZWdlclZhbHVlGQEAaWxvbmdWYWx1ZRkmkWpzaG9ydFZhbHVlGSaqa3N0cmluZ1ZhbHVlZnNpbXBsZXB0cnVlQm9vbGVhblZhbHVl9WlibG9iVmFsdWVDZm9v/w==",
+        // Before: http://ec2-54-84-9-83.compute-1.amazonaws.com/hex?value=v2lieXRlVmFsdWUFa2RvdWJsZVZhbHVl%2Bz%2F%2BOVgQYk3TcWZhbHNlQm9vbGVhblZhbHVl9GpmbG9hdFZhbHVl%2BkDz989rZXh0cmFPYmplY3S%2Fc2luZGVmaW5pdGVMZW5ndGhNYXC%2Fa3dpdGhBbkFycmF5nwECA%2F%2F%2FcWRlZmluaXRlTGVuZ3RoTWFwo3J3aXRoQURlZmluaXRlQXJyYXmDAQIDeB1hbmRTb21lSW5kZWZpbml0ZUxlbmd0aFN0cmluZ3gfdGhhdCBoYXMsIGJlZW4gY2h1bmtlZCBvbiBjb21tYWxub3JtYWxTdHJpbmdjZm9vanNob3J0VmFsdWUZJw9uc29tZU90aGVyRmllbGR2dGhpcyBzaG91bGQgYmUgc2tpcHBlZP9saW50ZWdlclZhbHVlGQEAaWxvbmdWYWx1ZRkmkWpzaG9ydFZhbHVlGSaqa3N0cmluZ1ZhbHVlZnNpbXBsZXB0cnVlQm9vbGVhblZhbHVl9WlibG9iVmFsdWVDZm9v%2Fw%3D%3D
+        // Now: http://ec2-54-84-9-83.compute-1.amazonaws.com/hex?value=v2lieXRlVmFsdWUFa2RvdWJsZVZhbHVl%2Bz%2F%2BOVgQYk3TcWZhbHNlQm9vbGVhblZhbHVl9GpmbG9hdFZhbHVl%2BkD0AABrZXh0cmFPYmplY3S%2Fc2luZGVmaW5pdGVMZW5ndGhNYXC%2Fa3dpdGhBbkFycmF5nwECA%2F%2F%2FcWRlZmluaXRlTGVuZ3RoTWFwo3J3aXRoQURlZmluaXRlQXJyYXmDAQIDeB1hbmRTb21lSW5kZWZpbml0ZUxlbmd0aFN0cmluZ3gfdGhhdCBoYXMsIGJlZW4gY2h1bmtlZCBvbiBjb21tYWxub3JtYWxTdHJpbmdjZm9vanNob3J0VmFsdWUZJw9uc29tZU90aGVyRmllbGR2dGhpcyBzaG91bGQgYmUgc2tpcHBlZP9saW50ZWdlclZhbHVlGQEAaWxvbmdWYWx1ZRkmkWpzaG9ydFZhbHVlGSaqa3N0cmluZ1ZhbHVlZnNpbXBsZXB0cnVlQm9vbGVhblZhbHVl9WlibG9iVmFsdWVDZm9v%2Fw%3D%3D
+        body: "v2lieXRlVmFsdWUFa2RvdWJsZVZhbHVl+z/+OVgQYk3TcWZhbHNlQm9vbGVhblZhbHVl9GpmbG9hdFZhbHVl+kD0AABrZXh0cmFPYmplY3S/c2luZGVmaW5pdGVMZW5ndGhNYXC/a3dpdGhBbkFycmF5nwECA///cWRlZmluaXRlTGVuZ3RoTWFwo3J3aXRoQURlZmluaXRlQXJyYXmDAQIDeB1hbmRTb21lSW5kZWZpbml0ZUxlbmd0aFN0cmluZ3gfdGhhdCBoYXMsIGJlZW4gY2h1bmtlZCBvbiBjb21tYWxub3JtYWxTdHJpbmdjZm9vanNob3J0VmFsdWUZJw9uc29tZU90aGVyRmllbGR2dGhpcyBzaG91bGQgYmUgc2tpcHBlZP9saW50ZWdlclZhbHVlGQEAaWxvbmdWYWx1ZRkmkWpzaG9ydFZhbHVlGSaqa3N0cmluZ1ZhbHVlZnNpbXBsZXB0cnVlQm9vbGVhblZhbHVl9WlibG9iVmFsdWVDZm9v/w==",
         params: {
             byteValue: 5,
             doubleValue: 1.889,
             falseBooleanValue: false,
-            floatValue: 7.624,
+            floatValue: 7.625,
             integerValue: 256,
             longValue: 9873,
             shortValue: 9898,
diff --git a/smithy-protocol-tests/model/rpcv2Cbor/defaults.smithy b/smithy-protocol-tests/model/rpcv2Cbor/defaults.smithy
index a62f26b83..bf1e44834 100644
--- a/smithy-protocol-tests/model/rpcv2Cbor/defaults.smithy
+++ b/smithy-protocol-tests/model/rpcv2Cbor/defaults.smithy
@@ -24,7 +24,7 @@ apply OperationWithDefaults @httpRequestTests([
             "Content-Length"
         ],
         bodyMediaType: "application/cbor"
-        body: "v21kZWZhdWx0U3RyaW5nYmhpbmRlZmF1bHRCb29sZWFu9WtkZWZhdWx0TGlzdIBwZGVmYXVsdFRpbWVzdGFtcMH7AAAAAAAAAABrZGVmYXVsdEJsb2JDYWJja2RlZmF1bHRCeXRlAWxkZWZhdWx0U2hvcnQBbmRlZmF1bHRJbnRlZ2VyCmtkZWZhdWx0TG9uZxhkbGRlZmF1bHRGbG9hdPo/gAAAbWRlZmF1bHREb3VibGX7P/AAAAAAAABqZGVmYXVsdE1hcKBrZGVmYXVsdEVudW1jRk9PbmRlZmF1bHRJbnRFbnVtAWtlbXB0eVN0cmluZ2BsZmFsc2VCb29sZWFu9GllbXB0eUJsb2JAaHplcm9CeXRlAGl6ZXJvU2hvcnQAa3plcm9JbnRlZ2VyAGh6ZXJvTG9uZwBpemVyb0Zsb2F0+gAAAABqemVyb0RvdWJsZfsAAAAAAAAAAP8="
+        body: "v2hkZWZhdWx0c79tZGVmYXVsdFN0cmluZ2JoaW5kZWZhdWx0Qm9vbGVhbvVrZGVmYXVsdExpc3Sf/3BkZWZhdWx0VGltZXN0YW1wwQBrZGVmYXVsdEJsb2JjYWJja2RlZmF1bHRCeXRlAWxkZWZhdWx0U2hvcnQBbmRlZmF1bHRJbnRlZ2VyCmtkZWZhdWx0TG9uZxhkbGRlZmF1bHRGbG9hdPo/gAAAbWRlZmF1bHREb3VibGX6P4AAAGpkZWZhdWx0TWFwv/9rZGVmYXVsdEVudW1jRk9PbmRlZmF1bHRJbnRFbnVtAWtlbXB0eVN0cmluZ2BsZmFsc2VCb29sZWFu9GllbXB0eUJsb2JgaHplcm9CeXRlAGl6ZXJvU2hvcnQAa3plcm9JbnRlZ2VyAGh6ZXJvTG9uZwBpemVyb0Zsb2F0+gAAAABqemVyb0RvdWJsZfoAAAAA//8="
         params: {
             defaults: {}
         }