Skip to content

Commit

Permalink
fix: s3 default execution context attributes overriding previous sect…
Browse files Browse the repository at this point in the history
…ion writers (#1166)
  • Loading branch information
aajtodd authored Dec 28, 2023
1 parent ca6631a commit d4b119d
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 5 deletions.
8 changes: 8 additions & 0 deletions .changes/f0f7ca8d-5690-4449-ace1-e826656a662c.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"id": "f0f7ca8d-5690-4449-ace1-e826656a662c",
"type": "bugfix",
"description": "(**s3**) Fix default execution context attributes",
"issues": [
"awslabs/aws-sdk-kotlin#1165"
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
package aws.sdk.kotlin.codegen.customization.s3

import software.amazon.smithy.kotlin.codegen.KotlinSettings
import software.amazon.smithy.kotlin.codegen.core.KotlinWriter
import software.amazon.smithy.kotlin.codegen.core.RuntimeTypes
import software.amazon.smithy.kotlin.codegen.integration.AppendingSectionWriter
import software.amazon.smithy.kotlin.codegen.integration.KotlinIntegration
import software.amazon.smithy.kotlin.codegen.integration.SectionWriterBinding
import software.amazon.smithy.kotlin.codegen.model.expectShape
Expand All @@ -27,10 +27,12 @@ class S3SigningConfig : KotlinIntegration {
override fun enabledForService(model: Model, settings: KotlinSettings) =
model.expectShape<ServiceShape>(settings.service).isS3

override val sectionWriters: List<SectionWriterBinding> = listOf(
SectionWriterBinding(HttpProtocolClientGenerator.MergeServiceDefaults, ::renderDefaultSigningContext),
)
private fun renderDefaultSigningContext(writer: KotlinWriter, previousValue: String?) {
override val sectionWriters: List<SectionWriterBinding>
get() = listOf(
SectionWriterBinding(HttpProtocolClientGenerator.MergeServiceDefaults, renderDefaultSigningContext),
)

private val renderDefaultSigningContext = AppendingSectionWriter { writer ->
val signingAttrs = RuntimeTypes.Auth.Signing.AwsSigningCommon.AwsSigningAttributes
// https://github.com/awslabs/aws-sdk-kotlin/issues/200
writer.putIfAbsent(signingAttrs, "NormalizeUriPath", "false")
Expand Down
67 changes: 67 additions & 0 deletions services/s3/common/test/aws/sdk/kotlin/services/s3/DefaultsTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package aws.sdk.kotlin.services.s3

import aws.sdk.kotlin.runtime.client.AwsClientOption
import aws.smithy.kotlin.runtime.auth.AuthSchemeId
import aws.smithy.kotlin.runtime.auth.awscredentials.CredentialsProvider
import aws.smithy.kotlin.runtime.auth.awssigning.AwsSignedBodyHeader
import aws.smithy.kotlin.runtime.auth.awssigning.AwsSigningAttributes
import aws.smithy.kotlin.runtime.client.RequestInterceptorContext
import aws.smithy.kotlin.runtime.client.SdkClientOption
import aws.smithy.kotlin.runtime.collections.get
import aws.smithy.kotlin.runtime.http.auth.*
import aws.smithy.kotlin.runtime.http.interceptors.HttpInterceptor
import aws.smithy.kotlin.runtime.httptest.buildTestConnection
import aws.smithy.kotlin.runtime.identity.IdentityProvider
import aws.smithy.kotlin.runtime.identity.IdentityProviderConfig
import aws.smithy.kotlin.runtime.io.use
import kotlinx.coroutines.test.runTest
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNotNull

class DefaultsTest {

/**
* Test execution context gets filled with defaults. This applies to any generated client but S3 has some additional
* things added.
*
* See [aws-sdk-kotlin#1164](https://github.com/awslabs/aws-sdk-kotlin/issues/1165S)
*/
@Test
fun testDefaultExecutionContext() = runTest {
val mockEngine = buildTestConnection { expect() }
val noAuth = object : AuthScheme {
override val schemeId: AuthSchemeId = AuthSchemeId.AwsSigV4
override val signer: HttpSigner = AnonymousHttpSigner
override fun identityProvider(identityProviderConfig: IdentityProviderConfig): IdentityProvider = AnonymousIdentityProvider
}

S3Client {
region = "us-east-1"
httpClient = mockEngine
authSchemes = listOf(noAuth)
interceptors += object : HttpInterceptor {
override fun readBeforeExecution(context: RequestInterceptorContext<Any>) {
assertNotNull(context.executionContext[SdkClientOption.ClientName])
assertNotNull(context.executionContext[SdkClientOption.LogMode])
assertNotNull(context.executionContext[AwsSigningAttributes.CredentialsProvider])

assertEquals(region, context.executionContext[AwsClientOption.Region])
assertEquals(region, context.executionContext[AwsSigningAttributes.SigningRegion])
assertEquals("s3", context.executionContext[AwsSigningAttributes.SigningService])

// S3 specific
assertEquals(false, context.executionContext[AwsSigningAttributes.NormalizeUriPath])
assertEquals(false, context.executionContext[AwsSigningAttributes.UseDoubleUriEncode])
assertEquals(AwsSignedBodyHeader.X_AMZ_CONTENT_SHA256, context.executionContext[AwsSigningAttributes.SignedBodyHeader])
}
}
}.use { s3 ->
s3.listBuckets()
}
}
}

0 comments on commit d4b119d

Please sign in to comment.