Skip to content

Commit

Permalink
Presigned URL checksums
Browse files Browse the repository at this point in the history
  • Loading branch information
0marperez committed Dec 13, 2024
1 parent b2e6f61 commit c63cf83
Show file tree
Hide file tree
Showing 10 changed files with 63 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ object RuntimeTypes {
val TimestampFormat = symbol("TimestampFormat", "time")
val ClientException = symbol("ClientException")
val SdkDsl = symbol("SdkDsl")
val IllegalStateException = symbol("IllegalStateException")

object BusinessMetrics : RuntimeTypePackage(KotlinDependency.CORE, "businessmetrics") {
val AccountIdBasedEndpointAccountId = symbol("AccountIdBasedEndpointAccountId")
Expand Down Expand Up @@ -170,6 +171,8 @@ object RuntimeTypes {

object Hashing : RuntimeTypePackage(KotlinDependency.CORE, "hashing") {
val Sha256 = symbol("Sha256")
val toHashFunctionOrThrow = symbol("toHashFunctionOrThrow")
val isSupportedForFlexibleChecksums = symbol("isSupportedForFlexibleChecksums")
}

object IO : RuntimeTypePackage(KotlinDependency.CORE, "io") {
Expand All @@ -180,6 +183,7 @@ object RuntimeTypes {
}

object Text : RuntimeTypePackage(KotlinDependency.CORE, "text") {
val lowercase = symbol("lowercase")
object Encoding : RuntimeTypePackage(KotlinDependency.CORE, "text.encoding") {
val decodeBase64 = symbol("decodeBase64")
val decodeBase64Bytes = symbol("decodeBase64Bytes")
Expand All @@ -199,6 +203,7 @@ object RuntimeTypes {
val toNumber = symbol("toNumber")
val type = symbol("type")
val PlatformProvider = symbol("PlatformProvider")
val runBlocking = symbol("runBlocking")
}

object Net : RuntimeTypePackage(KotlinDependency.CORE, "net") {
Expand Down Expand Up @@ -397,6 +402,7 @@ object RuntimeTypes {
val TelemetryContextElement = symbol("TelemetryContextElement", "context")
val TraceSpan = symbol("TraceSpan", "trace")
val withSpan = symbol("withSpan", "trace")
val warn = symbol("warn", "logging")
}
object TelemetryDefaults : RuntimeTypePackage(KotlinDependency.TELEMETRY_DEFAULTS) {
val Global = symbol("Global")
Expand Down
3 changes: 3 additions & 0 deletions runtime/auth/aws-signing-common/api/aws-signing-common.api
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ public final class aws/smithy/kotlin/runtime/auth/awssigning/AwsSigningConfig {
public static final field Companion Laws/smithy/kotlin/runtime/auth/awssigning/AwsSigningConfig$Companion;
public fun <init> (Laws/smithy/kotlin/runtime/auth/awssigning/AwsSigningConfig$Builder;)V
public final fun getAlgorithm ()Laws/smithy/kotlin/runtime/auth/awssigning/AwsSigningAlgorithm;
public final fun getChecksum ()Lkotlin/Pair;
public final fun getCredentials ()Laws/smithy/kotlin/runtime/auth/awscredentials/Credentials;
public final fun getExpiresAfter-FghU774 ()Lkotlin/time/Duration;
public final fun getHashSpecification ()Laws/smithy/kotlin/runtime/auth/awssigning/HashSpecification;
Expand All @@ -91,6 +92,7 @@ public final class aws/smithy/kotlin/runtime/auth/awssigning/AwsSigningConfig$Bu
public fun <init> ()V
public final fun build ()Laws/smithy/kotlin/runtime/auth/awssigning/AwsSigningConfig;
public final fun getAlgorithm ()Laws/smithy/kotlin/runtime/auth/awssigning/AwsSigningAlgorithm;
public final fun getChecksum ()Lkotlin/Pair;
public final fun getCredentials ()Laws/smithy/kotlin/runtime/auth/awscredentials/Credentials;
public final fun getExpiresAfter-FghU774 ()Lkotlin/time/Duration;
public final fun getHashSpecification ()Laws/smithy/kotlin/runtime/auth/awssigning/HashSpecification;
Expand All @@ -105,6 +107,7 @@ public final class aws/smithy/kotlin/runtime/auth/awssigning/AwsSigningConfig$Bu
public final fun getSigningDate ()Laws/smithy/kotlin/runtime/time/Instant;
public final fun getUseDoubleUriEncode ()Z
public final fun setAlgorithm (Laws/smithy/kotlin/runtime/auth/awssigning/AwsSigningAlgorithm;)V
public final fun setChecksum (Lkotlin/Pair;)V
public final fun setCredentials (Laws/smithy/kotlin/runtime/auth/awscredentials/Credentials;)V
public final fun setExpiresAfter-BwNAW2A (Lkotlin/time/Duration;)V
public final fun setHashSpecification (Laws/smithy/kotlin/runtime/auth/awssigning/HashSpecification;)V
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,11 @@ public class AwsSigningConfig(builder: Builder) {
*/
public val logRequest: Boolean = builder.logRequest

/**
* Determines the checksum to add to the canonical request query parameters before signing.
*/
public val checksum: Pair<String, String>? = builder.checksum

public fun toBuilder(): Builder = Builder().also {
it.region = region
it.service = service
Expand All @@ -187,6 +192,7 @@ public class AwsSigningConfig(builder: Builder) {
it.credentials = credentials
it.expiresAfter = expiresAfter
it.logRequest = logRequest
it.checksum = checksum
}

public class Builder {
Expand All @@ -204,6 +210,7 @@ public class AwsSigningConfig(builder: Builder) {
public var credentials: Credentials? = null
public var expiresAfter: Duration? = null
public var logRequest: Boolean = false
public var checksum: Pair<String, String>? = null

public fun build(): AwsSigningConfig = AwsSigningConfig(this)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,11 @@ internal class DefaultCanonicalizer(private val sha256Supplier: HashSupplier = :
param("X-Amz-Expires", config.expiresAfter?.inWholeSeconds?.toString(), signViaQueryParams)
param("X-Amz-Security-Token", sessionToken, !config.omitSessionToken) // Add pre-sig if omitSessionToken=false

// Add checksum as query param
if (config.signatureType == AwsSignatureType.HTTP_REQUEST_VIA_QUERY_PARAMS && config.checksum != null) {
param(config.checksum!!.first, config.checksum!!.second)
}

val headers = builder
.headers
.entries()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public class FlexibleChecksumsRequestInterceptor<I>(

private val checksumAlgorithm = requestChecksumAlgorithm
?.toHashFunctionOrThrow()
?.takeIf { it.isSupported }
?.takeIf { it.isSupportedForFlexibleChecksums }
?: (Crc32().takeIf { requestChecksumRequired || requestChecksumCalculation == HttpChecksumConfigOption.WHEN_SUPPORTED })

// TODO: Remove in next minor version bump
Expand Down Expand Up @@ -169,14 +169,6 @@ public class FlexibleChecksumsRequestInterceptor<I>(
contentLength != null &&
(isOneShot || contentLength!! > 65536 * 16)

/**
* @return if the [HashFunction] is supported by flexible checksums
*/
private val HashFunction.isSupported: Boolean get() = when (this) {
is Crc32, is Crc32c, is Sha256, is Sha1 -> true
else -> false
}

/**
* Removes all checksum headers except [headerName]
* @param headerName the checksum header name to keep
Expand Down
10 changes: 10 additions & 0 deletions runtime/runtime-core/api/runtime-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ public final class aws/smithy/kotlin/runtime/ErrorMetadata$Companion {
public abstract interface annotation class aws/smithy/kotlin/runtime/ExperimentalApi : java/lang/annotation/Annotation {
}

public final class aws/smithy/kotlin/runtime/IllegalStateException : java/lang/IllegalStateException {
public fun <init> (Ljava/lang/String;)V
}

public abstract interface annotation class aws/smithy/kotlin/runtime/InternalApi : java/lang/annotation/Annotation {
}

Expand Down Expand Up @@ -695,6 +699,7 @@ public final class aws/smithy/kotlin/runtime/hashing/HashFunction$DefaultImpls {
public final class aws/smithy/kotlin/runtime/hashing/HashFunctionKt {
public static final fun hash ([BLaws/smithy/kotlin/runtime/hashing/HashFunction;)[B
public static final fun hash ([BLkotlin/jvm/functions/Function0;)[B
public static final fun isSupportedForFlexibleChecksums (Laws/smithy/kotlin/runtime/hashing/HashFunction;)Z
public static final fun toHashFunction (Ljava/lang/String;)Laws/smithy/kotlin/runtime/hashing/HashFunction;
public static final fun toHashFunctionOrThrow (Ljava/lang/String;)Laws/smithy/kotlin/runtime/hashing/HashFunction;
}
Expand Down Expand Up @@ -2083,6 +2088,7 @@ public final class aws/smithy/kotlin/runtime/text/Scanner {
public final class aws/smithy/kotlin/runtime/text/TextKt {
public static final fun ensurePrefix (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
public static final fun ensureSuffix (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
public static final fun lowercase (Ljava/lang/String;)Ljava/lang/String;
}

public final class aws/smithy/kotlin/runtime/text/Utf8Kt {
Expand Down Expand Up @@ -2261,6 +2267,10 @@ public abstract interface class aws/smithy/kotlin/runtime/util/CanDeepCopy {
public abstract fun deepCopy ()Ljava/lang/Object;
}

public final class aws/smithy/kotlin/runtime/util/ConcurrencyKt {
public static final fun runBlocking (Lkotlin/jvm/functions/Function1;)V
}

public final class aws/smithy/kotlin/runtime/util/CoroutineUtilsKt {
public static final fun derivedName (Lkotlin/coroutines/CoroutineContext;Ljava/lang/String;)Lkotlinx/coroutines/CoroutineName;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package aws.smithy.kotlin.runtime
import aws.smithy.kotlin.runtime.collections.AttributeKey
import aws.smithy.kotlin.runtime.collections.MutableAttributes
import aws.smithy.kotlin.runtime.collections.mutableAttributes
import kotlin.IllegalStateException

/**
* Additional metadata about an error
Expand Down Expand Up @@ -174,3 +175,9 @@ public open class ServiceException : SdkBaseException {

override val sdkErrorMetadata: ServiceErrorMetadata = ServiceErrorMetadata()
}

/**
* Runtime accessible version of the [IllegalStateException]
*/
@InternalApi
public class IllegalStateException(message: String) : IllegalStateException(message)
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,12 @@ public fun String.toHashFunction(): HashFunction? = when (this.lowercase()) {
@InternalApi
public fun String.toHashFunctionOrThrow(): HashFunction =
toHashFunction() ?: throw ClientException("Checksum algorithm '$this' is not supported")

/**
* @return if the [HashFunction] is supported by flexible checksums
*/
@InternalApi
public val HashFunction.isSupportedForFlexibleChecksums: Boolean get() = when (this) {
is Crc32, is Crc32c, is Sha256, is Sha1 -> true
else -> false
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@
package aws.smithy.kotlin.runtime.text

import aws.smithy.kotlin.runtime.InternalApi
import java.util.*

@InternalApi
public fun String.ensurePrefix(prefix: String): String = if (startsWith(prefix)) this else prefix + this

@InternalApi
public fun String.ensureSuffix(suffix: String): String = if (endsWith(suffix)) this else plus(suffix)

@InternalApi
public fun String.lowercase(): String = this.lowercase(Locale.getDefault())
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package aws.smithy.kotlin.runtime.util

import aws.smithy.kotlin.runtime.InternalApi
import kotlinx.coroutines.runBlocking

@InternalApi
public fun runBlocking(block: suspend () -> Unit) {
runBlocking {
block()
}
}

0 comments on commit c63cf83

Please sign in to comment.