Unverified Commit dabbfaa8 authored by Russell Cohen's avatar Russell Cohen Committed by GitHub
Browse files

Add the ability to disable interceptors via the config bag (#2757)

This replaces the existing custom interceptor disable logic with shared
logic to allow generally disabling any public interceptors from Runtime
plugins. The previous behavior was very brittle because it relied
heavily on runtime plugin execution order.

## Motivation and Context
- simplify presigning behavior
- generalize logic to disable interceptors

## Description
Create `disable_interceptor` struct, which, when inserted into the
configuration bag can disable an interceptor via the `Interceptors`
execution interface.

## Testing
- ` (cd aws/sdk/build/aws-sdk/sdk/s3 && cargo test --test presigning)`

## 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 ccbc9a1a
Loading
Loading
Loading
Loading
+9 −8
Original line number Diff line number Diff line
@@ -8,13 +8,14 @@
use crate::presigning::PresigningConfig;
use crate::serialization_settings::HeaderSerializationSettings;
use aws_runtime::auth::sigv4::{HttpSignatureType, SigV4OperationSigningConfig};
use aws_runtime::invocation_id::DisableInvocationIdInterceptor;
use aws_runtime::request_info::DisableRequestInfoInterceptor;
use aws_runtime::user_agent::DisableUserAgentInterceptor;
use aws_runtime::invocation_id::InvocationIdInterceptor;
use aws_runtime::request_info::RequestInfoInterceptor;
use aws_runtime::user_agent::UserAgentInterceptor;
use aws_smithy_async::time::{SharedTimeSource, StaticTimeSource};
use aws_smithy_runtime_api::client::interceptors::{
    BeforeSerializationInterceptorContextMut, BeforeTransmitInterceptorContextMut, BoxError,
    Interceptor, InterceptorRegistrar, SharedInterceptor,
    disable_interceptor, BeforeSerializationInterceptorContextMut,
    BeforeTransmitInterceptorContextMut, BoxError, Interceptor, InterceptorRegistrar,
    SharedInterceptor,
};
use aws_smithy_runtime_api::client::orchestrator::ConfigBagAccessors;
use aws_smithy_runtime_api::client::runtime_plugin::RuntimePlugin;
@@ -92,9 +93,9 @@ impl RuntimePlugin for SigV4PresigningRuntimePlugin {
        interceptors: &mut InterceptorRegistrar,
    ) -> Result<(), BoxError> {
        // Disable some SDK interceptors that shouldn't run for presigning
        cfg.put(DisableInvocationIdInterceptor::new("presigning"));
        cfg.put(DisableRequestInfoInterceptor::new("presigning"));
        cfg.put(DisableUserAgentInterceptor::new("presigning"));
        cfg.put(disable_interceptor::<InvocationIdInterceptor>("presigning"));
        cfg.put(disable_interceptor::<RequestInfoInterceptor>("presigning"));
        cfg.put(disable_interceptor::<UserAgentInterceptor>("presigning"));

        // Register the presigning interceptor
        interceptors.register(self.interceptor.clone());
+0 −17
Original line number Diff line number Diff line
@@ -18,23 +18,6 @@ pub use test_util::{NoInvocationIdGenerator, PredefinedInvocationIdGenerator};
#[allow(clippy::declare_interior_mutable_const)] // we will never mutate this
const AMZ_SDK_INVOCATION_ID: HeaderName = HeaderName::from_static("amz-sdk-invocation-id");

/// Config marker that disables the invocation ID interceptor.
#[doc(hidden)]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct DisableInvocationIdInterceptor {
    why: &'static str,
}

impl DisableInvocationIdInterceptor {
    /// Creates a new `DisableInvocationIdInterceptor`.
    ///
    /// Takes a human readable string for the `Debug` impl to state why it is being disabled.
    /// This is to assist with debugging issues with requests.
    pub fn new(why: &'static str) -> Self {
        Self { why }
    }
}

/// A generator for returning new invocation IDs on demand.
pub trait InvocationIdGenerator: Debug + Send + Sync {
    /// Call this function to receive a new [`InvocationId`] or an error explaining why one couldn't
+0 −17
Original line number Diff line number Diff line
@@ -20,23 +20,6 @@ use std::time::{Duration, SystemTime};
#[allow(clippy::declare_interior_mutable_const)] // we will never mutate this
const AMZ_SDK_REQUEST: HeaderName = HeaderName::from_static("amz-sdk-request");

/// Config marker that disables the invocation ID interceptor.
#[doc(hidden)]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct DisableRequestInfoInterceptor {
    why: &'static str,
}

impl DisableRequestInfoInterceptor {
    /// Creates a new `DisableRequestInfoInterceptor`.
    ///
    /// Takes a human readable string for the `Debug` impl to state why it is being disabled.
    /// This is to assist with debugging issues with requests.
    pub fn new(why: &'static str) -> Self {
        Self { why }
    }
}

/// Generates and attaches a request header that communicates request-related metadata.
/// Examples include:
///
+0 −17
Original line number Diff line number Diff line
@@ -49,23 +49,6 @@ impl From<InvalidHeaderValue> for UserAgentInterceptorError {
    }
}

/// Config marker that disables the user agent interceptor.
#[doc(hidden)]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct DisableUserAgentInterceptor {
    why: &'static str,
}

impl DisableUserAgentInterceptor {
    /// Creates a new `DisableUserAgentInterceptor`.
    ///
    /// Takes a human readable string for the `Debug` impl to state why it is being disabled.
    /// This is to assist with debugging issues with requests.
    pub fn new(why: &'static str) -> Self {
        Self { why }
    }
}

/// Generates and attaches the AWS SDK's user agent to a HTTP request
#[non_exhaustive]
#[derive(Debug, Default)]
+2 −9
Original line number Diff line number Diff line
@@ -10,7 +10,6 @@ import software.amazon.smithy.rust.codegen.client.smithy.customize.ClientCodegen
import software.amazon.smithy.rust.codegen.client.smithy.generators.ServiceRuntimePluginCustomization
import software.amazon.smithy.rust.codegen.client.smithy.generators.ServiceRuntimePluginSection
import software.amazon.smithy.rust.codegen.core.rustlang.Writable
import software.amazon.smithy.rust.codegen.core.rustlang.rustBlockTemplate
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.util.letIf
@@ -38,15 +37,9 @@ private class InvocationIdRuntimePluginCustomization(

    override fun section(section: ServiceRuntimePluginSection): Writable = writable {
        if (section is ServiceRuntimePluginSection.AdditionalConfig) {
            val invocationId = AwsRuntimeType.awsRuntime(codegenContext.runtimeConfig).resolve("invocation_id")
            rustBlockTemplate(
                "if cfg.get::<#{DisableInvocationIdInterceptor}>().is_none()",
                "DisableInvocationIdInterceptor" to invocationId.resolve("DisableInvocationIdInterceptor"),
            ) {
            section.registerInterceptor(codegenContext.runtimeConfig, this) {
                rustTemplate("#{InvocationIdInterceptor}::new()", *codegenScope)
            }
        }
    }
}
}
Loading