Skip to content

Commit

Permalink
Add Clone impl to PresignedRequest
Browse files Browse the repository at this point in the history
  • Loading branch information
rcoh committed Oct 20, 2023
1 parent 66a3acf commit 8188899
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 11 deletions.
54 changes: 44 additions & 10 deletions aws/rust-runtime/aws-inlineable/src/presigning.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use aws_smithy_runtime_api::box_error::BoxError;
use aws_smithy_runtime_api::client::orchestrator::HttpRequest;
use aws_smithy_types::body::SdkBody;
use std::fmt;
use std::time::{Duration, SystemTime};

Expand Down Expand Up @@ -173,34 +174,67 @@ impl PresigningConfigBuilder {
/// - [`PresignedRequest::to_http_02x_request<B>`][Self::to_http_02x_request] returns an [`http::Request<B>`](https://docs.rs/http/0.2.6/http/request/struct.Request.html)
/// - [`PresignedRequest::into`](#impl-From<PresignedRequest>) returns an [`http::request::Builder`](https://docs.rs/http/0.2.6/http/request/struct.Builder.html)
#[non_exhaustive]
pub struct PresignedRequest(HttpRequest);
pub struct PresignedRequest {
http_request: HttpRequest,
}

impl Clone for PresignedRequest {
fn clone(&self) -> Self {
Self {
http_request: match self.http_request.try_clone() {
Some(body) => body,
None => {
unreachable!(
"during construction, we replaced the body with `SdkBody::empty()`"
)
}
},
}
}
}

impl PresignedRequest {
#[allow(dead_code)]
pub(crate) fn new(inner: HttpRequest) -> Self {
Self(inner)
pub(crate) fn new(inner: HttpRequest) -> Result<Self, BoxError> {
// throw out the body so we're sure it's cloneable
let http_request = inner.map(|_body| SdkBody::empty());
// this should never fail, a presigned request should always be convertible, but better to
// protect against this potential panic
let _ = http_request
.try_clone()
.expect("must be cloneable, body is empty")
.into_http02x()?;
Ok(Self { http_request })
}

/// Returns the HTTP request method.
pub fn method(&self) -> &str {
self.0.method()
self.http_request.method()
}

/// Returns the HTTP request URI.
pub fn uri(&self) -> &str {
self.0.uri()
self.http_request.uri()
}

/// Returns any HTTP headers that need to go along with the request, except for `Host`,
/// which should be sent based on the endpoint in the URI by the HTTP client rather than
/// added directly.
pub fn headers(&self) -> impl Iterator<Item = (&str, &str)> {
self.0.headers().iter()
self.http_request.headers().iter()
}

/// Given a body, produce an `http::Request` from this `PresignedRequest`
pub fn make_http_02x_request<B>(&self, body: B) -> http::Request<B> {
self.clone().into_http_02x_request(body)
}

/// Given a body, convert this `PresignedRequest` into an `http::Request`
pub fn to_http_02x_request<B>(self, body: B) -> Result<http::Request<B>, BoxError> {
Ok(self.0.into_http02x()?.map(|_req| body))
/// Converts this `PresignedRequest` directly into an `http` request.
pub fn into_http_02x_request<B>(self, body: B) -> http::Request<B> {
self.http_request
.into_http02x()
.expect("constructor validated convertibility")
.map(|_req| body)
}
}

Expand All @@ -209,7 +243,7 @@ impl fmt::Debug for PresignedRequest {
f.debug_struct("PresignedRequest")
.field("method", &self.method())
.field("uri", &self.uri())
.field("headers", self.0.headers())
.field("headers", self.http_request.headers())
.finish()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ class AwsPresignedFluentBuilderMethod(
})
})?;
let request = context.take_request().expect("request set before transmit");
Ok(#{PresignedRequest}::new(request))
Ok(#{PresignedRequest}::new(request)?)
""",
*codegenScope,
"Operation" to codegenContext.symbolProvider.toSymbol(section.operationShape),
Expand Down

0 comments on commit 8188899

Please sign in to comment.