Skip to content

Commit a4a4775

Browse files
committed
Fix rendering of :content-type header in event stream requests
1 parent 03cdfb4 commit a4a4775

File tree

3 files changed

+54
-7
lines changed
  • codegen
    • smithy-aws-kotlin-codegen/src
      • main/kotlin/software/amazon/smithy/kotlin/codegen/aws/protocols
      • test/kotlin/software/amazon/smithy/kotlin/codegen/aws/protocols
    • smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/protocol

3 files changed

+54
-7
lines changed

codegen/smithy-aws-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/aws/protocols/RpcV2Cbor.kt

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,12 @@ class RpcV2Cbor : AwsHttpBindingProtocolGenerator() {
139139
writer: KotlinWriter,
140140
resolver: HttpBindingResolver,
141141
) {
142-
writer.write("builder.headers.setMissing(\"Content-Type\", #S)", resolver.determineRequestContentType(op))
142+
val contentTypeHeader = when {
143+
op.isInputEventStream(ctx.model) -> "application/vnd.amazon.eventstream"
144+
else -> "application/cbor"
145+
}
146+
147+
writer.write("builder.headers.setMissing(\"Content-Type\", #S)", contentTypeHeader)
143148
}
144149

145150
class RpcV2CborHttpBindingResolver(
@@ -152,17 +157,13 @@ class RpcV2Cbor : AwsHttpBindingProtocolGenerator() {
152157
"application/cbor",
153158
TimestampFormatTrait.Format.UNKNOWN,
154159
) {
155-
156160
override fun httpTrait(operationShape: OperationShape): HttpTrait = HttpTrait
157161
.builder()
158162
.code(200)
159163
.method("POST")
160164
.uri(UriPattern.parse("/service/${serviceShape.id.name}/operation/${operationShape.id.name}"))
161165
.build()
162166

163-
override fun determineRequestContentType(operationShape: OperationShape): String = when {
164-
operationShape.isInputEventStream(model) -> "application/vnd.amazon.eventstream"
165-
else -> "application/cbor"
166-
}
167+
override fun determineRequestContentType(operationShape: OperationShape): String = "application/cbor"
167168
}
168169
}

codegen/smithy-aws-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/aws/protocols/RpcV2CborTest.kt

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class RpcV2CborTest {
2020
@service(sdkId: "CborExample")
2121
service CborExample {
2222
version: "1.0.0",
23-
operations: [GetFoo, GetFooStreaming]
23+
operations: [GetFoo, GetFooStreaming, PutFooStreaming]
2424
}
2525
2626
@http(method: "POST", uri: "/foo")
@@ -34,7 +34,29 @@ class RpcV2CborTest {
3434
}
3535
}
3636
37+
@http(method: "POST", uri: "/put-foo-streaming")
38+
operation PutFooStreaming {
39+
input: PutFooStreamingInput
40+
}
41+
42+
structure PutFooStreamingInput {
43+
room: String
44+
messages: PublishEvents
45+
}
46+
3747
// Model taken from https://smithy.io/2.0/spec/streaming.html#event-streams
48+
@streaming
49+
union PublishEvents {
50+
message: Message
51+
leave: LeaveEvent
52+
}
53+
54+
structure Message {
55+
message: String
56+
}
57+
58+
structure LeaveEvent {}
59+
3860
@streaming
3961
union FooEvents {
4062
up: Movement
@@ -98,4 +120,27 @@ class RpcV2CborTest {
98120
""".replaceIndent(" ")
99121
getFooMethod.shouldContainOnlyOnceWithDiff(expectedHeaderMutation)
100122
}
123+
124+
@Test
125+
fun testEventStreamContentTypeHeaders() {
126+
val ctx = model.newTestContext("CborExample")
127+
128+
val generator = RpcV2Cbor()
129+
generator.generateProtocolClient(ctx.generationCtx)
130+
131+
ctx.generationCtx.delegator.finalize()
132+
ctx.generationCtx.delegator.flushWriters()
133+
134+
val serializer = ctx.manifest.expectFileString("/src/main/kotlin/com/test/serde/PutFooStreamingOperationSerializer.kt")
135+
136+
// Event stream messages should have `:content-type: application/cbor`
137+
val encodeMessage = serializer.lines("private fun encodePutFooStreamingPublishEventsEventMessage(input: PublishEvents): Message = buildMessage {", "}")
138+
encodeMessage.shouldContainOnlyOnceWithDiff("""
139+
addHeader(":content-type", HeaderValue.String("application/cbor"))
140+
""".trimIndent())
141+
142+
// Event stream requests should have Content-Type=application/vnd.amazon.eventstream
143+
val serializeBody = serializer.lines(" override suspend fun serialize(context: ExecutionContext, input: PutFooStreamingRequest): HttpRequestBuilder {", "}")
144+
serializeBody.shouldContainOnlyOnceWithDiff("""builder.headers.setMissing("Content-Type", "application/vnd.amazon.eventstream")""")
145+
}
101146
}

codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/protocol/HttpBindingProtocolGenerator.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ abstract class HttpBindingProtocolGenerator : ProtocolGenerator {
249249
if (op.isInputEventStream(ctx.model)) {
250250
val eventStreamSerializeFn = eventStreamRequestHandler(ctx, op)
251251
writer.write("builder.body = #T(context, input)", eventStreamSerializeFn)
252+
renderContentTypeHeader(ctx, op, writer, resolver)
252253
} else {
253254
renderSerializeHttpBody(ctx, op, writer)
254255
}

0 commit comments

Comments
 (0)