Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,11 @@ internal fun HttpRequest.toCrtRequest(callContext: CoroutineContext): aws.sdk.ko
headers.forEach { key, values -> appendAll(key, values) }
}

val contentLength = body.contentLength?.toString() ?: headers[CONTENT_LENGTH_HEADER]
val bodyLen = body.contentLength
val contentLength = when {
bodyLen != null -> if (bodyLen > 0) bodyLen.toString() else null
else -> headers[CONTENT_LENGTH_HEADER]
}
contentLength?.let { crtHeaders.append(CONTENT_LENGTH_HEADER, it) }

return aws.sdk.kotlin.crt.http.HttpRequest(method.name, url.encodedPath, crtHeaders.build(), bodyStream)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,18 @@ class RequestConversionTest {
val crtBody = crtRequest.body as ReadChannelBodyStream
crtBody.cancel()
}

@Test
fun testEngineDoesNotAddContentLengthHeaderForEmptyBody() {
val request = HttpRequest(
HttpMethod.POST,
Url.parse("https://test.aws.com?foo=bar"),
Headers.Empty,
HttpBody.Empty
)

val testContext = EmptyCoroutineContext + Job()
val crtRequest = request.toCrtRequest(testContext)
assertFalse(crtRequest.headers.contains("Content-Length"))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,17 @@ package aws.sdk.kotlin.codegen.protocols
import aws.sdk.kotlin.codegen.protocols.core.AwsHttpBindingProtocolGenerator
import aws.sdk.kotlin.codegen.protocols.json.JsonHttpBindingProtocolGenerator
import software.amazon.smithy.aws.traits.protocols.RestJson1Trait
import software.amazon.smithy.kotlin.codegen.core.KotlinWriter
import software.amazon.smithy.kotlin.codegen.core.RuntimeTypes
import software.amazon.smithy.kotlin.codegen.core.defaultName
import software.amazon.smithy.kotlin.codegen.core.withBlock
import software.amazon.smithy.kotlin.codegen.rendering.protocol.*
import software.amazon.smithy.model.Model
import software.amazon.smithy.model.knowledge.HttpBinding
import software.amazon.smithy.model.shapes.OperationShape
import software.amazon.smithy.model.shapes.ServiceShape
import software.amazon.smithy.model.shapes.ShapeId
import software.amazon.smithy.model.shapes.StructureShape

/**
* Handles generating the aws.protocols#restJson1 protocol for services.
Expand All @@ -24,4 +31,32 @@ class RestJson1 : JsonHttpBindingProtocolGenerator() {

override fun getProtocolHttpBindingResolver(model: Model, serviceShape: ServiceShape): HttpBindingResolver =
HttpTraitResolver(model, serviceShape, "application/json")

override fun renderSerializeHttpBody(
ctx: ProtocolGenerator.GenerationContext,
op: OperationShape,
writer: KotlinWriter
) {
super.renderSerializeHttpBody(ctx, op, writer)

val resolver = getProtocolHttpBindingResolver(ctx.model, ctx.service)
if (!resolver.hasHttpBody(op)) return

// restjson1 has some different semantics and expectations around empty structures bound via @httpPayload trait
// * empty structures get serialized to `{}`
// see: https://github.com/awslabs/smithy/pull/924
val requestBindings = resolver.requestBindings(op)
val httpPayload = requestBindings.firstOrNull { it.location == HttpBinding.Location.PAYLOAD }
if (httpPayload != null) {
// explicit payload member as the sole payload
val memberName = httpPayload.member.defaultName()
val target = ctx.model.expectShape(httpPayload.member.target)
if (target is StructureShape) {
writer.withBlock("if (input.#L == null) {", "}", memberName) {
addImport(RuntimeTypes.Http.ByteArrayContent)
write("builder.body = #T(#S.encodeToByteArray())", RuntimeTypes.Http.ByteArrayContent, "{}")
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,6 @@ abstract class AwsHttpBindingProtocolGenerator : HttpBindingProtocolGenerator()
// FIXME - document type not fully supported yet, see https://github.com/awslabs/smithy-kotlin/issues/123
"PutAndGetInlineDocumentsInput",

// aws-sdk-kotlin#390
"RestJsonHttpWithHeaderMemberNoModeledBody",
"RestJsonHttpWithNoModeledBody",
"RestJsonHttpWithEmptyBlobPayload",
"RestJsonHttpWithEmptyStructurePayload",
"RestJsonHttpWithHeadersButNoPayload",

// smithy-kotlin#519
"SimpleScalarPropertiesWithWhiteSpace",
"SimpleScalarPropertiesPureWhiteSpace",
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ org.gradle.jvmargs=-Xmx6g -XX:MaxPermSize=6g -XX:MaxMetaspaceSize=1G
sdkVersion=0.10.0-SNAPSHOT

# codegen
smithyVersion=1.13.0
smithyVersion=1.13.1
smithyGradleVersion=0.5.3
# smithy-kotlin codegen and runtime are versioned together
smithyKotlinVersion=0.7.1-SNAPSHOT
Expand Down