aws_sdk_s3/
s3_expires_interceptor.rs

1// Code generated by software.amazon.smithy.rust.codegen.smithy-rs. DO NOT EDIT.
2/*
3 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7use aws_smithy_runtime_api::box_error::BoxError;
8use aws_smithy_runtime_api::client::interceptors::context::BeforeDeserializationInterceptorContextMut;
9use aws_smithy_runtime_api::client::interceptors::Intercept;
10use aws_smithy_runtime_api::client::runtime_components::RuntimeComponents;
11use aws_smithy_types::config_bag::ConfigBag;
12use aws_smithy_types::date_time::{DateTime, Format};
13
14/// An interceptor to implement custom parsing logic for S3's `Expires` header. This
15/// intercaptor copies the value of the `Expires` header to a (synthetically added)
16/// `ExpiresString` header. It also attempts to parse the header as an `HttpDate`, if
17/// that parsing fails the header is removed so the `Expires` field in the final output
18/// will be `None`.
19#[derive(Debug)]
20pub(crate) struct S3ExpiresInterceptor;
21const EXPIRES: &str = "Expires";
22const EXPIRES_STRING: &str = "ExpiresString";
23
24impl Intercept for S3ExpiresInterceptor {
25    fn name(&self) -> &'static str {
26        "S3ExpiresInterceptor"
27    }
28
29    fn modify_before_deserialization(
30        &self,
31        context: &mut BeforeDeserializationInterceptorContextMut<'_>,
32        _: &RuntimeComponents,
33        _: &mut ConfigBag,
34    ) -> Result<(), BoxError> {
35        let headers = context.response_mut().headers_mut();
36
37        if headers.contains_key(EXPIRES) {
38            let expires_header = headers.get(EXPIRES).unwrap().to_string();
39
40            // If the Expires header fails to parse to an HttpDate we remove the header so
41            // it is parsed to None. We use HttpDate since that is the SEP defined default
42            // if no other format is specified in the model.
43            if DateTime::from_str(&expires_header, Format::HttpDate).is_err() {
44                tracing::debug!(
45                    "Failed to parse the header `{EXPIRES}` = \"{expires_header}\" as an HttpDate. The raw string value can found in `{EXPIRES_STRING}`."
46                );
47                headers.remove(EXPIRES);
48            }
49
50            // Regardless of parsing success we copy the value of the Expires header to the
51            // ExpiresString header.
52            headers.insert(EXPIRES_STRING, expires_header);
53        }
54
55        Ok(())
56    }
57}