Skip to main content

aws_sdk_s3/operation/
put_object.rs

1// Code generated by software.amazon.smithy.rust.codegen.smithy-rs. DO NOT EDIT.
2/// Orchestration and serialization glue logic for `PutObject`.
3#[derive(::std::clone::Clone, ::std::default::Default, ::std::fmt::Debug)]
4#[non_exhaustive]
5pub struct PutObject;
6impl PutObject {
7    /// Creates a new `PutObject`
8    pub fn new() -> Self {
9        Self
10    }
11    pub(crate) async fn orchestrate(
12        runtime_plugins: &::aws_smithy_runtime_api::client::runtime_plugin::RuntimePlugins,
13        input: crate::operation::put_object::PutObjectInput,
14    ) -> ::std::result::Result<
15        crate::operation::put_object::PutObjectOutput,
16        ::aws_smithy_runtime_api::client::result::SdkError<
17            crate::operation::put_object::PutObjectError,
18            ::aws_smithy_runtime_api::client::orchestrator::HttpResponse,
19        >,
20    > {
21        let map_err = |err: ::aws_smithy_runtime_api::client::result::SdkError<
22            ::aws_smithy_runtime_api::client::interceptors::context::Error,
23            ::aws_smithy_runtime_api::client::orchestrator::HttpResponse,
24        >| {
25            err.map_service_error(|err| {
26                err.downcast::<crate::operation::put_object::PutObjectError>()
27                    .expect("correct error type")
28            })
29        };
30        let context = Self::orchestrate_with_stop_point(runtime_plugins, input, ::aws_smithy_runtime::client::orchestrator::StopPoint::None)
31            .await
32            .map_err(map_err)?;
33        let output = context.finalize().map_err(map_err)?;
34        ::std::result::Result::Ok(
35            output
36                .downcast::<crate::operation::put_object::PutObjectOutput>()
37                .expect("correct output type"),
38        )
39    }
40
41    pub(crate) async fn orchestrate_with_stop_point(
42        runtime_plugins: &::aws_smithy_runtime_api::client::runtime_plugin::RuntimePlugins,
43        input: crate::operation::put_object::PutObjectInput,
44        stop_point: ::aws_smithy_runtime::client::orchestrator::StopPoint,
45    ) -> ::std::result::Result<
46        ::aws_smithy_runtime_api::client::interceptors::context::InterceptorContext,
47        ::aws_smithy_runtime_api::client::result::SdkError<
48            ::aws_smithy_runtime_api::client::interceptors::context::Error,
49            ::aws_smithy_runtime_api::client::orchestrator::HttpResponse,
50        >,
51    > {
52        let input = ::aws_smithy_runtime_api::client::interceptors::context::Input::erase(input);
53        use ::tracing::Instrument;
54        ::aws_smithy_runtime::client::orchestrator::invoke_with_stop_point("S3", "PutObject", input, runtime_plugins, stop_point)
55            // Create a parent span for the entire operation. Includes a random, internal-only,
56            // seven-digit ID for the operation orchestration so that it can be correlated in the logs.
57            .instrument(::tracing::debug_span!(
58                "S3.PutObject",
59                "rpc.service" = "S3",
60                "rpc.method" = "PutObject",
61                "sdk_invocation_id" = ::fastrand::u32(1_000_000..10_000_000),
62                "rpc.system" = "aws-api",
63            ))
64            .await
65    }
66
67    pub(crate) fn operation_runtime_plugins(
68        client_runtime_plugins: ::aws_smithy_runtime_api::client::runtime_plugin::RuntimePlugins,
69        client_config: &crate::config::Config,
70        config_override: ::std::option::Option<crate::config::Builder>,
71    ) -> ::aws_smithy_runtime_api::client::runtime_plugin::RuntimePlugins {
72        let mut runtime_plugins = client_runtime_plugins.with_operation_plugin(Self::new());
73
74        if let ::std::option::Option::Some(config_override) = config_override {
75            for plugin in config_override.runtime_plugins.iter().cloned() {
76                runtime_plugins = runtime_plugins.with_operation_plugin(plugin);
77            }
78            runtime_plugins = runtime_plugins.with_operation_plugin(crate::config::ConfigOverrideRuntimePlugin::new(
79                config_override,
80                client_config.config.clone(),
81                &client_config.runtime_components,
82            ));
83        }
84        runtime_plugins
85    }
86}
87impl ::aws_smithy_runtime_api::client::runtime_plugin::RuntimePlugin for PutObject {
88    fn config(&self) -> ::std::option::Option<::aws_smithy_types::config_bag::FrozenLayer> {
89        let mut cfg = ::aws_smithy_types::config_bag::Layer::new("PutObject");
90
91        cfg.store_put(::aws_smithy_runtime_api::client::ser_de::SharedRequestSerializer::new(
92            PutObjectRequestSerializer,
93        ));
94        cfg.store_put(::aws_smithy_runtime_api::client::ser_de::SharedResponseDeserializer::new(
95            PutObjectResponseDeserializer,
96        ));
97
98        cfg.store_put(::aws_smithy_runtime_api::client::auth::AuthSchemeOptionResolverParams::new(
99            crate::config::auth::Params::builder()
100                .operation_name("PutObject")
101                .build()
102                .expect("required fields set"),
103        ));
104
105        cfg.store_put(::aws_smithy_runtime_api::client::orchestrator::SensitiveOutput);
106        cfg.store_put(::aws_smithy_runtime_api::client::orchestrator::Metadata::new("PutObject", "S3"));
107        let mut signing_options = ::aws_runtime::auth::SigningOptions::default();
108        signing_options.double_uri_encode = false;
109        signing_options.content_sha256_header = true;
110        signing_options.normalize_uri_path = false;
111        signing_options.payload_override = None;
112
113        cfg.store_put(::aws_runtime::auth::SigV4OperationSigningConfig {
114            signing_options,
115            ..::std::default::Default::default()
116        });
117
118        ::std::option::Option::Some(cfg.freeze())
119    }
120
121    fn runtime_components(
122        &self,
123        _: &::aws_smithy_runtime_api::client::runtime_components::RuntimeComponentsBuilder,
124    ) -> ::std::borrow::Cow<'_, ::aws_smithy_runtime_api::client::runtime_components::RuntimeComponentsBuilder> {
125        #[allow(unused_mut)]
126        let mut rcb = ::aws_smithy_runtime_api::client::runtime_components::RuntimeComponentsBuilder::new("PutObject")
127            .with_interceptor(::aws_smithy_runtime_api::client::interceptors::SharedInterceptor::permanent(
128                PutObjectTelemetryInputCaptureInterceptor,
129            ))
130            .with_interceptor(::aws_smithy_runtime_api::client::interceptors::SharedInterceptor::permanent(
131                ::aws_smithy_runtime::client::stalled_stream_protection::StalledStreamProtectionInterceptor::default(),
132            ))
133            .with_interceptor(::aws_smithy_runtime_api::client::interceptors::SharedInterceptor::permanent(
134                PutObjectEndpointParamsInterceptor,
135            ))
136            .with_interceptor(::aws_smithy_runtime_api::client::interceptors::SharedInterceptor::permanent(
137                crate::http_request_checksum::RequestChecksumInterceptor::new(
138                    |input: &::aws_smithy_runtime_api::client::interceptors::context::Input| {
139                        let input: &crate::operation::put_object::PutObjectInput = input.downcast_ref().expect("correct type");
140                        let checksum_algorithm = input.checksum_algorithm();
141                        let checksum_algorithm = checksum_algorithm.map(|algorithm| algorithm.as_str());
142                        (checksum_algorithm.map(|s| s.to_string()), false)
143                    },
144                    |request: &mut ::aws_smithy_runtime_api::http::Request, cfg: &::aws_smithy_types::config_bag::ConfigBag| {
145                        // We check if the user has set any of the checksum values manually
146                        let mut user_set_checksum_value = false;
147                        let headers_to_check =
148                            request
149                                .headers()
150                                .iter()
151                                .filter_map(|(name, _val)| if name.starts_with("x-amz-checksum-") { Some(name) } else { None });
152                        for algo_header in headers_to_check {
153                            if request.headers().get(algo_header).is_some() {
154                                user_set_checksum_value = true;
155                            }
156                        }
157
158                        // We check if the user set the checksum algo manually
159                        let user_set_checksum_algo = request.headers().get("x-amz-sdk-checksum-algorithm").is_some();
160
161                        // This value is set by the user on the SdkConfig to indicate their preference
162                        let request_checksum_calculation = cfg
163                            .load::<::aws_smithy_types::checksum_config::RequestChecksumCalculation>()
164                            .unwrap_or(&::aws_smithy_types::checksum_config::RequestChecksumCalculation::WhenSupported);
165
166                        // From the httpChecksum trait
167                        let http_checksum_required = false;
168
169                        let is_presigned_req = cfg.load::<crate::presigning::PresigningMarker>().is_some();
170
171                        // If the request is presigned we do not set a default.
172                        // If the RequestChecksumCalculation is WhenSupported and the user has not set a checksum value or algo
173                        // we set the default. If it is WhenRequired and a checksum is required by the trait and the user has not
174                        // set a checksum value or algo we also set the default. In all other cases we do nothing.
175                        match (
176                            request_checksum_calculation,
177                            http_checksum_required,
178                            user_set_checksum_value,
179                            user_set_checksum_algo,
180                            is_presigned_req,
181                        ) {
182                            (_, _, _, _, true) => {}
183                            (::aws_smithy_types::checksum_config::RequestChecksumCalculation::WhenSupported, _, false, false, _)
184                            | (::aws_smithy_types::checksum_config::RequestChecksumCalculation::WhenRequired, true, false, false, _) => {
185                                request.headers_mut().insert("x-amz-sdk-checksum-algorithm", "CRC32");
186                            }
187                            _ => {}
188                        }
189
190                        // We return a bool indicating if the user did set the checksum value, if they did
191                        // we can short circuit and exit the interceptor early.
192                        Ok(user_set_checksum_value)
193                    },
194                ),
195            ))
196            .with_interceptor(::aws_smithy_runtime_api::client::interceptors::SharedInterceptor::permanent(
197                crate::aws_chunked::AwsChunkedContentEncodingInterceptor,
198            ))
199            .with_retry_classifier(::aws_smithy_runtime::client::retries::classifiers::TransientErrorClassifier::<
200                crate::operation::put_object::PutObjectError,
201            >::new())
202            .with_retry_classifier(::aws_smithy_runtime::client::retries::classifiers::ModeledAsRetryableClassifier::<
203                crate::operation::put_object::PutObjectError,
204            >::new())
205            .with_retry_classifier(
206                ::aws_runtime::retries::classifiers::AwsErrorCodeClassifier::<crate::operation::put_object::PutObjectError>::builder()
207                    .transient_errors({
208                        let mut transient_errors: Vec<&'static str> = ::aws_runtime::retries::classifiers::TRANSIENT_ERRORS.into();
209                        transient_errors.push("InternalError");
210                        ::std::borrow::Cow::Owned(transient_errors)
211                    })
212                    .build(),
213            )
214            .with_retry_classifier(::aws_runtime::service_clock_skew::ServiceClockSkewClassifier::<
215                crate::operation::put_object::PutObjectError,
216            >::new());
217
218        ::std::borrow::Cow::Owned(rcb)
219    }
220}
221
222#[derive(Debug)]
223struct PutObjectTelemetryInputCaptureInterceptor;
224
225#[::aws_smithy_runtime_api::client::interceptors::dyn_dispatch_hint]
226impl ::aws_smithy_runtime_api::client::interceptors::Intercept for PutObjectTelemetryInputCaptureInterceptor {
227    fn name(&self) -> &'static str {
228        "PutObjectTelemetryInputCaptureInterceptor"
229    }
230
231    fn read_before_execution(
232        &self,
233        context: &::aws_smithy_runtime_api::client::interceptors::context::BeforeSerializationInterceptorContextRef<
234            '_,
235            ::aws_smithy_runtime_api::client::interceptors::context::Input,
236            ::aws_smithy_runtime_api::client::interceptors::context::Output,
237            ::aws_smithy_runtime_api::client::interceptors::context::Error,
238        >,
239        cfg: &mut ::aws_smithy_types::config_bag::ConfigBag,
240    ) -> ::std::result::Result<(), ::aws_smithy_runtime_api::box_error::BoxError> {
241        // Nothing to do unless the customer opted in by naming members to record.
242        let ::std::option::Option::Some(requested) = cfg
243            .load::<::aws_smithy_types::telemetry::RequestedTelemetryAttributes>()
244            .filter(|r| !r.is_empty())
245        else {
246            return ::std::result::Result::Ok(());
247        };
248
249        let ::std::option::Option::Some(input) = context.input().downcast_ref::<PutObjectInput>() else {
250            // A mismatched input is not this interceptor's concern; skip quietly.
251            return ::std::result::Result::Ok(());
252        };
253
254        let mut captured = ::aws_smithy_types::telemetry::CapturedTelemetryAttributes::default();
255        if requested.should_capture("Bucket") {
256            if let ::std::option::Option::Some(value) = input.bucket.as_deref() {
257                captured.insert("Bucket", value);
258            }
259        }
260        if requested.should_capture("CacheControl") {
261            if let ::std::option::Option::Some(value) = input.cache_control.as_deref() {
262                captured.insert("CacheControl", value);
263            }
264        }
265        if requested.should_capture("ContentDisposition") {
266            if let ::std::option::Option::Some(value) = input.content_disposition.as_deref() {
267                captured.insert("ContentDisposition", value);
268            }
269        }
270        if requested.should_capture("ContentEncoding") {
271            if let ::std::option::Option::Some(value) = input.content_encoding.as_deref() {
272                captured.insert("ContentEncoding", value);
273            }
274        }
275        if requested.should_capture("ContentLanguage") {
276            if let ::std::option::Option::Some(value) = input.content_language.as_deref() {
277                captured.insert("ContentLanguage", value);
278            }
279        }
280        if requested.should_capture("ContentMD5") {
281            if let ::std::option::Option::Some(value) = input.content_md5.as_deref() {
282                captured.insert("ContentMD5", value);
283            }
284        }
285        if requested.should_capture("ContentType") {
286            if let ::std::option::Option::Some(value) = input.content_type.as_deref() {
287                captured.insert("ContentType", value);
288            }
289        }
290        if requested.should_capture("ChecksumCRC32") {
291            if let ::std::option::Option::Some(value) = input.checksum_crc32.as_deref() {
292                captured.insert("ChecksumCRC32", value);
293            }
294        }
295        if requested.should_capture("ChecksumCRC32C") {
296            if let ::std::option::Option::Some(value) = input.checksum_crc32_c.as_deref() {
297                captured.insert("ChecksumCRC32C", value);
298            }
299        }
300        if requested.should_capture("ChecksumCRC64NVME") {
301            if let ::std::option::Option::Some(value) = input.checksum_crc64_nvme.as_deref() {
302                captured.insert("ChecksumCRC64NVME", value);
303            }
304        }
305        if requested.should_capture("ChecksumSHA1") {
306            if let ::std::option::Option::Some(value) = input.checksum_sha1.as_deref() {
307                captured.insert("ChecksumSHA1", value);
308            }
309        }
310        if requested.should_capture("ChecksumSHA256") {
311            if let ::std::option::Option::Some(value) = input.checksum_sha256.as_deref() {
312                captured.insert("ChecksumSHA256", value);
313            }
314        }
315        if requested.should_capture("ChecksumSHA512") {
316            if let ::std::option::Option::Some(value) = input.checksum_sha512.as_deref() {
317                captured.insert("ChecksumSHA512", value);
318            }
319        }
320        if requested.should_capture("ChecksumMD5") {
321            if let ::std::option::Option::Some(value) = input.checksum_md5.as_deref() {
322                captured.insert("ChecksumMD5", value);
323            }
324        }
325        if requested.should_capture("ChecksumXXHASH64") {
326            if let ::std::option::Option::Some(value) = input.checksum_xxhash64.as_deref() {
327                captured.insert("ChecksumXXHASH64", value);
328            }
329        }
330        if requested.should_capture("ChecksumXXHASH3") {
331            if let ::std::option::Option::Some(value) = input.checksum_xxhash3.as_deref() {
332                captured.insert("ChecksumXXHASH3", value);
333            }
334        }
335        if requested.should_capture("ChecksumXXHASH128") {
336            if let ::std::option::Option::Some(value) = input.checksum_xxhash128.as_deref() {
337                captured.insert("ChecksumXXHASH128", value);
338            }
339        }
340        if requested.should_capture("IfMatch") {
341            if let ::std::option::Option::Some(value) = input.if_match.as_deref() {
342                captured.insert("IfMatch", value);
343            }
344        }
345        if requested.should_capture("IfNoneMatch") {
346            if let ::std::option::Option::Some(value) = input.if_none_match.as_deref() {
347                captured.insert("IfNoneMatch", value);
348            }
349        }
350        if requested.should_capture("GrantFullControl") {
351            if let ::std::option::Option::Some(value) = input.grant_full_control.as_deref() {
352                captured.insert("GrantFullControl", value);
353            }
354        }
355        if requested.should_capture("GrantRead") {
356            if let ::std::option::Option::Some(value) = input.grant_read.as_deref() {
357                captured.insert("GrantRead", value);
358            }
359        }
360        if requested.should_capture("GrantReadACP") {
361            if let ::std::option::Option::Some(value) = input.grant_read_acp.as_deref() {
362                captured.insert("GrantReadACP", value);
363            }
364        }
365        if requested.should_capture("GrantWriteACP") {
366            if let ::std::option::Option::Some(value) = input.grant_write_acp.as_deref() {
367                captured.insert("GrantWriteACP", value);
368            }
369        }
370        if requested.should_capture("Key") {
371            if let ::std::option::Option::Some(value) = input.key.as_deref() {
372                captured.insert("Key", value);
373            }
374        }
375        if requested.should_capture("WebsiteRedirectLocation") {
376            if let ::std::option::Option::Some(value) = input.website_redirect_location.as_deref() {
377                captured.insert("WebsiteRedirectLocation", value);
378            }
379        }
380        if requested.should_capture("SSECustomerAlgorithm") {
381            if let ::std::option::Option::Some(value) = input.sse_customer_algorithm.as_deref() {
382                captured.insert("SSECustomerAlgorithm", value);
383            }
384        }
385        if requested.should_capture("SSECustomerKeyMD5") {
386            if let ::std::option::Option::Some(value) = input.sse_customer_key_md5.as_deref() {
387                captured.insert("SSECustomerKeyMD5", value);
388            }
389        }
390        if requested.should_capture("Tagging") {
391            if let ::std::option::Option::Some(value) = input.tagging.as_deref() {
392                captured.insert("Tagging", value);
393            }
394        }
395        if requested.should_capture("ExpectedBucketOwner") {
396            if let ::std::option::Option::Some(value) = input.expected_bucket_owner.as_deref() {
397                captured.insert("ExpectedBucketOwner", value);
398            }
399        }
400
401        cfg.interceptor_state().store_put(captured);
402        ::std::result::Result::Ok(())
403    }
404}
405#[derive(Debug)]
406struct PutObjectResponseDeserializer;
407impl ::aws_smithy_runtime_api::client::ser_de::DeserializeResponse for PutObjectResponseDeserializer {
408    fn deserialize_nonstreaming_with_config(
409        &self,
410        response: &::aws_smithy_runtime_api::client::orchestrator::HttpResponse,
411        _cfg: &::aws_smithy_types::config_bag::ConfigBag,
412    ) -> ::aws_smithy_runtime_api::client::interceptors::context::OutputOrError {
413        let (success, status) = (response.status().is_success(), response.status().as_u16());
414        let headers = response.headers();
415        let body = response.body().bytes().expect("body loaded");
416        #[allow(unused_mut)]
417        let mut force_error = false;
418        ::tracing::debug!(extended_request_id = ?crate::s3_request_id::RequestIdExt::extended_request_id(response));
419        if matches!(crate::rest_xml_unwrapped_errors::body_is_error(body), Ok(true)) {
420            force_error = true;
421        }
422        ::tracing::debug!(request_id = ?::aws_types::request_id::RequestId::request_id(response));
423        let parse_result = if !success && status != 200 || force_error {
424            crate::protocol_serde::shape_put_object::de_put_object_http_error(status, headers, body)
425        } else {
426            crate::protocol_serde::shape_put_object::de_put_object_http_response(status, headers, body)
427        };
428        crate::protocol_serde::type_erase_result(parse_result)
429    }
430}
431#[derive(Debug)]
432struct PutObjectRequestSerializer;
433impl ::aws_smithy_runtime_api::client::ser_de::SerializeRequest for PutObjectRequestSerializer {
434    #[allow(unused_mut, clippy::let_and_return, clippy::needless_borrow, clippy::useless_conversion)]
435    fn serialize_input(
436        &self,
437        input: ::aws_smithy_runtime_api::client::interceptors::context::Input,
438        _cfg: &mut ::aws_smithy_types::config_bag::ConfigBag,
439    ) -> ::std::result::Result<::aws_smithy_runtime_api::client::orchestrator::HttpRequest, ::aws_smithy_runtime_api::box_error::BoxError> {
440        let input = input.downcast::<crate::operation::put_object::PutObjectInput>().expect("correct type");
441        let _header_serialization_settings = _cfg
442            .load::<crate::serialization_settings::HeaderSerializationSettings>()
443            .cloned()
444            .unwrap_or_default();
445        let mut request_builder = {
446            #[allow(clippy::uninlined_format_args)]
447            fn uri_base(
448                _input: &crate::operation::put_object::PutObjectInput,
449                output: &mut ::std::string::String,
450            ) -> ::std::result::Result<(), ::aws_smithy_types::error::operation::BuildError> {
451                use ::std::fmt::Write as _;
452                let input_1 = &_input.key;
453                let input_1 = input_1
454                    .as_ref()
455                    .ok_or_else(|| ::aws_smithy_types::error::operation::BuildError::missing_field("key", "cannot be empty or unset"))?;
456                let key = ::aws_smithy_http::label::fmt_string(input_1, ::aws_smithy_http::label::EncodingStrategy::Greedy);
457                if key.is_empty() {
458                    return ::std::result::Result::Err(::aws_smithy_types::error::operation::BuildError::missing_field(
459                        "key",
460                        "cannot be empty or unset",
461                    ));
462                }
463                ::std::write!(output, "/{Key}", Key = key).expect("formatting should succeed");
464                ::std::result::Result::Ok(())
465            }
466            fn uri_query(
467                _input: &crate::operation::put_object::PutObjectInput,
468                mut output: &mut ::std::string::String,
469            ) -> ::std::result::Result<(), ::aws_smithy_types::error::operation::BuildError> {
470                let mut query = ::aws_smithy_http::query::Writer::new(output);
471                query.push_kv("x-id", "PutObject");
472                ::std::result::Result::Ok(())
473            }
474            #[allow(clippy::unnecessary_wraps)]
475            fn update_http_builder(
476                input: &crate::operation::put_object::PutObjectInput,
477                builder: ::http_1x::request::Builder,
478            ) -> ::std::result::Result<::http_1x::request::Builder, ::aws_smithy_types::error::operation::BuildError> {
479                let mut uri = ::std::string::String::new();
480                uri_base(input, &mut uri)?;
481                uri_query(input, &mut uri)?;
482                let builder = crate::protocol_serde::shape_put_object::ser_put_object_headers(input, builder)?;
483                ::std::result::Result::Ok(builder.method("PUT").uri(uri))
484            }
485            let mut builder = update_http_builder(&input, ::http_1x::request::Builder::new())?;
486            builder = _header_serialization_settings.set_default_header(builder, ::http_1x::header::CONTENT_TYPE, "application/octet-stream");
487            builder
488        };
489        let body = crate::protocol_serde::shape_put_object_input::ser_body_http_payload(input.body)?.into_inner();
490        if let Some(content_length) = body.content_length() {
491            let content_length = content_length.to_string();
492            request_builder = _header_serialization_settings.set_default_header(request_builder, ::http_1x::header::CONTENT_LENGTH, &content_length);
493        }
494        ::std::result::Result::Ok(request_builder.body(body).expect("valid request").try_into().unwrap())
495    }
496}
497#[derive(Debug)]
498struct PutObjectEndpointParamsInterceptor;
499
500#[::aws_smithy_runtime_api::client::interceptors::dyn_dispatch_hint]
501impl ::aws_smithy_runtime_api::client::interceptors::Intercept for PutObjectEndpointParamsInterceptor {
502    fn name(&self) -> &'static str {
503        "PutObjectEndpointParamsInterceptor"
504    }
505
506    fn read_before_execution(
507        &self,
508        context: &::aws_smithy_runtime_api::client::interceptors::context::BeforeSerializationInterceptorContextRef<
509            '_,
510            ::aws_smithy_runtime_api::client::interceptors::context::Input,
511            ::aws_smithy_runtime_api::client::interceptors::context::Output,
512            ::aws_smithy_runtime_api::client::interceptors::context::Error,
513        >,
514        cfg: &mut ::aws_smithy_types::config_bag::ConfigBag,
515    ) -> ::std::result::Result<(), ::aws_smithy_runtime_api::box_error::BoxError> {
516        let _input = context
517            .input()
518            .downcast_ref::<PutObjectInput>()
519            .ok_or("failed to downcast to PutObjectInput")?;
520
521        let params = crate::config::endpoint::Params::builder()
522            .set_region(cfg.load::<::aws_types::region::Region>().map(|r| r.as_ref().to_owned()))
523            .set_use_fips(cfg.load::<::aws_types::endpoint_config::UseFips>().map(|ty| ty.0))
524            .set_use_dual_stack(cfg.load::<::aws_types::endpoint_config::UseDualStack>().map(|ty| ty.0))
525            .set_endpoint(cfg.load::<::aws_types::endpoint_config::EndpointUrl>().map(|ty| ty.0.clone()))
526            .set_force_path_style(cfg.load::<crate::config::ForcePathStyle>().map(|ty| ty.0))
527            .set_use_arn_region(cfg.load::<crate::config::UseArnRegion>().map(|ty| ty.0))
528            .set_disable_multi_region_access_points(cfg.load::<crate::config::DisableMultiRegionAccessPoints>().map(|ty| ty.0))
529            .set_accelerate(cfg.load::<crate::config::Accelerate>().map(|ty| ty.0))
530            .set_disable_s3_express_session_auth(cfg.load::<crate::config::DisableS3ExpressSessionAuth>().map(|ty| ty.0))
531            .set_bucket(Some(
532                _input
533                    .bucket
534                    .clone()
535                    .filter(|f| !AsRef::<str>::as_ref(f).trim().is_empty())
536                    .ok_or_else(|| ::aws_smithy_types::error::operation::BuildError::missing_field("bucket", "A required field was not set"))?,
537            ))
538            .set_key(Some(
539                _input
540                    .key
541                    .clone()
542                    .filter(|f| !AsRef::<str>::as_ref(f).trim().is_empty())
543                    .ok_or_else(|| ::aws_smithy_types::error::operation::BuildError::missing_field("key", "A required field was not set"))?,
544            ))
545            .build()
546            .map_err(|err| {
547                ::aws_smithy_runtime_api::client::interceptors::error::ContextAttachedError::new("endpoint params could not be built", err)
548            })?;
549        cfg.interceptor_state()
550            .store_put(::aws_smithy_runtime_api::client::endpoint::EndpointResolverParams::new(params));
551        ::std::result::Result::Ok(())
552    }
553}
554
555// The get_* functions below are generated from JMESPath expressions in the
556// operationContextParams trait. They target the operation's input shape.
557
558#[allow(unreachable_code, unused_variables)]
559#[cfg(test)]
560mod put_object_test {
561
562    /// This test validates that if a content-type is specified, that only one content-type header is sent
563    /// Test ID: DontSendDuplicateContentType
564    #[::tokio::test]
565    #[::tracing_test::traced_test]
566    async fn dont_send_duplicate_content_type_request() {
567        let (http_client, request_receiver) = ::aws_smithy_http_client::test_util::capture_request(None);
568        let config_builder = crate::config::Config::builder()
569            .with_test_defaults()
570            // TODO(https://github.com/smithy-lang/smithy-rs/issues/4177):
571            //  Until the incorrect separation is addressed, we need to rely on this workaround.
572            .allow_no_auth()
573            .endpoint_url("https://example.com");
574        let config_builder = config_builder.region(::aws_types::region::Region::new("us-east-1"));
575        let mut config_builder = config_builder;
576        config_builder.set_region(Some(crate::config::Region::new("us-east-1")));
577
578        let config = config_builder.http_client(http_client).build();
579        let client = crate::Client::from_conf(config);
580        let result = client
581            .put_object()
582            .set_bucket(::std::option::Option::Some("test-bucket".to_owned()))
583            .set_key(::std::option::Option::Some("test-key".to_owned()))
584            .set_content_type(::std::option::Option::Some("text/html".to_owned()))
585            .send()
586            .await;
587        let _ = dbg!(result);
588        let http_request = request_receiver.expect_request();
589        let expected_headers = [("content-type", "text/html")];
590        ::aws_smithy_protocol_test::assert_ok(::aws_smithy_protocol_test::validate_headers(http_request.headers(), expected_headers));
591        let uri: ::http_1x::Uri = http_request.uri().parse().expect("invalid URI sent");
592        ::pretty_assertions::assert_eq!(http_request.method(), "PUT", "method was incorrect");
593        ::pretty_assertions::assert_eq!(uri.path(), "/test-key", "path was incorrect");
594    }
595}
596
597/// Error type for the `PutObjectError` operation.
598#[non_exhaustive]
599#[derive(::std::fmt::Debug)]
600pub enum PutObjectError {
601    /// <p>The existing object was created with a different encryption type. Subsequent write requests must include the appropriate encryption parameters in the request or while creating the session.</p>
602    EncryptionTypeMismatch(crate::types::error::EncryptionTypeMismatch),
603    /// <p>A parameter or header in your request isn't valid. For details, see the description of this API operation.</p>
604    InvalidRequest(crate::types::error::InvalidRequest),
605    /// <p>The write offset value that you specified does not match the current object size.</p>
606    InvalidWriteOffset(crate::types::error::InvalidWriteOffset),
607    /// <p>You have attempted to add more parts than the maximum of 10000 that are allowed for this object. You can use the CopyObject operation to copy this object to another and then add more data to the newly copied object.</p>
608    TooManyParts(crate::types::error::TooManyParts),
609    /// An unexpected error occurred (e.g., invalid JSON returned by the service or an unknown error code).
610    #[deprecated(note = "Matching `Unhandled` directly is not forwards compatible. Instead, match using a \
611    variable wildcard pattern and check `.code()`:
612     \
613    &nbsp;&nbsp;&nbsp;`err if err.code() == Some(\"SpecificExceptionCode\") => { /* handle the error */ }`
614     \
615    See [`ProvideErrorMetadata`](#impl-ProvideErrorMetadata-for-PutObjectError) for what information is available for the error.")]
616    Unhandled(crate::error::sealed_unhandled::Unhandled),
617}
618impl PutObjectError {
619    /// Creates the `PutObjectError::Unhandled` variant from any error type.
620    pub fn unhandled(
621        err: impl ::std::convert::Into<::std::boxed::Box<dyn ::std::error::Error + ::std::marker::Send + ::std::marker::Sync + 'static>>,
622    ) -> Self {
623        Self::Unhandled(crate::error::sealed_unhandled::Unhandled {
624            source: err.into(),
625            meta: ::std::default::Default::default(),
626        })
627    }
628
629    /// Creates the `PutObjectError::Unhandled` variant from an [`ErrorMetadata`](::aws_smithy_types::error::ErrorMetadata).
630    pub fn generic(err: ::aws_smithy_types::error::ErrorMetadata) -> Self {
631        Self::Unhandled(crate::error::sealed_unhandled::Unhandled {
632            source: err.clone().into(),
633            meta: err,
634        })
635    }
636    ///
637    /// Returns error metadata, which includes the error code, message,
638    /// request ID, and potentially additional information.
639    ///
640    pub fn meta(&self) -> &::aws_smithy_types::error::ErrorMetadata {
641        match self {
642            Self::EncryptionTypeMismatch(e) => ::aws_smithy_types::error::metadata::ProvideErrorMetadata::meta(e),
643            Self::InvalidRequest(e) => ::aws_smithy_types::error::metadata::ProvideErrorMetadata::meta(e),
644            Self::InvalidWriteOffset(e) => ::aws_smithy_types::error::metadata::ProvideErrorMetadata::meta(e),
645            Self::TooManyParts(e) => ::aws_smithy_types::error::metadata::ProvideErrorMetadata::meta(e),
646            Self::Unhandled(e) => &e.meta,
647        }
648    }
649    /// Returns `true` if the error kind is `PutObjectError::EncryptionTypeMismatch`.
650    pub fn is_encryption_type_mismatch(&self) -> bool {
651        matches!(self, Self::EncryptionTypeMismatch(_))
652    }
653    /// Returns `true` if the error kind is `PutObjectError::InvalidRequest`.
654    pub fn is_invalid_request(&self) -> bool {
655        matches!(self, Self::InvalidRequest(_))
656    }
657    /// Returns `true` if the error kind is `PutObjectError::InvalidWriteOffset`.
658    pub fn is_invalid_write_offset(&self) -> bool {
659        matches!(self, Self::InvalidWriteOffset(_))
660    }
661    /// Returns `true` if the error kind is `PutObjectError::TooManyParts`.
662    pub fn is_too_many_parts(&self) -> bool {
663        matches!(self, Self::TooManyParts(_))
664    }
665}
666impl ::std::error::Error for PutObjectError {
667    fn source(&self) -> ::std::option::Option<&(dyn ::std::error::Error + 'static)> {
668        match self {
669            Self::EncryptionTypeMismatch(_inner) => ::std::option::Option::Some(_inner),
670            Self::InvalidRequest(_inner) => ::std::option::Option::Some(_inner),
671            Self::InvalidWriteOffset(_inner) => ::std::option::Option::Some(_inner),
672            Self::TooManyParts(_inner) => ::std::option::Option::Some(_inner),
673            Self::Unhandled(_inner) => ::std::option::Option::Some(&*_inner.source),
674        }
675    }
676}
677impl ::std::fmt::Display for PutObjectError {
678    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
679        match self {
680            Self::EncryptionTypeMismatch(_inner) => _inner.fmt(f),
681            Self::InvalidRequest(_inner) => _inner.fmt(f),
682            Self::InvalidWriteOffset(_inner) => _inner.fmt(f),
683            Self::TooManyParts(_inner) => _inner.fmt(f),
684            Self::Unhandled(_inner) => {
685                if let ::std::option::Option::Some(code) = ::aws_smithy_types::error::metadata::ProvideErrorMetadata::code(self) {
686                    write!(f, "unhandled error ({code})")
687                } else {
688                    f.write_str("unhandled error")
689                }
690            }
691        }
692    }
693}
694impl ::aws_smithy_types::retry::ProvideErrorKind for PutObjectError {
695    fn code(&self) -> ::std::option::Option<&str> {
696        ::aws_smithy_types::error::metadata::ProvideErrorMetadata::code(self)
697    }
698    fn retryable_error_kind(&self) -> ::std::option::Option<::aws_smithy_types::retry::ErrorKind> {
699        ::std::option::Option::None
700    }
701}
702impl ::aws_smithy_types::error::metadata::ProvideErrorMetadata for PutObjectError {
703    fn meta(&self) -> &::aws_smithy_types::error::ErrorMetadata {
704        match self {
705            Self::EncryptionTypeMismatch(_inner) => ::aws_smithy_types::error::metadata::ProvideErrorMetadata::meta(_inner),
706            Self::InvalidRequest(_inner) => ::aws_smithy_types::error::metadata::ProvideErrorMetadata::meta(_inner),
707            Self::InvalidWriteOffset(_inner) => ::aws_smithy_types::error::metadata::ProvideErrorMetadata::meta(_inner),
708            Self::TooManyParts(_inner) => ::aws_smithy_types::error::metadata::ProvideErrorMetadata::meta(_inner),
709            Self::Unhandled(_inner) => &_inner.meta,
710        }
711    }
712}
713impl ::aws_smithy_runtime_api::client::result::CreateUnhandledError for PutObjectError {
714    fn create_unhandled_error(
715        source: ::std::boxed::Box<dyn ::std::error::Error + ::std::marker::Send + ::std::marker::Sync + 'static>,
716        meta: ::std::option::Option<::aws_smithy_types::error::ErrorMetadata>,
717    ) -> Self {
718        Self::Unhandled(crate::error::sealed_unhandled::Unhandled {
719            source,
720            meta: meta.unwrap_or_default(),
721        })
722    }
723}
724impl crate::s3_request_id::RequestIdExt for crate::operation::put_object::PutObjectError {
725    fn extended_request_id(&self) -> Option<&str> {
726        self.meta().extended_request_id()
727    }
728}
729impl ::aws_types::request_id::RequestId for crate::operation::put_object::PutObjectError {
730    fn request_id(&self) -> Option<&str> {
731        self.meta().request_id()
732    }
733}
734
735pub use crate::operation::put_object::_put_object_input::PutObjectInput;
736
737pub use crate::operation::put_object::_put_object_output::PutObjectOutput;
738
739mod _put_object_input;
740
741mod _put_object_output;
742
743/// Builders
744pub mod builders;