From dd715a1f2527c1aafd5209c56ed8d2c13ef8dee9 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Wed, 19 Mar 2025 09:42:01 -0400 Subject: [PATCH 01/30] Re-enable aws-signing-tests --- .../runtime/auth/awssigning/tests/BasicSigningTestBase.kt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/BasicSigningTestBase.kt b/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/BasicSigningTestBase.kt index 3f4e1e1d17..a99663e17b 100644 --- a/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/BasicSigningTestBase.kt +++ b/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/BasicSigningTestBase.kt @@ -56,7 +56,6 @@ public abstract class BasicSigningTestBase : HasSigner { credentials = DEFAULT_TEST_CREDENTIALS } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test public fun testSignRequestSigV4(): TestResult = runTest { // sanity test @@ -85,7 +84,6 @@ public abstract class BasicSigningTestBase : HasSigner { assertEquals(expectedSig, result.signature.decodeToString()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test public open fun testSignRequestSigV4Asymmetric(): TestResult = runTest { // sanity test @@ -168,7 +166,6 @@ public abstract class BasicSigningTestBase : HasSigner { return chunk } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test public fun testSignChunks(): TestResult = runTest { val request = createChunkedTestRequest() @@ -192,7 +189,6 @@ public abstract class BasicSigningTestBase : HasSigner { assertEquals(EXPECTED_FINAL_CHUNK_SIGNATURE, finalChunkResult.signature.decodeToString()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test public fun testSigningCopiesInput(): TestResult = runTest { // sanity test the signer doesn't mutate the input and instead copies to a new request From 61c9b69f337f9cb17596a3bc855f73ebd55c18a2 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Wed, 19 Mar 2025 10:20:12 -0400 Subject: [PATCH 02/30] Re-enable `testReadAfterExecutionSuppressedException` --- .../kotlin/runtime/http/operation/HttpInterceptorTest.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/HttpInterceptorTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/HttpInterceptorTest.kt index ffa4a4d894..83c90cecfb 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/HttpInterceptorTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/HttpInterceptorTest.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.http.operation -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.client.* import aws.smithy.kotlin.runtime.http.Headers import aws.smithy.kotlin.runtime.http.interceptors.HttpInterceptor @@ -14,6 +13,7 @@ import aws.smithy.kotlin.runtime.http.request.HttpRequestBuilder import aws.smithy.kotlin.runtime.http.request.toBuilder import aws.smithy.kotlin.runtime.http.response.HttpResponse import aws.smithy.kotlin.runtime.http.response.copy +import io.ktor.util.internal.initCauseBridge import kotlinx.coroutines.test.runTest import kotlin.IllegalStateException import kotlin.test.* @@ -236,7 +236,6 @@ class HttpInterceptorTest { testMapFailure(interceptor) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testReadAfterExecutionSuppressedException() = runTest { val interceptor = object : HttpInterceptor { @@ -261,7 +260,7 @@ class HttpInterceptorTest { op.roundTrip(client, Unit) } - val cause = assertNotNull(ex.cause) + val cause = assertNotNull(ex.cause ?: ex) assertEquals(1, cause.suppressedExceptions.size) assertIs(cause.suppressedExceptions.last()) } From f5660b528d7aea342cf6908cc020f4f2296a303e Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Wed, 19 Mar 2025 10:20:39 -0400 Subject: [PATCH 03/30] ktlint --- .../kotlin/runtime/auth/awssigning/tests/BasicSigningTestBase.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/BasicSigningTestBase.kt b/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/BasicSigningTestBase.kt index a99663e17b..2a517fc090 100644 --- a/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/BasicSigningTestBase.kt +++ b/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/BasicSigningTestBase.kt @@ -4,7 +4,6 @@ */ package aws.smithy.kotlin.runtime.auth.awssigning.tests -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.auth.awscredentials.Credentials import aws.smithy.kotlin.runtime.auth.awssigning.* import aws.smithy.kotlin.runtime.http.HttpBody From 1281338ef316adb46b4a77e47c35d293f6b87516 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Wed, 19 Mar 2025 10:46:55 -0400 Subject: [PATCH 04/30] Re-enable some tests --- .../kotlin/runtime/crt/ReadChannelBodyStreamTest.kt | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/runtime/crt-util/jvmAndNative/test/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStreamTest.kt b/runtime/crt-util/jvmAndNative/test/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStreamTest.kt index b4afa25c91..ff72f4df18 100644 --- a/runtime/crt-util/jvmAndNative/test/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStreamTest.kt +++ b/runtime/crt-util/jvmAndNative/test/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStreamTest.kt @@ -27,7 +27,6 @@ class ReadChannelBodyStreamTest { return MutableBuffer.of(dest) to dest } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation. kotlin.native.internal.FileFailedToInitializeException at null:-1 @Test fun testClose() = runTest { val chan = SdkByteChannel() @@ -44,7 +43,6 @@ class ReadChannelBodyStreamTest { assertTrue(stream.sendRequestBody(sendBuffer)) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation. kotlin.native.internal.FileFailedToInitializeException at null:-1 @Test fun testCancellation() = runTest { val chan = SdkByteChannel() @@ -59,7 +57,7 @@ class ReadChannelBodyStreamTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation. kotlin.NotImplementedError at null:-1 + @IgnoreNative // FIXME Need to implement transferRequestBody @Test fun testReadFully() = runTest { val data = byteArrayOf(1, 2, 3, 4, 5) @@ -75,7 +73,7 @@ class ReadChannelBodyStreamTest { } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation. kotlin.NotImplementedError at null:-1 + @IgnoreNative // FIXME Need to implement transferRequestBody @Test fun testPartialRead() = runTest { val chan = SdkByteReadChannel("123456".encodeToByteArray()) @@ -94,7 +92,7 @@ class ReadChannelBodyStreamTest { assertEquals("456", sent2.decodeToString()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation. kotlin.native.internal.FileFailedToInitializeException at null:-1 + @IgnoreNative // FIXME Need to implement transferRequestBody @Test fun testLargeTransfer() = runTest { val chan = SdkByteChannel() From 986907fb9e7f84bec6a33092a3ca58373085500e Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Wed, 19 Mar 2025 10:50:30 -0400 Subject: [PATCH 05/30] Initialize CRT in CrtAwsSigner --- runtime/auth/aws-signing-crt/api/aws-signing-crt.api | 2 +- .../smithy/kotlin/runtime/auth/awssigning/crt/CrtAwsSigner.kt | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/runtime/auth/aws-signing-crt/api/aws-signing-crt.api b/runtime/auth/aws-signing-crt/api/aws-signing-crt.api index ed1934cac9..39dc9fdf45 100644 --- a/runtime/auth/aws-signing-crt/api/aws-signing-crt.api +++ b/runtime/auth/aws-signing-crt/api/aws-signing-crt.api @@ -1,4 +1,4 @@ -public final class aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtAwsSigner : aws/smithy/kotlin/runtime/auth/awssigning/AwsSigner { +public final class aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtAwsSigner : aws/sdk/kotlin/crt/WithCrt, aws/smithy/kotlin/runtime/auth/awssigning/AwsSigner { public static final field INSTANCE Laws/smithy/kotlin/runtime/auth/awssigning/crt/CrtAwsSigner; public fun sign (Laws/smithy/kotlin/runtime/http/request/HttpRequest;Laws/smithy/kotlin/runtime/auth/awssigning/AwsSigningConfig;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun signChunk ([B[BLaws/smithy/kotlin/runtime/auth/awssigning/AwsSigningConfig;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; diff --git a/runtime/auth/aws-signing-crt/jvmAndNative/src/aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtAwsSigner.kt b/runtime/auth/aws-signing-crt/jvmAndNative/src/aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtAwsSigner.kt index c0069c1aca..b73d8cb8f3 100644 --- a/runtime/auth/aws-signing-crt/jvmAndNative/src/aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtAwsSigner.kt +++ b/runtime/auth/aws-signing-crt/jvmAndNative/src/aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtAwsSigner.kt @@ -21,10 +21,11 @@ import aws.sdk.kotlin.crt.auth.signing.AwsSigner as CrtSigner import aws.sdk.kotlin.crt.auth.signing.AwsSigningAlgorithm as CrtSigningAlgorithm import aws.sdk.kotlin.crt.auth.signing.AwsSigningConfig as CrtSigningConfig import aws.sdk.kotlin.crt.http.Headers as CrtHeaders +import aws.sdk.kotlin.crt.WithCrt private const val S3_EXPRESS_HEADER_NAME = "X-Amz-S3session-Token" -public object CrtAwsSigner : AwsSigner { +public object CrtAwsSigner : AwsSigner, WithCrt() { override suspend fun sign(request: HttpRequest, config: AwsSigningConfig): AwsSigningResult { val isUnsigned = config.hashSpecification is HashSpecification.UnsignedPayload val isAwsChunked = request.headers.contains("Content-Encoding", "aws-chunked") From 9f8999e045335ac28b4046a8717c233c31ae58cd Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Wed, 19 Mar 2025 10:56:16 -0400 Subject: [PATCH 06/30] Update FIXME message --- .../kotlin/runtime/http/auth/AwsHttpSignerTestBase.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/runtime/auth/http-auth-aws/common/test/aws/smithy/kotlin/runtime/http/auth/AwsHttpSignerTestBase.kt b/runtime/auth/http-auth-aws/common/test/aws/smithy/kotlin/runtime/http/auth/AwsHttpSignerTestBase.kt index 1786744b01..8f1e9eed40 100644 --- a/runtime/auth/http-auth-aws/common/test/aws/smithy/kotlin/runtime/http/auth/AwsHttpSignerTestBase.kt +++ b/runtime/auth/http-auth-aws/common/test/aws/smithy/kotlin/runtime/http/auth/AwsHttpSignerTestBase.kt @@ -134,7 +134,7 @@ public abstract class AwsHttpSignerTestBase( assertEquals(expectedSig, signed.headers["Authorization"]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation. + @IgnoreNative // FIXME Native signed request has additional `transfer-encoding` header @Test public fun testSignReplayableStreamingRequest(): TestResult = runTest { val op = buildOperation(streaming = true) @@ -148,7 +148,7 @@ public abstract class AwsHttpSignerTestBase( assertEquals(expectedSig, signed.headers["Authorization"]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation. + @IgnoreNative // FIXME Native signed request has additional `transfer-encoding` header @Test public fun testSignAwsChunkedStreamNonReplayable(): TestResult = runTest { val op = buildOperation(streaming = true, replayable = false, requestBody = "a".repeat(AWS_CHUNKED_THRESHOLD + 1)) @@ -162,7 +162,7 @@ public abstract class AwsHttpSignerTestBase( assertEquals(expectedSig, signed.headers["Authorization"]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation. + @IgnoreNative // FIXME Native signed request has additional `transfer-encoding` header @Test public fun testSignAwsChunkedStreamReplayable(): TestResult = runTest { val op = buildOperation(streaming = true, replayable = true, requestBody = "a".repeat(AWS_CHUNKED_THRESHOLD + 1)) @@ -176,7 +176,7 @@ public abstract class AwsHttpSignerTestBase( assertEquals(expectedSig, signed.headers["Authorization"]) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation. + @IgnoreNative // FIXME Native signed request has additional `transfer-encoding` header @Test public fun testSignOneShotStream(): TestResult = runTest { val op = buildOperation(streaming = true, replayable = false) From 3fca2672f27a3785b8d1e06f4a248cc8c89bef1d Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Wed, 19 Mar 2025 11:15:26 -0400 Subject: [PATCH 07/30] Ignore SigV4a test on Native --- .../runtime/auth/awssigning/tests/BasicSigningTestBase.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/BasicSigningTestBase.kt b/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/BasicSigningTestBase.kt index 2a517fc090..6427919615 100644 --- a/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/BasicSigningTestBase.kt +++ b/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/BasicSigningTestBase.kt @@ -4,6 +4,7 @@ */ package aws.smithy.kotlin.runtime.auth.awssigning.tests +import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.auth.awscredentials.Credentials import aws.smithy.kotlin.runtime.auth.awssigning.* import aws.smithy.kotlin.runtime.http.HttpBody @@ -83,6 +84,8 @@ public abstract class BasicSigningTestBase : HasSigner { assertEquals(expectedSig, result.signature.decodeToString()) } + @IgnoreNative // ecdsaSecp256r1 not implemented on Native. Can we make the signer implementation expect/actual and + // use CRT signer on Native? @Test public open fun testSignRequestSigV4Asymmetric(): TestResult = runTest { // sanity test From ba8f1cb93f831369e35ab76e08300d7d9873953c Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Wed, 19 Mar 2025 11:25:09 -0400 Subject: [PATCH 08/30] Re-enable `AwsChunkedByteReadChannelTestBase` --- .../auth/awssigning/tests/AwsChunkedByteReadChannelTestBase.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/AwsChunkedByteReadChannelTestBase.kt b/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/AwsChunkedByteReadChannelTestBase.kt index 3374dedc42..686105bd86 100644 --- a/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/AwsChunkedByteReadChannelTestBase.kt +++ b/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/AwsChunkedByteReadChannelTestBase.kt @@ -18,7 +18,6 @@ import kotlin.test.* import kotlin.time.Duration.Companion.milliseconds abstract class AwsChunkedByteReadChannelTestBase : AwsChunkedTestBase(AwsChunkedReaderFactory.Channel) { - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testSlowProducerMultipleChunksPartialLast(): TestResult = runTest { val numChunks = 6 From 3bbc14a882db7a32cf9b1889d7776bf3f0b3bf30 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Wed, 19 Mar 2025 11:29:20 -0400 Subject: [PATCH 09/30] Re-enable `AwsChunkedTestBase` --- .../runtime/auth/awssigning/tests/AwsChunkedTestBase.kt | 9 --------- 1 file changed, 9 deletions(-) diff --git a/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/AwsChunkedTestBase.kt b/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/AwsChunkedTestBase.kt index be05b88eb9..37f824476d 100644 --- a/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/AwsChunkedTestBase.kt +++ b/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/AwsChunkedTestBase.kt @@ -172,7 +172,6 @@ abstract class AwsChunkedTestBase( return length } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testReadNegativeOffset(): TestResult = runTest { val dataLengthBytes = CHUNK_SIZE_BYTES @@ -186,7 +185,6 @@ abstract class AwsChunkedTestBase( } } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testReadExactBytes(): TestResult = runTest { val dataLengthBytes = CHUNK_SIZE_BYTES @@ -220,7 +218,6 @@ abstract class AwsChunkedTestBase( assertTrue(awsChunked.isClosedForRead()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testReadExcessiveBytes(): TestResult = runTest { val dataLengthBytes = CHUNK_SIZE_BYTES @@ -250,7 +247,6 @@ abstract class AwsChunkedTestBase( assertTrue(awsChunked.isClosedForRead()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testReadFewerBytes(): TestResult = runTest { val dataLengthBytes = CHUNK_SIZE_BYTES @@ -277,7 +273,6 @@ abstract class AwsChunkedTestBase( assertFalse(awsChunked.isClosedForRead()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testReadMultipleFullChunks(): TestResult = runTest { val numChunks = 5 @@ -325,7 +320,6 @@ abstract class AwsChunkedTestBase( assertTrue(awsChunked.isClosedForRead()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation @Test fun testReadMultipleChunksLastChunkNotFull(): TestResult = runTest { val numChunks = 6 @@ -391,7 +385,6 @@ abstract class AwsChunkedTestBase( assertEquals(0, chunkSizes.last()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testReadWithTrailingHeaders(): TestResult = runTest { val dataLengthBytes = CHUNK_SIZE_BYTES @@ -442,7 +435,6 @@ abstract class AwsChunkedTestBase( assertEquals(expectedTrailerSignature.decodeToString(), trailerSignature) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testUnsignedChunk(): TestResult = runTest { val dataLengthBytes = CHUNK_SIZE_BYTES @@ -474,7 +466,6 @@ abstract class AwsChunkedTestBase( assertEquals(chunkSizes[1], 0) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation @Test fun testUnsignedChunkWithTrailingHeaders(): TestResult = runTest { val dataLengthBytes = CHUNK_SIZE_BYTES From 00d10a59a19dda0ab070a427d1bc923ec996b65c Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Wed, 19 Mar 2025 11:32:44 -0400 Subject: [PATCH 10/30] Initialize CRT runtime to get correct error code --- .../runtime/http/engine/crt/SdkStreamResponseHandlerTest.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/SdkStreamResponseHandlerTest.kt b/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/SdkStreamResponseHandlerTest.kt index 7382adcca4..21843ef546 100644 --- a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/SdkStreamResponseHandlerTest.kt +++ b/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/SdkStreamResponseHandlerTest.kt @@ -5,9 +5,9 @@ package aws.smithy.kotlin.runtime.http.engine.crt +import aws.sdk.kotlin.crt.CRT import aws.sdk.kotlin.crt.http.* import aws.sdk.kotlin.crt.io.byteArrayBuffer -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.http.HttpBody import aws.smithy.kotlin.runtime.http.HttpErrorCode import aws.smithy.kotlin.runtime.http.HttpException @@ -153,9 +153,9 @@ class SdkStreamResponseHandlerTest { assertEquals(data, respChan.readToBuffer().readUtf8()) } - @IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation. @Test fun testStreamError() = runTest { + CRT.initRuntime() val handler = SdkStreamResponseHandler(mockConn, coroutineContext) val stream = MockHttpStream(200) val data = "foo bar" From eac050202fdfaaf9e07597a0ce669af25a4defc6 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Wed, 19 Mar 2025 11:32:55 -0400 Subject: [PATCH 11/30] Update FIXME message --- .../smithy/kotlin/runtime/http/engine/crt/AsyncStressTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/AsyncStressTest.kt b/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/AsyncStressTest.kt index 7d0b0def83..2d91bbb88c 100644 --- a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/AsyncStressTest.kt +++ b/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/AsyncStressTest.kt @@ -37,7 +37,7 @@ class AsyncStressTest : TestWithLocalServer() { } }.start() - @IgnoreNative // FIXME Re-enable after Kotlin/Native implementation + @IgnoreNative // FIXME CRT HTTP engine @Test fun testStreamNotConsumed() = runBlocking { // test that filling the stream window and not consuming the body stream still cleans up resources From a0d2fc512e235c46ff300998585600f6ef401e52 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Wed, 19 Mar 2025 11:41:30 -0400 Subject: [PATCH 12/30] ktlint --- .../smithy/kotlin/runtime/auth/awssigning/crt/CrtAwsSigner.kt | 2 +- .../auth/awssigning/tests/AwsChunkedByteReadChannelTestBase.kt | 1 - .../kotlin/runtime/auth/awssigning/tests/AwsChunkedTestBase.kt | 1 - .../smithy/kotlin/runtime/http/operation/HttpInterceptorTest.kt | 1 - 4 files changed, 1 insertion(+), 4 deletions(-) diff --git a/runtime/auth/aws-signing-crt/jvmAndNative/src/aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtAwsSigner.kt b/runtime/auth/aws-signing-crt/jvmAndNative/src/aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtAwsSigner.kt index b73d8cb8f3..ac039d519b 100644 --- a/runtime/auth/aws-signing-crt/jvmAndNative/src/aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtAwsSigner.kt +++ b/runtime/auth/aws-signing-crt/jvmAndNative/src/aws/smithy/kotlin/runtime/auth/awssigning/crt/CrtAwsSigner.kt @@ -4,6 +4,7 @@ */ package aws.smithy.kotlin.runtime.auth.awssigning.crt +import aws.sdk.kotlin.crt.WithCrt import aws.smithy.kotlin.runtime.auth.awscredentials.Credentials import aws.smithy.kotlin.runtime.auth.awssigning.* import aws.smithy.kotlin.runtime.crt.toSignableCrtRequest @@ -21,7 +22,6 @@ import aws.sdk.kotlin.crt.auth.signing.AwsSigner as CrtSigner import aws.sdk.kotlin.crt.auth.signing.AwsSigningAlgorithm as CrtSigningAlgorithm import aws.sdk.kotlin.crt.auth.signing.AwsSigningConfig as CrtSigningConfig import aws.sdk.kotlin.crt.http.Headers as CrtHeaders -import aws.sdk.kotlin.crt.WithCrt private const val S3_EXPRESS_HEADER_NAME = "X-Amz-S3session-Token" diff --git a/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/AwsChunkedByteReadChannelTestBase.kt b/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/AwsChunkedByteReadChannelTestBase.kt index 686105bd86..f86ef5ba3a 100644 --- a/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/AwsChunkedByteReadChannelTestBase.kt +++ b/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/AwsChunkedByteReadChannelTestBase.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.auth.awssigning.tests -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.auth.awssigning.* import aws.smithy.kotlin.runtime.auth.awssigning.internal.CHUNK_SIZE_BYTES import aws.smithy.kotlin.runtime.io.* diff --git a/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/AwsChunkedTestBase.kt b/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/AwsChunkedTestBase.kt index 37f824476d..10247109ae 100644 --- a/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/AwsChunkedTestBase.kt +++ b/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/AwsChunkedTestBase.kt @@ -5,7 +5,6 @@ package aws.smithy.kotlin.runtime.auth.awssigning.tests -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.auth.awssigning.* import aws.smithy.kotlin.runtime.auth.awssigning.internal.CHUNK_SIZE_BYTES import aws.smithy.kotlin.runtime.http.DeferredHeaders diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/HttpInterceptorTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/HttpInterceptorTest.kt index 83c90cecfb..4e75b8b59e 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/HttpInterceptorTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/HttpInterceptorTest.kt @@ -13,7 +13,6 @@ import aws.smithy.kotlin.runtime.http.request.HttpRequestBuilder import aws.smithy.kotlin.runtime.http.request.toBuilder import aws.smithy.kotlin.runtime.http.response.HttpResponse import aws.smithy.kotlin.runtime.http.response.copy -import io.ktor.util.internal.initCauseBridge import kotlinx.coroutines.test.runTest import kotlin.IllegalStateException import kotlin.test.* From d8878a3e91899996c68eda91e4063c46cffa54f1 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Wed, 19 Mar 2025 11:48:56 -0400 Subject: [PATCH 13/30] Implement transferRequestBody --- .../smithy/kotlin/runtime/crt/ReadChannelBodyStreamTest.kt | 4 ---- .../kotlin/runtime/crt/ReadChannelBodyStreamNative.kt | 6 +++++- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/runtime/crt-util/jvmAndNative/test/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStreamTest.kt b/runtime/crt-util/jvmAndNative/test/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStreamTest.kt index ff72f4df18..eb0acf777e 100644 --- a/runtime/crt-util/jvmAndNative/test/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStreamTest.kt +++ b/runtime/crt-util/jvmAndNative/test/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStreamTest.kt @@ -6,7 +6,6 @@ package aws.smithy.kotlin.runtime.crt import aws.sdk.kotlin.crt.io.MutableBuffer -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.io.SdkBuffer import aws.smithy.kotlin.runtime.io.SdkByteChannel import aws.smithy.kotlin.runtime.io.SdkByteReadChannel @@ -57,7 +56,6 @@ class ReadChannelBodyStreamTest { } } - @IgnoreNative // FIXME Need to implement transferRequestBody @Test fun testReadFully() = runTest { val data = byteArrayOf(1, 2, 3, 4, 5) @@ -73,7 +71,6 @@ class ReadChannelBodyStreamTest { } } - @IgnoreNative // FIXME Need to implement transferRequestBody @Test fun testPartialRead() = runTest { val chan = SdkByteReadChannel("123456".encodeToByteArray()) @@ -92,7 +89,6 @@ class ReadChannelBodyStreamTest { assertEquals("456", sent2.decodeToString()) } - @IgnoreNative // FIXME Need to implement transferRequestBody @Test fun testLargeTransfer() = runTest { val chan = SdkByteChannel() diff --git a/runtime/crt-util/native/src/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStreamNative.kt b/runtime/crt-util/native/src/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStreamNative.kt index 09eb88dfd8..e27805bbf6 100644 --- a/runtime/crt-util/native/src/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStreamNative.kt +++ b/runtime/crt-util/native/src/aws/smithy/kotlin/runtime/crt/ReadChannelBodyStreamNative.kt @@ -7,4 +7,8 @@ package aws.smithy.kotlin.runtime.crt import aws.sdk.kotlin.crt.io.MutableBuffer import aws.smithy.kotlin.runtime.io.SdkBuffer -internal actual fun transferRequestBody(outgoing: SdkBuffer, dest: MutableBuffer): Int = TODO("Not yet implemented") +internal actual fun transferRequestBody(outgoing: SdkBuffer, dest: MutableBuffer): Int { + val length = minOf(outgoing.size, dest.writeRemaining.toLong()) + if (length <= 0) return 0 + return dest.write(outgoing.readByteArray(length)) +} From 1eebd5ea9679b9b3796267d72d3a93b7ba81549c Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Wed, 19 Mar 2025 12:06:03 -0400 Subject: [PATCH 14/30] Update FIXME message --- .../smithy/kotlin/runtime/http/engine/crt/AsyncStressTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/AsyncStressTest.kt b/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/AsyncStressTest.kt index 2d91bbb88c..e509808ec1 100644 --- a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/AsyncStressTest.kt +++ b/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/AsyncStressTest.kt @@ -37,7 +37,7 @@ class AsyncStressTest : TestWithLocalServer() { } }.start() - @IgnoreNative // FIXME CRT HTTP engine + @IgnoreNative // FIXME TlsContext needs to initialize CRT. Segmentation fault. @Test fun testStreamNotConsumed() = runBlocking { // test that filling the stream window and not consuming the body stream still cleans up resources From 27af57efc142611337a45bf73dd249a252423db0 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Wed, 19 Mar 2025 12:28:31 -0400 Subject: [PATCH 15/30] Make `DefaultAwsSigner` expect/actual, point to CRT signer on Native --- .../api/aws-signing-default.api | 2 +- .../auth/aws-signing-default/build.gradle.kts | 6 + .../auth/awssigning/DefaultAwsSigner.kt | 133 +----------------- .../runtime/auth/awssigning/RequestMutator.kt | 19 +++ .../auth/awssigning/DefaultAwsSignerJVM.kt | 121 ++++++++++++++++ .../auth/awssigning/DefaultAwsSignerNative.kt | 11 ++ .../awssigning/tests/BasicSigningTestBase.kt | 2 - .../kotlin/runtime/hashing/EcdsaNative.kt | 5 +- 8 files changed, 160 insertions(+), 139 deletions(-) create mode 100644 runtime/auth/aws-signing-default/jvm/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSignerJVM.kt create mode 100644 runtime/auth/aws-signing-default/native/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSignerNative.kt diff --git a/runtime/auth/aws-signing-default/api/aws-signing-default.api b/runtime/auth/aws-signing-default/api/aws-signing-default.api index e00e6d829a..15ca42c07e 100644 --- a/runtime/auth/aws-signing-default/api/aws-signing-default.api +++ b/runtime/auth/aws-signing-default/api/aws-signing-default.api @@ -5,7 +5,7 @@ public final class aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSignerBui public final fun setTelemetryProvider (Laws/smithy/kotlin/runtime/telemetry/TelemetryProvider;)V } -public final class aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSignerKt { +public final class aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSignerJVMKt { public static final fun DefaultAwsSigner (Lkotlin/jvm/functions/Function1;)Laws/smithy/kotlin/runtime/auth/awssigning/AwsSigner; public static final fun getDefaultAwsSigner ()Laws/smithy/kotlin/runtime/auth/awssigning/AwsSigner; } diff --git a/runtime/auth/aws-signing-default/build.gradle.kts b/runtime/auth/aws-signing-default/build.gradle.kts index 22e20d39fd..71781c66c7 100644 --- a/runtime/auth/aws-signing-default/build.gradle.kts +++ b/runtime/auth/aws-signing-default/build.gradle.kts @@ -25,5 +25,11 @@ kotlin { all { languageSettings.optIn("aws.smithy.kotlin.runtime.InternalApi") } + + nativeMain { + dependencies { + implementation(project(":runtime:auth:aws-signing-crt")) + } + } } } diff --git a/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSigner.kt b/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSigner.kt index 85896349b1..df5d2076b9 100644 --- a/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSigner.kt +++ b/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSigner.kt @@ -4,136 +4,5 @@ */ package aws.smithy.kotlin.runtime.auth.awssigning -import aws.smithy.kotlin.runtime.ExperimentalApi -import aws.smithy.kotlin.runtime.http.Headers -import aws.smithy.kotlin.runtime.http.request.HttpRequest -import aws.smithy.kotlin.runtime.telemetry.TelemetryProvider -import aws.smithy.kotlin.runtime.telemetry.logging.logger -import aws.smithy.kotlin.runtime.time.TimestampFormat -import kotlin.coroutines.coroutineContext - /** The default implementation of [AwsSigner] */ -public val DefaultAwsSigner: AwsSigner = DefaultAwsSignerImpl() - -/** Creates a customized instance of [AwsSigner] */ -@Suppress("ktlint:standard:function-naming") -public fun DefaultAwsSigner(block: DefaultAwsSignerBuilder.() -> Unit): AwsSigner = - DefaultAwsSignerBuilder().apply(block).build() - -/** A builder class for creating instances of [AwsSigner] using the default implementation */ -public class DefaultAwsSignerBuilder { - public var telemetryProvider: TelemetryProvider? = null - - public fun build(): AwsSigner = DefaultAwsSignerImpl( - telemetryProvider = telemetryProvider, - ) -} - -private val AwsSigningAlgorithm.signatureCalculator - get() = when (this) { - AwsSigningAlgorithm.SIGV4 -> SignatureCalculator.SigV4 - AwsSigningAlgorithm.SIGV4_ASYMMETRIC -> SignatureCalculator.SigV4a - } - -@OptIn(ExperimentalApi::class) -internal class DefaultAwsSignerImpl( - private val canonicalizer: Canonicalizer = Canonicalizer.Default, - private val requestMutator: RequestMutator = RequestMutator.Default, - private val telemetryProvider: TelemetryProvider? = null, -) : AwsSigner { - override suspend fun sign(request: HttpRequest, config: AwsSigningConfig): AwsSigningResult { - val logger = telemetryProvider?.loggerProvider?.getOrCreateLogger("DefaultAwsSigner") - ?: coroutineContext.logger() - - val canonical = canonicalizer.canonicalRequest(request, config) - if (config.logRequest) { - logger.trace { "Canonical request:\n${canonical.requestString}" } - } - - val signatureCalculator = config.algorithm.signatureCalculator - - val stringToSign = signatureCalculator.stringToSign(canonical.requestString, config) - logger.trace { "String to sign:\n$stringToSign" } - - val signingKey = signatureCalculator.signingKey(config) - - val signature = signatureCalculator.calculate(signingKey, stringToSign) - logger.debug { "Calculated signature: $signature" } - - val signedRequest = requestMutator.appendAuth(config, canonical, signature) - - return AwsSigningResult(signedRequest, signature.encodeToByteArray()) - } - - override suspend fun signChunk( - chunkBody: ByteArray, - prevSignature: ByteArray, - config: AwsSigningConfig, - ): AwsSigningResult { - val logger = telemetryProvider?.loggerProvider?.getOrCreateLogger("DefaultAwsSigner") - ?: coroutineContext.logger() - - val signatureCalculator = config.algorithm.signatureCalculator - - val stringToSign = signatureCalculator.chunkStringToSign(chunkBody, prevSignature, config) - logger.trace { "Chunk string to sign:\n$stringToSign" } - - val signingKey = signatureCalculator.signingKey(config) - - val signature = signatureCalculator.calculate(signingKey, stringToSign) - logger.debug { "Calculated chunk signature: $signature" } - - return AwsSigningResult(Unit, signature.encodeToByteArray()) - } - - override suspend fun signChunkTrailer( - trailingHeaders: Headers, - prevSignature: ByteArray, - config: AwsSigningConfig, - ): AwsSigningResult { - val logger = telemetryProvider?.loggerProvider?.getOrCreateLogger("DefaultAwsSigner") - ?: coroutineContext.logger() - - val signatureCalculator = config.algorithm.signatureCalculator - - // FIXME - can we share canonicalization code more than we are..., also this reduce is inefficient. - // canonicalize the headers - val trailingHeadersBytes = trailingHeaders.entries().sortedBy { e -> e.key.lowercase() } - .map { e -> - buildString { - append(e.key.lowercase()) - append(":") - append(e.value.joinToString(",") { v -> v.trim() }) - append("\n") - }.encodeToByteArray() - }.reduce { acc, bytes -> acc + bytes } - - val stringToSign = signatureCalculator.chunkTrailerStringToSign(trailingHeadersBytes, prevSignature, config) - logger.trace { "Chunk trailer string to sign:\n$stringToSign" } - - val signingKey = signatureCalculator.signingKey(config) - - val signature = signatureCalculator.calculate(signingKey, stringToSign) - logger.debug { "Calculated chunk signature: $signature" } - - return AwsSigningResult(Unit, signature.encodeToByteArray()) - } -} - -/** - * Formats a credential scope consisting of a signing date, region (SigV4 only), service, and a signature type - */ -internal val AwsSigningConfig.credentialScope: String - get() = run { - val signingDate = signingDate.format(TimestampFormat.ISO_8601_CONDENSED_DATE) - return when (algorithm) { - AwsSigningAlgorithm.SIGV4 -> "$signingDate/$region/$service/aws4_request" - AwsSigningAlgorithm.SIGV4_ASYMMETRIC -> "$signingDate/$service/aws4_request" - } - } - -/** - * Formats the value for a credential header/parameter - */ -internal fun credentialValue(config: AwsSigningConfig): String = - "${config.credentials.accessKeyId}/${config.credentialScope}" +public expect val DefaultAwsSigner: AwsSigner diff --git a/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/RequestMutator.kt b/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/RequestMutator.kt index 0c1882cd54..e0286249ca 100644 --- a/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/RequestMutator.kt +++ b/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/RequestMutator.kt @@ -5,6 +5,7 @@ package aws.smithy.kotlin.runtime.auth.awssigning import aws.smithy.kotlin.runtime.http.request.HttpRequest +import aws.smithy.kotlin.runtime.time.TimestampFormat /** * An object that can mutate requests to include signing attributes. @@ -55,3 +56,21 @@ internal class DefaultRequestMutator : RequestMutator { return canonical.request.build() } } + +/** + * Formats a credential scope consisting of a signing date, region (SigV4 only), service, and a signature type + */ +internal val AwsSigningConfig.credentialScope: String + get() = run { + val signingDate = signingDate.format(TimestampFormat.ISO_8601_CONDENSED_DATE) + return when (algorithm) { + AwsSigningAlgorithm.SIGV4 -> "$signingDate/$region/$service/aws4_request" + AwsSigningAlgorithm.SIGV4_ASYMMETRIC -> "$signingDate/$service/aws4_request" + } + } + +/** + * Formats the value for a credential header/parameter + */ +internal fun credentialValue(config: AwsSigningConfig): String = + "${config.credentials.accessKeyId}/${config.credentialScope}" \ No newline at end of file diff --git a/runtime/auth/aws-signing-default/jvm/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSignerJVM.kt b/runtime/auth/aws-signing-default/jvm/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSignerJVM.kt new file mode 100644 index 0000000000..b2642717cf --- /dev/null +++ b/runtime/auth/aws-signing-default/jvm/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSignerJVM.kt @@ -0,0 +1,121 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +package aws.smithy.kotlin.runtime.auth.awssigning + +import aws.smithy.kotlin.runtime.ExperimentalApi +import aws.smithy.kotlin.runtime.http.Headers +import aws.smithy.kotlin.runtime.http.request.HttpRequest +import aws.smithy.kotlin.runtime.telemetry.TelemetryProvider +import aws.smithy.kotlin.runtime.telemetry.logging.logger +import kotlin.coroutines.coroutineContext + +/** The default implementation of [AwsSigner] */ +public actual val DefaultAwsSigner: AwsSigner + get() = DefaultAwsSignerImpl() + +/** Creates a customized instance of [AwsSigner] */ +@Suppress("ktlint:standard:function-naming") +public fun DefaultAwsSigner(block: DefaultAwsSignerBuilder.() -> Unit): AwsSigner = + DefaultAwsSignerBuilder().apply(block).build() + +/** A builder class for creating instances of [AwsSigner] using the default implementation */ +public class DefaultAwsSignerBuilder { + public var telemetryProvider: TelemetryProvider? = null + + public fun build(): AwsSigner = DefaultAwsSignerImpl( + telemetryProvider = telemetryProvider, + ) +} + +private val AwsSigningAlgorithm.signatureCalculator + get() = when (this) { + AwsSigningAlgorithm.SIGV4 -> SignatureCalculator.SigV4 + AwsSigningAlgorithm.SIGV4_ASYMMETRIC -> SignatureCalculator.SigV4a + } + +@OptIn(ExperimentalApi::class) +internal class DefaultAwsSignerImpl( + private val canonicalizer: Canonicalizer = Canonicalizer.Default, + private val requestMutator: RequestMutator = RequestMutator.Default, + private val telemetryProvider: TelemetryProvider? = null, +) : AwsSigner { + override suspend fun sign(request: HttpRequest, config: AwsSigningConfig): AwsSigningResult { + val logger = telemetryProvider?.loggerProvider?.getOrCreateLogger("DefaultAwsSigner") + ?: coroutineContext.logger() + + val canonical = canonicalizer.canonicalRequest(request, config) + if (config.logRequest) { + logger.trace { "Canonical request:\n${canonical.requestString}" } + } + + val signatureCalculator = config.algorithm.signatureCalculator + + val stringToSign = signatureCalculator.stringToSign(canonical.requestString, config) + logger.trace { "String to sign:\n$stringToSign" } + + val signingKey = signatureCalculator.signingKey(config) + + val signature = signatureCalculator.calculate(signingKey, stringToSign) + logger.debug { "Calculated signature: $signature" } + + val signedRequest = requestMutator.appendAuth(config, canonical, signature) + + return AwsSigningResult(signedRequest, signature.encodeToByteArray()) + } + + override suspend fun signChunk( + chunkBody: ByteArray, + prevSignature: ByteArray, + config: AwsSigningConfig, + ): AwsSigningResult { + val logger = telemetryProvider?.loggerProvider?.getOrCreateLogger("DefaultAwsSigner") + ?: coroutineContext.logger() + + val signatureCalculator = config.algorithm.signatureCalculator + + val stringToSign = signatureCalculator.chunkStringToSign(chunkBody, prevSignature, config) + logger.trace { "Chunk string to sign:\n$stringToSign" } + + val signingKey = signatureCalculator.signingKey(config) + + val signature = signatureCalculator.calculate(signingKey, stringToSign) + logger.debug { "Calculated chunk signature: $signature" } + + return AwsSigningResult(Unit, signature.encodeToByteArray()) + } + + override suspend fun signChunkTrailer( + trailingHeaders: Headers, + prevSignature: ByteArray, + config: AwsSigningConfig, + ): AwsSigningResult { + val logger = telemetryProvider?.loggerProvider?.getOrCreateLogger("DefaultAwsSigner") + ?: coroutineContext.logger() + + val signatureCalculator = config.algorithm.signatureCalculator + + // FIXME - can we share canonicalization code more than we are..., also this reduce is inefficient. + // canonicalize the headers + val trailingHeadersBytes = trailingHeaders.entries().sortedBy { e -> e.key.lowercase() } + .map { e -> + buildString { + append(e.key.lowercase()) + append(":") + append(e.value.joinToString(",") { v -> v.trim() }) + append("\n") + }.encodeToByteArray() + }.reduce { acc, bytes -> acc + bytes } + + val stringToSign = signatureCalculator.chunkTrailerStringToSign(trailingHeadersBytes, prevSignature, config) + logger.trace { "Chunk trailer string to sign:\n$stringToSign" } + + val signingKey = signatureCalculator.signingKey(config) + + val signature = signatureCalculator.calculate(signingKey, stringToSign) + logger.debug { "Calculated chunk signature: $signature" } + + return AwsSigningResult(Unit, signature.encodeToByteArray()) + } +} diff --git a/runtime/auth/aws-signing-default/native/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSignerNative.kt b/runtime/auth/aws-signing-default/native/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSignerNative.kt new file mode 100644 index 0000000000..a3804e8061 --- /dev/null +++ b/runtime/auth/aws-signing-default/native/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSignerNative.kt @@ -0,0 +1,11 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +package aws.smithy.kotlin.runtime.auth.awssigning + +import aws.smithy.kotlin.runtime.auth.awssigning.crt.CrtAwsSigner + +/** The default implementation of [AwsSigner] */ +public actual val DefaultAwsSigner: AwsSigner + get() = CrtAwsSigner \ No newline at end of file diff --git a/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/BasicSigningTestBase.kt b/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/BasicSigningTestBase.kt index 6427919615..a99663e17b 100644 --- a/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/BasicSigningTestBase.kt +++ b/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/BasicSigningTestBase.kt @@ -84,8 +84,6 @@ public abstract class BasicSigningTestBase : HasSigner { assertEquals(expectedSig, result.signature.decodeToString()) } - @IgnoreNative // ecdsaSecp256r1 not implemented on Native. Can we make the signer implementation expect/actual and - // use CRT signer on Native? @Test public open fun testSignRequestSigV4Asymmetric(): TestResult = runTest { // sanity test diff --git a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/hashing/EcdsaNative.kt b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/hashing/EcdsaNative.kt index a2bca1c4e6..112b60df14 100644 --- a/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/hashing/EcdsaNative.kt +++ b/runtime/runtime-core/native/src/aws/smithy/kotlin/runtime/hashing/EcdsaNative.kt @@ -4,10 +4,7 @@ */ package aws.smithy.kotlin.runtime.hashing -// FIXME Implement using aws-c-cal: https://github.com/awslabs/aws-c-cal/blob/main/include/aws/cal/ecc.h -// Will need to be implemented and exposed in aws-crt-kotlin. Or maybe we can _only_ offer the CRT signer on Native? -// Will require updating DefaultAwsSigner to be expect/actual and set to CrtSigner on Native. /** * ECDSA on the SECP256R1 curve. */ -public actual fun ecdsaSecp256r1(key: ByteArray, message: ByteArray): ByteArray = TODO("Not yet implemented") +public actual fun ecdsaSecp256r1(key: ByteArray, message: ByteArray): ByteArray = error("This function should not be invoked on Native, which uses the CrtAwsSigner.") From 8d73a86d4a8ab4f5f3c7c85c00611a7438bcced9 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Wed, 19 Mar 2025 12:28:52 -0400 Subject: [PATCH 16/30] ktlint --- .../aws/smithy/kotlin/runtime/auth/awssigning/RequestMutator.kt | 2 +- .../kotlin/runtime/auth/awssigning/DefaultAwsSignerNative.kt | 2 +- .../runtime/auth/awssigning/tests/BasicSigningTestBase.kt | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/RequestMutator.kt b/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/RequestMutator.kt index e0286249ca..9eafd6accd 100644 --- a/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/RequestMutator.kt +++ b/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/RequestMutator.kt @@ -73,4 +73,4 @@ internal val AwsSigningConfig.credentialScope: String * Formats the value for a credential header/parameter */ internal fun credentialValue(config: AwsSigningConfig): String = - "${config.credentials.accessKeyId}/${config.credentialScope}" \ No newline at end of file + "${config.credentials.accessKeyId}/${config.credentialScope}" diff --git a/runtime/auth/aws-signing-default/native/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSignerNative.kt b/runtime/auth/aws-signing-default/native/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSignerNative.kt index a3804e8061..e05ba1a5c3 100644 --- a/runtime/auth/aws-signing-default/native/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSignerNative.kt +++ b/runtime/auth/aws-signing-default/native/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSignerNative.kt @@ -8,4 +8,4 @@ import aws.smithy.kotlin.runtime.auth.awssigning.crt.CrtAwsSigner /** The default implementation of [AwsSigner] */ public actual val DefaultAwsSigner: AwsSigner - get() = CrtAwsSigner \ No newline at end of file + get() = CrtAwsSigner diff --git a/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/BasicSigningTestBase.kt b/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/BasicSigningTestBase.kt index a99663e17b..2a517fc090 100644 --- a/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/BasicSigningTestBase.kt +++ b/runtime/auth/aws-signing-tests/common/src/aws/smithy/kotlin/runtime/auth/awssigning/tests/BasicSigningTestBase.kt @@ -4,7 +4,6 @@ */ package aws.smithy.kotlin.runtime.auth.awssigning.tests -import aws.smithy.kotlin.runtime.IgnoreNative import aws.smithy.kotlin.runtime.auth.awscredentials.Credentials import aws.smithy.kotlin.runtime.auth.awssigning.* import aws.smithy.kotlin.runtime.http.HttpBody From ed5da6b5b6520691438863a42d0bd89c652d83f7 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Wed, 19 Mar 2025 12:30:57 -0400 Subject: [PATCH 17/30] Unignore passing test --- .../aws/smithy/kotlin/runtime/http/auth/AwsHttpSignerTestBase.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/runtime/auth/http-auth-aws/common/test/aws/smithy/kotlin/runtime/http/auth/AwsHttpSignerTestBase.kt b/runtime/auth/http-auth-aws/common/test/aws/smithy/kotlin/runtime/http/auth/AwsHttpSignerTestBase.kt index 8f1e9eed40..e284989694 100644 --- a/runtime/auth/http-auth-aws/common/test/aws/smithy/kotlin/runtime/http/auth/AwsHttpSignerTestBase.kt +++ b/runtime/auth/http-auth-aws/common/test/aws/smithy/kotlin/runtime/http/auth/AwsHttpSignerTestBase.kt @@ -134,7 +134,6 @@ public abstract class AwsHttpSignerTestBase( assertEquals(expectedSig, signed.headers["Authorization"]) } - @IgnoreNative // FIXME Native signed request has additional `transfer-encoding` header @Test public fun testSignReplayableStreamingRequest(): TestResult = runTest { val op = buildOperation(streaming = true) From 5ad9d5ec680f889d212c4fbdb66285cad0487978 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Thu, 20 Mar 2025 10:42:20 -0400 Subject: [PATCH 18/30] Update FIXME message --- .../kotlin/runtime/http/auth/AwsHttpSignerTestBase.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/runtime/auth/http-auth-aws/common/test/aws/smithy/kotlin/runtime/http/auth/AwsHttpSignerTestBase.kt b/runtime/auth/http-auth-aws/common/test/aws/smithy/kotlin/runtime/http/auth/AwsHttpSignerTestBase.kt index e284989694..6797ed74fb 100644 --- a/runtime/auth/http-auth-aws/common/test/aws/smithy/kotlin/runtime/http/auth/AwsHttpSignerTestBase.kt +++ b/runtime/auth/http-auth-aws/common/test/aws/smithy/kotlin/runtime/http/auth/AwsHttpSignerTestBase.kt @@ -147,7 +147,7 @@ public abstract class AwsHttpSignerTestBase( assertEquals(expectedSig, signed.headers["Authorization"]) } - @IgnoreNative // FIXME Native signed request has additional `transfer-encoding` header + @IgnoreNative // FIXME Our JVM implementation does not sign `transfer-encoding`, but CRT does, causing a signature mismatch. Upgrade to latest version of aws-c-auth to get the fix. @Test public fun testSignAwsChunkedStreamNonReplayable(): TestResult = runTest { val op = buildOperation(streaming = true, replayable = false, requestBody = "a".repeat(AWS_CHUNKED_THRESHOLD + 1)) @@ -161,7 +161,7 @@ public abstract class AwsHttpSignerTestBase( assertEquals(expectedSig, signed.headers["Authorization"]) } - @IgnoreNative // FIXME Native signed request has additional `transfer-encoding` header + @IgnoreNative // FIXME Our JVM implementation does not sign `transfer-encoding`, but CRT does, causing a signature mismatch. Upgrade to latest version of aws-c-auth to get the fix. @Test public fun testSignAwsChunkedStreamReplayable(): TestResult = runTest { val op = buildOperation(streaming = true, replayable = true, requestBody = "a".repeat(AWS_CHUNKED_THRESHOLD + 1)) @@ -175,7 +175,7 @@ public abstract class AwsHttpSignerTestBase( assertEquals(expectedSig, signed.headers["Authorization"]) } - @IgnoreNative // FIXME Native signed request has additional `transfer-encoding` header + @IgnoreNative // FIXME Our JVM implementation does not sign `transfer-encoding`, but CRT does, causing a signature mismatch. Upgrade to latest version of aws-c-auth to get the fix. @Test public fun testSignOneShotStream(): TestResult = runTest { val op = buildOperation(streaming = true, replayable = false) From cf45c86c918b6fc37084975f8b01a900e910e651 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Fri, 21 Mar 2025 11:35:09 -0400 Subject: [PATCH 19/30] CI From 6b1756b636341856f2e2ee9a5f83ee0c1f1ab89b Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Fri, 21 Mar 2025 15:07:58 -0400 Subject: [PATCH 20/30] CI From eeb84633c9f4bbb3259bb7102206ebf98fcad066 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Mon, 24 Mar 2025 10:58:04 -0400 Subject: [PATCH 21/30] CI From c5905cdc8ca25e1f8244f2c566269c1a9be60a6a Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Mon, 24 Mar 2025 11:10:32 -0400 Subject: [PATCH 22/30] Use setup-build action in artifact-size-metrics to pull in aws-crt-kotlin as an includeBuild --- .github/workflows/artifact-size-metrics.yml | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/.github/workflows/artifact-size-metrics.yml b/.github/workflows/artifact-size-metrics.yml index a9d3c7b6e9..67f734e46e 100644 --- a/.github/workflows/artifact-size-metrics.yml +++ b/.github/workflows/artifact-size-metrics.yml @@ -45,23 +45,27 @@ jobs: steps: - name: Checkout Sources uses: actions/checkout@v4 - - name: Configure JDK - uses: actions/setup-java@v3 with: - distribution: 'corretto' - java-version: 17 - cache: 'gradle' + path: 'smithy-kotlin' + + - name: Setup build + uses: ./smithy-kotlin/.github/actions/setup-build + - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ secrets.CI_AWS_ROLE_ARN }} aws-region: us-west-2 + - name: Configure Gradle uses: awslabs/aws-kotlin-repo-tools/.github/actions/configure-gradle@main + - name: Generate Artifact Size Metrics run: ./gradlew -Paws.kotlin.native=false artifactSizeMetrics + - name: Analyze Artifact Size Metrics run: ./gradlew analyzeArtifactSizeMetrics + - name: Show Results uses: actions/github-script@v7 with: From 11dac4e4f0d2c01d749409877ddf9fc2ecf71542 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Mon, 24 Mar 2025 11:14:16 -0400 Subject: [PATCH 23/30] Try to fix path --- .github/workflows/artifact-size-metrics.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/artifact-size-metrics.yml b/.github/workflows/artifact-size-metrics.yml index 67f734e46e..fb0be57b67 100644 --- a/.github/workflows/artifact-size-metrics.yml +++ b/.github/workflows/artifact-size-metrics.yml @@ -45,11 +45,9 @@ jobs: steps: - name: Checkout Sources uses: actions/checkout@v4 - with: - path: 'smithy-kotlin' - name: Setup build - uses: ./smithy-kotlin/.github/actions/setup-build + uses: .github/actions/setup-build - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v4 From 2857ecd8deccbd0c2b99357d10c992af2f075cb1 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Mon, 24 Mar 2025 12:42:35 -0400 Subject: [PATCH 24/30] =?UTF-8?q?CI=20glitch:=20size-check=20Expected=20?= =?UTF-8?q?=E2=80=94=20Waiting=20for=20status=20to=20be=20reported?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From 3580da48eade03c5029e915d354770650b42a171 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Mon, 24 Mar 2025 12:58:05 -0400 Subject: [PATCH 25/30] Temporarily remove `size-check` --- .github/workflows/artifact-size-metrics.yml | 87 +-------------------- 1 file changed, 1 insertion(+), 86 deletions(-) diff --git a/.github/workflows/artifact-size-metrics.yml b/.github/workflows/artifact-size-metrics.yml index fb0be57b67..713c84de38 100644 --- a/.github/workflows/artifact-size-metrics.yml +++ b/.github/workflows/artifact-size-metrics.yml @@ -38,89 +38,4 @@ jobs: - name: Save Artifact Size Metrics run: ./gradlew saveArtifactSizeMetrics -Prelease=${{ github.event.release.tag_name }} - name: Put Artifact Size Metrics in CloudWatch - run: ./gradlew putArtifactSizeMetricsInCloudWatch -Prelease=${{ github.event.release.tag_name }} - size-check: - if: github.event_name == 'pull_request' - runs-on: ubuntu-latest - steps: - - name: Checkout Sources - uses: actions/checkout@v4 - - - name: Setup build - uses: .github/actions/setup-build - - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 - with: - role-to-assume: ${{ secrets.CI_AWS_ROLE_ARN }} - aws-region: us-west-2 - - - name: Configure Gradle - uses: awslabs/aws-kotlin-repo-tools/.github/actions/configure-gradle@main - - - name: Generate Artifact Size Metrics - run: ./gradlew -Paws.kotlin.native=false artifactSizeMetrics - - - name: Analyze Artifact Size Metrics - run: ./gradlew analyzeArtifactSizeMetrics - - - name: Show Results - uses: actions/github-script@v7 - with: - script: | - const getComments = - `query { - repository(owner:"${context.repo.owner}", name:"${context.repo.repo}"){ - pullRequest(number: ${context.issue.number}) { - id - comments(last:100) { - nodes { - id - body - author { - login - } - isMinimized - } - } - } - } - }` - - const response = await github.graphql(getComments) - const comments = response.repository.pullRequest.comments.nodes - - const mutations = comments - .filter(comment => comment.author.login == 'github-actions' && !comment.isMinimized && comment.body.startsWith('Affected Artifacts')) - .map(comment => - github.graphql( - `mutation { - minimizeComment(input:{subjectId:"${comment.id}", classifier:OUTDATED}){ - clientMutationId - } - }` - ) - ) - await Promise.all(mutations) - - const fs = require('node:fs') - const comment = fs.readFileSync('build/reports/metrics/artifact-analysis.md', 'utf8') - - const writeComment = - `mutation { - addComment(input:{body:"""${comment}""", subjectId:"${response.repository.pullRequest.id}"}){ - clientMutationId - } - }` - - await github.graphql(writeComment) - - - name: Evaluate - if: ${{ !contains(github.event.pull_request.labels.*.name, 'acknowledge-artifact-size-increase') }} - run: | - cd build/reports/metrics - cat has-significant-change.txt | grep false || { - echo An artifact increased in size by more than allowed or a new artifact was created. - echo If this is expected please add the 'acknowledge-artifact-size-increase' label to this pull request. - exit 1 - } + run: ./gradlew putArtifactSizeMetricsInCloudWatch -Prelease=${{ github.event.release.tag_name }} \ No newline at end of file From d4bb8e45752996de0f495b54e69b54cb52ad3873 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Mon, 24 Mar 2025 12:58:32 -0400 Subject: [PATCH 26/30] Revert "Temporarily remove `size-check`" This reverts commit 3580da48eade03c5029e915d354770650b42a171. --- .github/workflows/artifact-size-metrics.yml | 87 ++++++++++++++++++++- 1 file changed, 86 insertions(+), 1 deletion(-) diff --git a/.github/workflows/artifact-size-metrics.yml b/.github/workflows/artifact-size-metrics.yml index 713c84de38..fb0be57b67 100644 --- a/.github/workflows/artifact-size-metrics.yml +++ b/.github/workflows/artifact-size-metrics.yml @@ -38,4 +38,89 @@ jobs: - name: Save Artifact Size Metrics run: ./gradlew saveArtifactSizeMetrics -Prelease=${{ github.event.release.tag_name }} - name: Put Artifact Size Metrics in CloudWatch - run: ./gradlew putArtifactSizeMetricsInCloudWatch -Prelease=${{ github.event.release.tag_name }} \ No newline at end of file + run: ./gradlew putArtifactSizeMetricsInCloudWatch -Prelease=${{ github.event.release.tag_name }} + size-check: + if: github.event_name == 'pull_request' + runs-on: ubuntu-latest + steps: + - name: Checkout Sources + uses: actions/checkout@v4 + + - name: Setup build + uses: .github/actions/setup-build + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ secrets.CI_AWS_ROLE_ARN }} + aws-region: us-west-2 + + - name: Configure Gradle + uses: awslabs/aws-kotlin-repo-tools/.github/actions/configure-gradle@main + + - name: Generate Artifact Size Metrics + run: ./gradlew -Paws.kotlin.native=false artifactSizeMetrics + + - name: Analyze Artifact Size Metrics + run: ./gradlew analyzeArtifactSizeMetrics + + - name: Show Results + uses: actions/github-script@v7 + with: + script: | + const getComments = + `query { + repository(owner:"${context.repo.owner}", name:"${context.repo.repo}"){ + pullRequest(number: ${context.issue.number}) { + id + comments(last:100) { + nodes { + id + body + author { + login + } + isMinimized + } + } + } + } + }` + + const response = await github.graphql(getComments) + const comments = response.repository.pullRequest.comments.nodes + + const mutations = comments + .filter(comment => comment.author.login == 'github-actions' && !comment.isMinimized && comment.body.startsWith('Affected Artifacts')) + .map(comment => + github.graphql( + `mutation { + minimizeComment(input:{subjectId:"${comment.id}", classifier:OUTDATED}){ + clientMutationId + } + }` + ) + ) + await Promise.all(mutations) + + const fs = require('node:fs') + const comment = fs.readFileSync('build/reports/metrics/artifact-analysis.md', 'utf8') + + const writeComment = + `mutation { + addComment(input:{body:"""${comment}""", subjectId:"${response.repository.pullRequest.id}"}){ + clientMutationId + } + }` + + await github.graphql(writeComment) + + - name: Evaluate + if: ${{ !contains(github.event.pull_request.labels.*.name, 'acknowledge-artifact-size-increase') }} + run: | + cd build/reports/metrics + cat has-significant-change.txt | grep false || { + echo An artifact increased in size by more than allowed or a new artifact was created. + echo If this is expected please add the 'acknowledge-artifact-size-increase' label to this pull request. + exit 1 + } From 56d6f7162c7af88d0d7d57b22a6b2cd89ba2694d Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Tue, 25 Mar 2025 11:56:58 -0400 Subject: [PATCH 27/30] Add a FIXME comment for `ex` / `ex.cause` --- .../smithy/kotlin/runtime/http/operation/HttpInterceptorTest.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/HttpInterceptorTest.kt b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/HttpInterceptorTest.kt index 4e75b8b59e..5d36840bcf 100644 --- a/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/HttpInterceptorTest.kt +++ b/runtime/protocol/http-client/common/test/aws/smithy/kotlin/runtime/http/operation/HttpInterceptorTest.kt @@ -259,6 +259,8 @@ class HttpInterceptorTest { op.roundTrip(client, Unit) } + // FIXME Investigate why the exception `ex` and its cause are duplicated on JVM. + // On JVM, `ex.cause` has the suppressed exceptions. On Native, `ex` has the suppressed exceptions and it has no cause. val cause = assertNotNull(ex.cause ?: ex) assertEquals(1, cause.suppressedExceptions.size) assertIs(cause.suppressedExceptions.last()) From 4ea1a06ee832821bb1be31e8972fd01c5f7e0606 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Tue, 25 Mar 2025 11:57:06 -0400 Subject: [PATCH 28/30] Address nit / `run { ... }` --- .../aws/smithy/kotlin/runtime/auth/awssigning/RequestMutator.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/RequestMutator.kt b/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/RequestMutator.kt index 9eafd6accd..ee67e7833b 100644 --- a/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/RequestMutator.kt +++ b/runtime/auth/aws-signing-default/common/src/aws/smithy/kotlin/runtime/auth/awssigning/RequestMutator.kt @@ -61,7 +61,7 @@ internal class DefaultRequestMutator : RequestMutator { * Formats a credential scope consisting of a signing date, region (SigV4 only), service, and a signature type */ internal val AwsSigningConfig.credentialScope: String - get() = run { + get() { val signingDate = signingDate.format(TimestampFormat.ISO_8601_CONDENSED_DATE) return when (algorithm) { AwsSigningAlgorithm.SIGV4 -> "$signingDate/$region/$service/aws4_request" From d17bf67fb29c83a9b820d288e4072449ef08af01 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Tue, 25 Mar 2025 11:57:24 -0400 Subject: [PATCH 29/30] Remove getter for `DefaultAwsSigner` values --- .../kotlin/runtime/auth/awssigning/DefaultAwsSignerJVM.kt | 3 +-- .../kotlin/runtime/auth/awssigning/DefaultAwsSignerNative.kt | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/runtime/auth/aws-signing-default/jvm/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSignerJVM.kt b/runtime/auth/aws-signing-default/jvm/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSignerJVM.kt index b2642717cf..ea1f4723d6 100644 --- a/runtime/auth/aws-signing-default/jvm/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSignerJVM.kt +++ b/runtime/auth/aws-signing-default/jvm/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSignerJVM.kt @@ -12,8 +12,7 @@ import aws.smithy.kotlin.runtime.telemetry.logging.logger import kotlin.coroutines.coroutineContext /** The default implementation of [AwsSigner] */ -public actual val DefaultAwsSigner: AwsSigner - get() = DefaultAwsSignerImpl() +public actual val DefaultAwsSigner: AwsSigner = DefaultAwsSignerImpl() /** Creates a customized instance of [AwsSigner] */ @Suppress("ktlint:standard:function-naming") diff --git a/runtime/auth/aws-signing-default/native/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSignerNative.kt b/runtime/auth/aws-signing-default/native/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSignerNative.kt index e05ba1a5c3..0b9335ec1d 100644 --- a/runtime/auth/aws-signing-default/native/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSignerNative.kt +++ b/runtime/auth/aws-signing-default/native/src/aws/smithy/kotlin/runtime/auth/awssigning/DefaultAwsSignerNative.kt @@ -7,5 +7,4 @@ package aws.smithy.kotlin.runtime.auth.awssigning import aws.smithy.kotlin.runtime.auth.awssigning.crt.CrtAwsSigner /** The default implementation of [AwsSigner] */ -public actual val DefaultAwsSigner: AwsSigner - get() = CrtAwsSigner +public actual val DefaultAwsSigner: AwsSigner = CrtAwsSigner From 5621fe0908978840f63d65526520081f2ec68b1c Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Tue, 25 Mar 2025 12:35:21 -0400 Subject: [PATCH 30/30] Add an explanation for CRT.initRuntime --- .../runtime/http/engine/crt/SdkStreamResponseHandlerTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/SdkStreamResponseHandlerTest.kt b/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/SdkStreamResponseHandlerTest.kt index 21843ef546..6c09f0dd02 100644 --- a/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/SdkStreamResponseHandlerTest.kt +++ b/runtime/protocol/http-client-engines/http-client-engine-crt/jvmAndNative/test/aws/smithy/kotlin/runtime/http/engine/crt/SdkStreamResponseHandlerTest.kt @@ -155,7 +155,7 @@ class SdkStreamResponseHandlerTest { @Test fun testStreamError() = runTest { - CRT.initRuntime() + CRT.initRuntime() // CRT needs to be initialized for human-readable error codes val handler = SdkStreamResponseHandler(mockConn, coroutineContext) val stream = MockHttpStream(200) val data = "foo bar"