diana_aws_lambda/
run_aws_req.rs1use async_graphql::{ObjectType, SubscriptionType};
4use aws_lambda_events::encodings::Body;
5use netlify_lambda_http::{Request, Response};
6use std::any::Any;
7
8use diana::{DianaHandler, DianaResponse, Options};
9
10pub type AwsError = Box<dyn std::error::Error + Send + Sync + 'static>;
12
13enum AwsReqData {
15 Valid((String, Option<String>)),
16 Invalid(Response<String>), }
18
19fn get_data_from_aws_req(req: Request) -> Result<AwsReqData, AwsError> {
22 let body = req.body();
25 let body = match body {
26 Body::Text(body_str) => body_str.to_string(),
27 Body::Binary(body_binary) => {
29 let body_str = std::str::from_utf8(&body_binary);
30 match body_str {
31 Ok(body_str) => body_str.to_string(),
32 Err(_) => {
33 let res = Response::builder()
34 .status(400) .body(
36 "Found binary body that couldn't be serialized to string".to_string(),
37 )?;
38 return Ok(AwsReqData::Invalid(res));
39 }
40 }
41 }
42 Body::Empty => {
43 let res = Response::builder()
44 .status(400) .body("Found empty body, expected string".to_string())?;
46 return Ok(AwsReqData::Invalid(res));
47 }
48 };
49 let auth_header = req.headers().get("Authorization");
52 let auth_header = match auth_header {
53 Some(auth_header) => {
54 let header_str = auth_header.to_str();
55 match header_str {
56 Ok(header_str) => Some(header_str.to_string()),
57 Err(_) => {
58 let res = Response::builder()
59 .status(400) .body("Couldn't parse authorization header as string".to_string())?;
61 return Ok(AwsReqData::Invalid(res));
62 }
63 }
64 }
65 None => None,
66 };
67
68 Ok(AwsReqData::Valid((body, auth_header)))
69}
70
71fn parse_aws_res(res: DianaResponse) -> Result<Response<String>, AwsError> {
73 let res = match res {
74 DianaResponse::Success(gql_res_str) => Response::builder()
75 .status(200) .body(gql_res_str)?,
77 DianaResponse::Blocked => Response::builder()
78 .status(403) .body("Request blocked due to invalid or insufficient authentication".to_string())?,
80 DianaResponse::Error(_) => Response::builder()
81 .status(500) .body("An internal server error occurred".to_string())?,
83 };
84
85 Ok(res)
86}
87
88pub async fn run_aws_req<C, Q, M, S>(
93 req: Request,
94 opts: Options<C, Q, M, S>,
95) -> Result<Response<String>, AwsError>
96where
97 C: Any + Send + Sync + Clone,
98 Q: Clone + ObjectType + 'static,
99 M: Clone + ObjectType + 'static,
100 S: Clone + SubscriptionType + 'static,
101{
102 let diana_handler = DianaHandler::new(opts.clone()).map_err(|err| err.to_string())?;
106 let req_data = get_data_from_aws_req(req)?;
108 let (body, auth_header) = match req_data {
109 AwsReqData::Valid(data) => data,
110 AwsReqData::Invalid(http_res) => return Ok(http_res), };
112
113 let res = diana_handler
117 .run_stateless_without_subscriptions(body, auth_header.as_deref(), None)
118 .await;
119
120 let http_res = parse_aws_res(res)?;
122 Ok(http_res)
123}