cloud_sdk_reqwest/asynchronous/
basic_client.rs1use core::fmt;
2use std::sync::Arc;
3
4use cloud_sdk::authentication::{AsyncAuthenticatedTransport, AuthenticatedRequest};
5use cloud_sdk::transport::{
6 AsyncResponseStaging, BoundTransport, EndpointIdentity, EndpointIdentityError,
7 ResponseCompletion, ResponseStorageSanitizer, TransportFailure,
8};
9use cloud_sdk_sanitization::sanitize_bytes;
10
11use crate::shared::{
12 AuthenticatedTransportFailure, BasicCredential, HttpsEndpoint, TransportError,
13 map_authentication_error, validate_basic_authentication,
14};
15
16use super::RawAsyncClient;
17
18#[derive(Clone)]
20pub struct AsyncBasicClient {
21 client: RawAsyncClient,
22 endpoint: HttpsEndpoint,
23 credential: Arc<BasicCredential>,
24 allow_insecure_loopback: bool,
25}
26
27impl AsyncBasicClient {
28 pub(super) fn new(
29 client: RawAsyncClient,
30 endpoint: HttpsEndpoint,
31 credential: BasicCredential,
32 allow_insecure_loopback: bool,
33 ) -> Self {
34 Self {
35 client,
36 endpoint,
37 credential: Arc::new(credential),
38 allow_insecure_loopback,
39 }
40 }
41
42 async fn send_inner<'writer, 'buffer>(
43 &self,
44 authenticated: AuthenticatedRequest<'_, '_>,
45 response: AsyncResponseStaging<'writer, 'buffer>,
46 ) -> Result<ResponseCompletion, AuthenticatedTransportFailure> {
47 let endpoint = self.endpoint.identity().map_err(|_| {
48 TransportFailure::not_sent(TransportError::AuthenticationEndpointMismatch)
49 })?;
50 validate_basic_authentication(
51 endpoint,
52 self.credential.scope(),
53 authenticated.policy(),
54 self.allow_insecure_loopback,
55 )
56 .map_err(|error| TransportFailure::not_sent(map_authentication_error(error)))?;
57 let authorization = self
58 .credential
59 .header_value()
60 .map_err(|_| TransportFailure::not_sent(TransportError::HeaderRejected))?;
61 self.client
62 .execute_authenticated(
63 authenticated.transport_request(),
64 authenticated.response_policy(),
65 authorization,
66 response,
67 )
68 .await
69 .map_err(|failure| failure.map(TransportError::RawHttp))
70 }
71}
72
73impl AsyncAuthenticatedTransport for AsyncBasicClient {
74 type Error = AuthenticatedTransportFailure;
75
76 async fn send_authenticated<'transport, 'request, 'policy, 'writer, 'buffer>(
77 &'transport self,
78 request: AuthenticatedRequest<'request, 'policy>,
79 response: AsyncResponseStaging<'writer, 'buffer>,
80 ) -> Result<ResponseCompletion, Self::Error>
81 where
82 'transport: 'writer,
83 'request: 'writer,
84 'policy: 'writer,
85 'buffer: 'writer,
86 {
87 self.send_inner(request, response).await
88 }
89}
90
91impl ResponseStorageSanitizer for AsyncBasicClient {
92 fn sanitize_response_storage(&self, response_storage: &mut [u8]) {
93 sanitize_bytes(response_storage);
94 }
95}
96
97impl BoundTransport for AsyncBasicClient {
98 fn endpoint_identity(&self) -> Result<EndpointIdentity<'_>, EndpointIdentityError> {
99 self.endpoint.identity()
100 }
101}
102
103impl fmt::Debug for AsyncBasicClient {
104 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
105 formatter
106 .debug_struct("AsyncBasicClient")
107 .field("endpoint", &"[redacted]")
108 .field("credential", &"[redacted]")
109 .finish_non_exhaustive()
110 }
111}