Skip to content

Commit

Permalink
fix: rpcv2Cbor event stream requests sending incorrect `:content-ty…
Browse files Browse the repository at this point in the history
…pe` (#1180)
  • Loading branch information
lauzadis authored Nov 14, 2024
1 parent 162eff3 commit b3ab799
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 7 deletions.
5 changes: 5 additions & 0 deletions .changes/51a98f59-4a7f-4d14-8f26-4eb70a3eb1dc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"id": "51a98f59-4a7f-4d14-8f26-4eb70a3eb1dc",
"type": "bugfix",
"description": "Fix application of `:content-type` for event stream inputs in the `smithy.protocols#rpcv2Cbor` protocol"
}
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,12 @@ class RpcV2Cbor : AwsHttpBindingProtocolGenerator() {
writer: KotlinWriter,
resolver: HttpBindingResolver,
) {
writer.write("builder.headers.setMissing(\"Content-Type\", #S)", resolver.determineRequestContentType(op))
val contentTypeHeader = when {
op.isInputEventStream(ctx.model) -> "application/vnd.amazon.eventstream"
else -> "application/cbor"
}

writer.write("builder.headers.setMissing(\"Content-Type\", #S)", contentTypeHeader)
}

class RpcV2CborHttpBindingResolver(
Expand All @@ -152,17 +157,13 @@ class RpcV2Cbor : AwsHttpBindingProtocolGenerator() {
"application/cbor",
TimestampFormatTrait.Format.UNKNOWN,
) {

override fun httpTrait(operationShape: OperationShape): HttpTrait = HttpTrait
.builder()
.code(200)
.method("POST")
.uri(UriPattern.parse("/service/${serviceShape.id.name}/operation/${operationShape.id.name}"))
.build()

override fun determineRequestContentType(operationShape: OperationShape): String = when {
operationShape.isInputEventStream(model) -> "application/vnd.amazon.eventstream"
else -> "application/cbor"
}
override fun determineRequestContentType(operationShape: OperationShape): String = "application/cbor"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ val RPC_BOUND_PROTOCOLS = setOf(
"awsJson1_1",
"awsQuery",
"ec2Query",
"rpcv2Cbor",
)

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class RpcV2CborTest {
@service(sdkId: "CborExample")
service CborExample {
version: "1.0.0",
operations: [GetFoo, GetFooStreaming]
operations: [GetFoo, GetFooStreaming, PutFooStreaming]
}
@http(method: "POST", uri: "/foo")
Expand All @@ -34,7 +34,29 @@ class RpcV2CborTest {
}
}
@http(method: "POST", uri: "/put-foo-streaming")
operation PutFooStreaming {
input: PutFooStreamingInput
}
structure PutFooStreamingInput {
room: String
messages: PublishEvents
}
// Model taken from https://smithy.io/2.0/spec/streaming.html#event-streams
@streaming
union PublishEvents {
message: Message
leave: LeaveEvent
}
structure Message {
message: String
}
structure LeaveEvent {}
@streaming
union FooEvents {
up: Movement
Expand Down Expand Up @@ -98,4 +120,29 @@ class RpcV2CborTest {
""".replaceIndent(" ")
getFooMethod.shouldContainOnlyOnceWithDiff(expectedHeaderMutation)
}

@Test
fun testEventStreamContentTypeHeaders() {
val ctx = model.newTestContext("CborExample")

val generator = RpcV2Cbor()
generator.generateProtocolClient(ctx.generationCtx)

ctx.generationCtx.delegator.finalize()
ctx.generationCtx.delegator.flushWriters()

val serializer = ctx.manifest.expectFileString("/src/main/kotlin/com/test/serde/PutFooStreamingOperationSerializer.kt")

// Event stream messages should have `:content-type: application/cbor`
val encodeMessage = serializer.lines("private fun encodePutFooStreamingPublishEventsEventMessage(input: PublishEvents): Message = buildMessage {", "}")
encodeMessage.shouldContainOnlyOnceWithDiff(
"""
addHeader(":content-type", HeaderValue.String("application/cbor"))
""".trimIndent(),
)

// Event stream requests should have Content-Type=application/vnd.amazon.eventstream
val serializeBody = serializer.lines(" override suspend fun serialize(context: ExecutionContext, input: PutFooStreamingRequest): HttpRequestBuilder {", "}")
serializeBody.shouldContainOnlyOnceWithDiff("""builder.headers.setMissing("Content-Type", "application/vnd.amazon.eventstream")""")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ abstract class HttpBindingProtocolGenerator : ProtocolGenerator {
if (op.isInputEventStream(ctx.model)) {
val eventStreamSerializeFn = eventStreamRequestHandler(ctx, op)
writer.write("builder.body = #T(context, input)", eventStreamSerializeFn)
renderContentTypeHeader(ctx, op, writer, resolver)
} else {
renderSerializeHttpBody(ctx, op, writer)
}
Expand Down

0 comments on commit b3ab799

Please sign in to comment.