Skip to content

Commit 378f996

Browse files
authored
Revert "Introduce generic fluent client generator to non-sdk codegen (#463)"
This reverts commit 7774d68.
1 parent 7774d68 commit 378f996

File tree

30 files changed

+399
-2006
lines changed

30 files changed

+399
-2006
lines changed

aws/rust-runtime/aws-endpoint/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ pub fn set_endpoint_resolver(config: &mut PropertyBag, provider: AwsEndpointReso
161161
/// 3. Apply the endpoint to the URI in the request
162162
/// 4. Set the `SigningRegion` and `SigningService` in the property bag to drive downstream
163163
/// signing middleware.
164-
#[derive(Clone, Debug)]
164+
#[derive(Clone)]
165165
pub struct AwsEndpointStage;
166166

167167
#[derive(Debug)]

aws/rust-runtime/aws-http/src/user_agent.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ impl Display for ExecEnvMetadata {
216216
}
217217

218218
#[non_exhaustive]
219-
#[derive(Default, Clone, Debug)]
219+
#[derive(Default, Clone)]
220220
pub struct UserAgentStage;
221221

222222
impl UserAgentStage {

aws/rust-runtime/aws-hyper/Cargo.toml

+2-3
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ license = "Apache-2.0"
1010
[features]
1111
test-util = ["protocol-test-helpers"]
1212
default = ["test-util"]
13-
native-tls = ["hyper-tls", "smithy-client/native-tls"]
14-
rustls = ["hyper-rustls", "smithy-client/rustls"]
13+
native-tls = ["hyper-tls"]
14+
rustls = ["hyper-rustls"]
1515

1616
[dependencies]
1717
hyper = { version = "0.14.2", features = ["client", "http1", "http2", "tcp", "runtime"] }
@@ -28,7 +28,6 @@ http-body = "0.4.0"
2828
smithy-http = { path = "../../../rust-runtime/smithy-http" }
2929
smithy-types = { path = "../../../rust-runtime/smithy-types" }
3030
smithy-http-tower = { path = "../../../rust-runtime/smithy-http-tower" }
31-
smithy-client = { path = "../../../rust-runtime/smithy-client" }
3231
fastrand = "1.4.0"
3332
tokio = { version = "1", features = ["time"] }
3433

+203
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0.
4+
*/
5+
6+
use crate::BoxError;
7+
use http::Request;
8+
use hyper::client::ResponseFuture;
9+
use hyper::Response;
10+
use smithy_http::body::SdkBody;
11+
use std::future::Future;
12+
use std::pin::Pin;
13+
use std::task::{Context, Poll};
14+
use tower::Service;
15+
16+
#[derive(Clone)]
17+
pub struct Standard(Connector);
18+
19+
impl Standard {
20+
/// An https connection
21+
///
22+
/// If the `rustls` feature is enabled, this will use `rustls`.
23+
/// If the ONLY the `native-tls` feature is enabled, this will use `native-tls`.
24+
/// If both features are enabled, this will use `rustls`
25+
#[cfg(any(feature = "native-tls", feature = "rustls"))]
26+
pub fn https() -> Self {
27+
#[cfg(feature = "rustls")]
28+
{
29+
Self::rustls()
30+
}
31+
32+
// If we are compiling this function & rustls is not enabled, then native-tls MUST be enabled
33+
#[cfg(not(feature = "rustls"))]
34+
{
35+
Self::native_tls()
36+
}
37+
}
38+
39+
#[cfg(feature = "rustls")]
40+
pub fn rustls() -> Self {
41+
let https = hyper_rustls::HttpsConnector::with_native_roots();
42+
let client = hyper::Client::builder().build::<_, SdkBody>(https);
43+
Self(Connector::RustlsHttps(client))
44+
}
45+
46+
#[cfg(feature = "native-tls")]
47+
pub fn native_tls() -> Self {
48+
let https = hyper_tls::HttpsConnector::new();
49+
let client = hyper::Client::builder().build::<_, SdkBody>(https);
50+
Self(Connector::NativeHttps(client))
51+
}
52+
53+
/// A connection based on the provided `impl HttpService`
54+
///
55+
/// Generally, [`Standard::https()`](Standard::https) should be used. This constructor is intended to support
56+
/// using things like [`TestConnection`](crate::test_connection::TestConnection) or alternative
57+
/// http implementations.
58+
pub fn new(connector: impl HttpService + 'static) -> Self {
59+
Self(Connector::Dyn(Box::new(connector)))
60+
}
61+
}
62+
63+
/// An Http connection type for most use cases
64+
///
65+
/// This supports three options:
66+
/// 1. HTTPS
67+
/// 2. A `TestConnection`
68+
/// 3. Any implementation of the `HttpService` trait
69+
///
70+
/// This is designed to be used with [`aws_hyper::Client`](crate::Client) as a connector.
71+
#[derive(Clone)]
72+
enum Connector {
73+
/// An Https Connection
74+
///
75+
/// This is the correct connection for use cases talking to real AWS services.
76+
#[cfg(feature = "native-tls")]
77+
NativeHttps(hyper::Client<hyper_tls::HttpsConnector<hyper::client::HttpConnector>, SdkBody>),
78+
79+
/// An Https Connection
80+
///
81+
/// This is the correct connection for use cases talking to real AWS services.
82+
#[cfg(feature = "rustls")]
83+
RustlsHttps(hyper::Client<hyper_rustls::HttpsConnector<hyper::client::HttpConnector>, SdkBody>),
84+
85+
/// A generic escape hatch
86+
///
87+
/// This enables using any implementation of the HttpService trait. This allows using a totally
88+
/// separate HTTP stack or your own custom `TestConnection`.
89+
Dyn(Box<dyn HttpService>),
90+
}
91+
92+
impl Clone for Box<dyn HttpService> {
93+
fn clone(&self) -> Self {
94+
self.clone_box()
95+
}
96+
}
97+
98+
pub trait HttpService: Send + Sync {
99+
/// Return whether this service is ready to accept a request
100+
///
101+
/// See [`Service::poll_ready`](tower::Service::poll_ready)
102+
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), BoxError>>;
103+
104+
/// Call this service and return a response
105+
///
106+
/// See [`Service::call`](tower::Service::call)
107+
fn call(
108+
&mut self,
109+
req: http::Request<SdkBody>,
110+
) -> Pin<Box<dyn Future<Output = Result<http::Response<SdkBody>, BoxError>> + Send>>;
111+
112+
/// Return a Boxed-clone of this service
113+
///
114+
/// `aws_hyper::Client` will clone the inner service for each request so this should be a cheap
115+
/// clone operation.
116+
fn clone_box(&self) -> Box<dyn HttpService>;
117+
}
118+
119+
/// Reverse implementation: If you have a correctly shaped tower service, it _is_ an `HttpService`
120+
///
121+
/// This is to facilitate ease of use for people using `Standard::Dyn`
122+
impl<S> HttpService for S
123+
where
124+
S: Service<http::Request<SdkBody>, Response = http::Response<SdkBody>>
125+
+ Send
126+
+ Sync
127+
+ Clone
128+
+ 'static,
129+
S::Error: Into<BoxError> + Send + Sync + 'static,
130+
S::Future: Send + 'static,
131+
{
132+
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), BoxError>> {
133+
Service::poll_ready(self, cx).map_err(|err| err.into())
134+
}
135+
136+
fn call(
137+
&mut self,
138+
req: Request<SdkBody>,
139+
) -> Pin<Box<dyn Future<Output = Result<Response<SdkBody>, BoxError>> + Send>> {
140+
let fut = Service::call(self, req);
141+
let fut = async move {
142+
fut.await
143+
.map(|res| res.map(SdkBody::from))
144+
.map_err(|err| err.into())
145+
};
146+
Box::pin(fut)
147+
}
148+
149+
fn clone_box(&self) -> Box<dyn HttpService> {
150+
Box::new(self.clone())
151+
}
152+
}
153+
154+
impl tower::Service<http::Request<SdkBody>> for Standard {
155+
type Response = http::Response<SdkBody>;
156+
type Error = BoxError;
157+
type Future = StandardFuture;
158+
159+
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
160+
match &mut self.0 {
161+
#[cfg(feature = "native-tls")]
162+
Connector::NativeHttps(https) => {
163+
Service::poll_ready(https, cx).map_err(|err| err.into())
164+
}
165+
#[cfg(feature = "rustls")]
166+
Connector::RustlsHttps(https) => {
167+
Service::poll_ready(https, cx).map_err(|err| err.into())
168+
}
169+
Connector::Dyn(conn) => conn.poll_ready(cx),
170+
}
171+
}
172+
173+
fn call(&mut self, req: http::Request<SdkBody>) -> Self::Future {
174+
match &mut self.0 {
175+
#[cfg(feature = "native-tls")]
176+
Connector::NativeHttps(https) => StandardFuture::Https(Service::call(https, req)),
177+
#[cfg(feature = "rustls")]
178+
Connector::RustlsHttps(https) => StandardFuture::Https(Service::call(https, req)),
179+
Connector::Dyn(conn) => StandardFuture::Dyn(conn.call(req)),
180+
}
181+
}
182+
}
183+
184+
/// Future returned by `Standard` when used as a tower::Service
185+
#[pin_project::pin_project(project = FutProj)]
186+
pub enum StandardFuture {
187+
Https(#[pin] ResponseFuture),
188+
Dyn(#[pin] Pin<Box<dyn Future<Output = Result<http::Response<SdkBody>, BoxError>> + Send>>),
189+
}
190+
191+
impl Future for StandardFuture {
192+
type Output = Result<http::Response<SdkBody>, BoxError>;
193+
194+
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
195+
match self.project() {
196+
FutProj::Https(fut) => fut
197+
.poll(cx)
198+
.map(|resp| resp.map(|res| res.map(SdkBody::from)))
199+
.map_err(|err| err.into()),
200+
FutProj::Dyn(dyn_fut) => dyn_fut.poll(cx),
201+
}
202+
}
203+
}

0 commit comments

Comments
 (0)