aws_http_client.rs

  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}