cloud_sdk/operation/
local_async.rs1use super::{CheckedResponseGuard, PreparedExecutionError, PreparedRequest};
4use crate::authentication::{LocalAsyncAuthenticatedTransport, drive_local_authenticated};
5use crate::transport::{AsyncExecutionError, BoundTransport, EndpointIdentity, ResponseBuffer};
6use cloud_sdk_sanitization::sanitize_bytes;
7
8impl<'request> PreparedRequest<'request> {
9 pub async fn execute_local_async<'transport, 'buffer, T>(
16 &'transport self,
17 transport: &'transport T,
18 response_storage: &'buffer mut [u8],
19 response_header_storage: &'buffer mut [u8],
20 ) -> Result<CheckedResponseGuard<'buffer>, PreparedExecutionError<T::Error>>
21 where
22 T: LocalAsyncAuthenticatedTransport + BoundTransport,
23 'request: 'transport,
24 {
25 let response = self
26 .send_local_async(transport, response_storage, response_header_storage)
27 .await?;
28 self.validate_response(response)
29 .map_err(PreparedExecutionError::ResponsePolicy)
30 }
31
32 pub(crate) async fn send_local_async<'transport, 'buffer, T>(
33 &'transport self,
34 transport: &'transport T,
35 response_storage: &'buffer mut [u8],
36 response_header_storage: &'buffer mut [u8],
37 ) -> Result<ResponseBuffer<'buffer>, PreparedExecutionError<T::Error>>
38 where
39 T: LocalAsyncAuthenticatedTransport + BoundTransport,
40 'request: 'transport,
41 {
42 if self.requires_execution_permit() {
43 sanitize_bytes(response_storage);
44 sanitize_bytes(response_header_storage);
45 return Err(PreparedExecutionError::AuthorizationRequired);
46 }
47 self.send_local_async_authorized(transport, None, response_storage, response_header_storage)
48 .await
49 }
50
51 pub(crate) async fn execute_local_async_authorized<'transport, 'buffer, T>(
52 &'transport self,
53 transport: &'transport T,
54 confirmed_endpoint: Option<EndpointIdentity<'_>>,
55 response_storage: &'buffer mut [u8],
56 response_header_storage: &'buffer mut [u8],
57 ) -> Result<CheckedResponseGuard<'buffer>, PreparedExecutionError<T::Error>>
58 where
59 T: LocalAsyncAuthenticatedTransport + BoundTransport,
60 'request: 'transport,
61 {
62 let response = self
63 .send_local_async_authorized(
64 transport,
65 confirmed_endpoint,
66 response_storage,
67 response_header_storage,
68 )
69 .await?;
70 self.validate_response(response)
71 .map_err(PreparedExecutionError::ResponsePolicy)
72 }
73
74 pub(crate) async fn send_local_async_authorized<'transport, 'buffer, T>(
75 &'transport self,
76 transport: &'transport T,
77 confirmed_endpoint: Option<EndpointIdentity<'_>>,
78 response_storage: &'buffer mut [u8],
79 response_header_storage: &'buffer mut [u8],
80 ) -> Result<ResponseBuffer<'buffer>, PreparedExecutionError<T::Error>>
81 where
82 T: LocalAsyncAuthenticatedTransport + BoundTransport,
83 'request: 'transport,
84 {
85 let mut response = ResponseBuffer::new(
86 response_storage,
87 self.raw_response_policy().max_body_bytes(),
88 response_header_storage,
89 );
90 let actual = transport
91 .endpoint_identity()
92 .map_err(PreparedExecutionError::EndpointIdentity)?;
93 match confirmed_endpoint {
94 Some(expected) if actual == expected => {}
95 Some(_) => return Err(PreparedExecutionError::EndpointMismatch),
96 None => self
97 .service()
98 .endpoint_policy()
99 .verify(actual)
100 .map_err(|_| PreparedExecutionError::EndpointMismatch)?,
101 }
102 drive_local_authenticated(transport, self.authenticated_request(), response.writer())
103 .await
104 .map_err(map_local_error)?;
105 Ok(response)
106 }
107}
108
109fn map_local_error<E>(error: AsyncExecutionError<E>) -> PreparedExecutionError<E> {
110 match error {
111 AsyncExecutionError::Transport(error) => PreparedExecutionError::Transport(error),
112 AsyncExecutionError::Response(error) => PreparedExecutionError::ResponseWriter(error),
113 }
114}