1use std::fmt;
2use std::sync::Arc;
3
4use aws_smithy_runtime_api::client::http::{
5 HttpClient as AwsClient, HttpConnector as AwsConnector,
6 HttpConnectorFuture as AwsConnectorFuture, HttpConnectorFuture, HttpConnectorSettings,
7 SharedHttpConnector,
8};
9use aws_smithy_runtime_api::client::orchestrator::{HttpRequest as AwsHttpRequest, HttpResponse};
10use aws_smithy_runtime_api::client::result::ConnectorError;
11use aws_smithy_runtime_api::client::runtime_components::RuntimeComponents;
12use aws_smithy_runtime_api::http::{Headers, StatusCode};
13use aws_smithy_types::body::SdkBody;
14use http_client::AsyncBody;
15use http_client::{HttpClient, Request};
16
17struct AwsHttpConnector {
18 client: Arc<dyn HttpClient>,
19}
20
21impl std::fmt::Debug for AwsHttpConnector {
22 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result {
23 f.debug_struct("AwsHttpConnector").finish()
24 }
25}
26
27impl AwsConnector for AwsHttpConnector {
28 fn call(&self, request: AwsHttpRequest) -> AwsConnectorFuture {
29 let req = match request.try_into_http1x() {
30 Ok(req) => req,
31 Err(err) => {
32 return HttpConnectorFuture::ready(Err(ConnectorError::other(err.into(), None)));
33 }
34 };
35
36 let (parts, body) = req.into_parts();
37
38 let response = self
39 .client
40 .send(Request::from_parts(parts, convert_to_async_body(body)));
41
42 HttpConnectorFuture::new(async move {
43 let response = match response.await {
44 Ok(response) => response,
45 Err(err) => return Err(ConnectorError::other(err.into(), None)),
46 };
47 let (parts, body) = response.into_parts();
48
49 let mut response = HttpResponse::new(
50 StatusCode::try_from(parts.status.as_u16()).unwrap(),
51 convert_to_sdk_body(body),
52 );
53
54 let headers = match Headers::try_from(parts.headers) {
55 Ok(headers) => headers,
56 Err(err) => return Err(ConnectorError::other(err.into(), None)),
57 };
58
59 *response.headers_mut() = headers;
60
61 Ok(response)
62 })
63 }
64}
65
66#[derive(Clone)]
67pub struct AwsHttpClient {
68 client: Arc<dyn HttpClient>,
69}
70
71impl std::fmt::Debug for AwsHttpClient {
72 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result {
73 f.debug_struct("AwsHttpClient").finish()
74 }
75}
76
77impl AwsHttpClient {
78 pub fn new(client: Arc<dyn HttpClient>) -> Self {
79 Self { client }
80 }
81}
82
83impl AwsClient for AwsHttpClient {
84 fn http_connector(
85 &self,
86 _settings: &HttpConnectorSettings,
87 _components: &RuntimeComponents,
88 ) -> SharedHttpConnector {
89 SharedHttpConnector::new(AwsHttpConnector {
90 client: self.client.clone(),
91 })
92 }
93}
94
95pub fn convert_to_sdk_body(body: AsyncBody) -> SdkBody {
96 SdkBody::from_body_1_x(body)
97}
98
99pub fn convert_to_async_body(body: SdkBody) -> AsyncBody {
100 match body.bytes() {
101 Some(bytes) => AsyncBody::from((*bytes).to_vec()),
102 None => AsyncBody::empty(),
103 }
104}