Unverified Commit 9009d1b6 authored by Zelda Hessler's avatar Zelda Hessler Committed by GitHub
Browse files

Add support for converting PresignedRequest to http 1.x request (#3696)

## Checklist
<!--- If a checkbox below is not applicable, then please DELETE it
rather than leaving it unchecked -->
- [ ] I have updated `CHANGELOG.next.toml` if I made changes to the
smithy-rs codegen or runtime crates
- [ ] I have updated `CHANGELOG.next.toml` if I made changes to the AWS
SDK, generated SDK code, or SDK runtime crates

----

_By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice._
parent d7593493
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -28,3 +28,12 @@ message = "Add documentation on the default configuration to `from_env`, `load_f
references = ["aws-sdk-rust#1162"]
meta = { "breaking" = false, "tada" = false, "bug" = false }
author = "ysaito1001"

[[aws-sdk-rust]]
message = """
Pre-signed requests may now be converted to Http v1.x requests. This requires enabling the `http-1x` feature for the SDK in question.
Then, call `PresignedRequest::make_http_1x_request` or `PresignedRequest::into_http_1x_request`.
"""
references = ["smithy-rs#3696"]
meta = { "breaking" = false, "tada" = true, "bug" = false }
author = "Velfi"
+5 −0
Original line number Diff line number Diff line
@@ -11,6 +11,9 @@ license = "Apache-2.0"
publish = false
repository = "https://github.com/smithy-lang/smithy-rs"

[features]
http_1x = ["dep:http-1x", "dep:http-body-1x", "aws-smithy-runtime-api/http-1x"]

[dependencies]
# Used by lru, and this forces it to be a later version that avoids
# https://github.com/tkaitchuck/aHash/issues/200
@@ -30,6 +33,8 @@ fastrand = "2.0.0"
hex = "0.4.3"
http = "0.2.9"
http-body = "0.4.5"
http-1x = { package = "http", version = "1", optional = true }
http-body-1x = { package = "http-body", version = "1", optional = true }
hmac = "0.12"
lru = "0.12.2"
ring = "0.17.5"
+15 −0
Original line number Diff line number Diff line
@@ -236,6 +236,21 @@ impl PresignedRequest {
            .expect("constructor validated convertibility")
            .map(|_req| body)
    }

    #[cfg(feature = "http-1x")]
    /// Given a body, produce an `http_1x::Request` from this `PresignedRequest`
    pub fn make_http_1x_request<B>(&self, body: B) -> http_1x::Request<B> {
        self.clone().into_http_1x_request(body)
    }

    #[cfg(feature = "http-1x")]
    /// Converts this `PresignedRequest` directly into an `http_1x` request.
    pub fn into_http_1x_request<B>(self, body: B) -> http_1x::Request<B> {
        self.http_request
            .try_into_http1x()
            .expect("constructor validated convertibility")
            .map(|_req| body)
    }
}

impl fmt::Debug for PresignedRequest {
+25 −14
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import software.amazon.smithy.rust.codegen.client.smithy.generators.client.Inter
import software.amazon.smithy.rust.codegen.client.smithy.generators.client.fluentBuilderType
import software.amazon.smithy.rust.codegen.client.smithy.generators.protocol.RequestSerializerGenerator
import software.amazon.smithy.rust.codegen.core.rustlang.CargoDependency
import software.amazon.smithy.rust.codegen.core.rustlang.Feature
import software.amazon.smithy.rust.codegen.core.rustlang.RustWriter
import software.amazon.smithy.rust.codegen.core.rustlang.Writable
import software.amazon.smithy.rust.codegen.core.rustlang.docs
@@ -36,6 +37,7 @@ import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.core.rustlang.writable
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType.Companion.preludeScope
import software.amazon.smithy.rust.codegen.core.smithy.RustCrate
import software.amazon.smithy.rust.codegen.core.smithy.contextName
import software.amazon.smithy.rust.codegen.core.smithy.customize.AdHocCustomization
import software.amazon.smithy.rust.codegen.core.smithy.customize.adhocCustomization
@@ -43,7 +45,6 @@ import software.amazon.smithy.rust.codegen.core.util.cloneOperation
import software.amazon.smithy.rust.codegen.core.util.expectTrait
import software.amazon.smithy.rust.codegen.core.util.thenSingletonListOf
import software.amazon.smithy.rustsdk.traits.PresignableTrait
import kotlin.streams.toList

private val presigningTypes: Array<Pair<String, Any>> =
    arrayOf(
@@ -101,12 +102,6 @@ class AwsPresigningDecorator internal constructor(
    override val name: String = "AwsPresigning"
    override val order: Byte = ORDER

    private val codegenScope =
        arrayOf(
            *presigningTypes,
            *preludeScope,
        )

    /**
     * Adds presignable trait to known presignable operations and creates synthetic presignable shapes for codegen
     */
@@ -160,13 +155,29 @@ class AwsPresigningDecorator internal constructor(
                        self.execute(move |sender, conf|sender.presign(conf, presigning_config)).await
                    }
                    """,
                    *codegenScope,
                    "CustomizablePresigned" to CustomizablePresigned,
                    *preludeScope,
                    *presigningTypes,
                    "CustomizablePresigned" to customizablePresigned,
                )
            }
        }

    private val CustomizablePresigned =
    override fun extras(
        codegenContext: ClientCodegenContext,
        rustCrate: RustCrate,
    ) {
        if (anyPresignedShapes(codegenContext)) {
            rustCrate.mergeFeature(
                Feature(
                    "http-1x",
                    default = false,
                    listOf("dep:http-1x", "dep:http-body-1x", "aws-smithy-runtime-api/http-1x"),
                ),
            )
        }
    }

    private val customizablePresigned =
        RuntimeType.forInlineFun("CustomizablePresigned", InternalTraitsModule) {
            rustTemplate(
                """
@@ -175,7 +186,8 @@ class AwsPresigningDecorator internal constructor(
                }

                """,
                *codegenScope,
                *preludeScope,
                *presigningTypes,
            )
        }
}
@@ -186,8 +198,8 @@ class AwsPresignedFluentBuilderMethod(
    private val runtimeConfig = codegenContext.runtimeConfig
    private val codegenScope =
        arrayOf(
            *presigningTypes,
            *preludeScope,
            *presigningTypes,
            "Error" to AwsRuntimeType.presigning().resolve("config::Error"),
            "SdkError" to RuntimeType.sdkError(runtimeConfig),
        )
@@ -246,8 +258,7 @@ class AwsPresignedFluentBuilderMethod(
                    }
                }
                """,
                *preludeScope,
                *presigningTypes,
                *codegenScope,
                "OperationError" to section.operationErrorType,
                "SdkError" to RuntimeType.sdkError(runtimeConfig),
            )
+7 −1
Original line number Diff line number Diff line
@@ -33,7 +33,13 @@ fun RuntimeConfig.awsRoot(): RuntimeCrateLocation {

object AwsRuntimeType {
    fun presigning(): RuntimeType =
        RuntimeType.forInlineDependency(InlineAwsDependency.forRustFile("presigning", visibility = Visibility.PUBLIC))
        RuntimeType.forInlineDependency(
            InlineAwsDependency.forRustFile(
                "presigning", visibility = Visibility.PUBLIC,
                CargoDependency.Http1x,
                CargoDependency.HttpBody1x,
            ),
        )

    fun presigningInterceptor(runtimeConfig: RuntimeConfig): RuntimeType =
        RuntimeType.forInlineDependency(
Loading