hvcg_commons_lambda_client/
http_request.rs

1use bytes::Bytes;
2use rusoto_core::RusotoError;
3use rusoto_lambda::{InvocationRequest, InvocationResponse, InvokeError, Lambda, LambdaClient};
4use serde::{Deserialize, Serialize};
5use serde_json::{json, Value};
6use std::env;
7
8pub async fn invoke<P>(
9    function_name: String,
10    path: String,
11    method: String,
12    body_option: Option<P>,
13) -> Result<String, RusotoError<InvokeError>>
14where
15    P: Serialize,
16{
17    let body: Value;
18    if body_option.is_none() {
19        body = Default::default();
20    } else {
21        body = json!(json!(body_option.unwrap()).to_string());
22    }
23
24    let request = Request {
25        resource: path.clone(),
26        path: path.clone(),
27        http_method: method.clone(),
28        headers: Headers {
29            accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9".to_string(),
30            accept_encoding: "gzip, deflate, br".to_string(),
31            accept_language: "en-US,en;q=0.9".to_string(),
32            cookie: "s_fid=7AAB6XMPLAFD9BBF-0643XMPL09956DE2; regStatus=pre-register".to_string(),
33            content_type: "application/json".to_string(),
34            host: "70ixmpl4fl.execute-api.us-east-2.amazonaws.com".to_string(),
35            sec_fetch_dest: "document".to_string(),
36            sec_fetch_mode: "navigate".to_string(),
37            sec_fetch_site: "none".to_string(),
38            upgrade_insecure_requests: "1".to_string(),
39            user_agent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36".to_string(),
40            x_amzn_trace_id: "Root=1-5e66d96f-7491f09xmpl79d18acf3d050".to_string(),
41            x_forwarded_for: "52.255.255.12".to_string(),
42            x_forwarded_port: "443".to_string(),
43            x_forwarded_proto: "https".to_string()
44        },
45        multi_value_headers: Default::default(),
46        query_string_parameters: Default::default(),
47        multi_value_query_string_parameters: Default::default(),
48        path_parameters: Default::default(),
49        stage_variables: Default::default(),
50        request_context: RequestContext {
51            resource_id: "id123".to_string(),
52            resource_path: path.clone(),
53            http_method: method,
54            extended_request_id: "ext123".to_string(),
55            request_time: "10/Mar/2020:00:03:59 +0000".to_string(),
56            path: path.clone(),
57            account_id: "123456789012".to_string(),
58            protocol: "HTTP/1.1".to_string(),
59            stage: "dev".to_string(),
60            domain_prefix: "prefix123".to_string(),
61            request_time_epoch: 1583798639428,
62            request_id: "id123".to_string(),
63            identity: Default::default(),
64            domain_name: "".to_string(),
65            api_id: "".to_string()
66        },
67        body,
68        is_base64_encoded: false
69    };
70    let json_request: Value = json!(request);
71    let json_request_string = serde_json::to_string(&json_request).unwrap();
72    println!("invoking with {}", json_request_string);
73    let json_request_bytes = json_request_string.into_bytes();
74
75    let lambda_client = LambdaClient::new("ap-southeast-1".parse().unwrap());
76    let res = lambda_client
77        .invoke(InvocationRequest {
78            client_context: None,
79            function_name: (env::var("APP_ENV").unwrap() + "_" + &*function_name)
80                .parse()
81                .unwrap(),
82            invocation_type: None,
83            log_type: None,
84            payload: Option::from(Bytes::from(json_request_bytes)),
85            qualifier: None,
86        })
87        .await;
88    if res.is_err() {
89        Err(res.err().unwrap())
90    } else {
91        let payload_bytes = res.unwrap().payload.unwrap();
92        // let res_string = String::from_utf8(payload_bytes.to_vec()).unwrap();
93        // let res_string_static: &'a str = &*res_string;
94        // // let res_str: &'a str = &*res_string;
95        // let p: P = serde_json::from_str(&*res_string).unwrap();
96        Ok(String::from_utf8(payload_bytes.to_vec()).unwrap())
97    }
98}
99
100#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
101#[serde(rename_all = "camelCase")]
102pub struct Request {
103    pub resource: String,
104    pub path: String,
105    pub http_method: String,
106    pub headers: Headers,
107    pub multi_value_headers: MultiValueHeaders,
108    pub query_string_parameters: ::serde_json::Value,
109    pub multi_value_query_string_parameters: ::serde_json::Value,
110    pub path_parameters: ::serde_json::Value,
111    pub stage_variables: ::serde_json::Value,
112    pub request_context: RequestContext,
113    pub body: ::serde_json::Value,
114    pub is_base64_encoded: bool,
115}
116
117#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
118#[serde(rename_all = "camelCase")]
119pub struct Headers {
120    pub accept: String,
121    #[serde(rename = "accept-encoding")]
122    pub accept_encoding: String,
123    #[serde(rename = "accept-language")]
124    pub accept_language: String,
125    pub cookie: String,
126    #[serde(rename = "content-type")]
127    pub content_type: String,
128    #[serde(rename = "Host")]
129    pub host: String,
130    #[serde(rename = "sec-fetch-dest")]
131    pub sec_fetch_dest: String,
132    #[serde(rename = "sec-fetch-mode")]
133    pub sec_fetch_mode: String,
134    #[serde(rename = "sec-fetch-site")]
135    pub sec_fetch_site: String,
136    #[serde(rename = "upgrade-insecure-requests")]
137    pub upgrade_insecure_requests: String,
138    #[serde(rename = "User-Agent")]
139    pub user_agent: String,
140    #[serde(rename = "X-Amzn-Trace-Id")]
141    pub x_amzn_trace_id: String,
142    #[serde(rename = "X-Forwarded-For")]
143    pub x_forwarded_for: String,
144    #[serde(rename = "X-Forwarded-Port")]
145    pub x_forwarded_port: String,
146    #[serde(rename = "X-Forwarded-Proto")]
147    pub x_forwarded_proto: String,
148}
149
150#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
151#[serde(rename_all = "camelCase")]
152pub struct MultiValueHeaders {
153    pub accept: Vec<String>,
154    #[serde(rename = "accept-encoding")]
155    pub accept_encoding: Vec<String>,
156    #[serde(rename = "accept-language")]
157    pub accept_language: Vec<String>,
158    pub cookie: Vec<String>,
159    #[serde(rename = "Host")]
160    pub host: Vec<String>,
161    #[serde(rename = "sec-fetch-dest")]
162    pub sec_fetch_dest: Vec<String>,
163    #[serde(rename = "sec-fetch-mode")]
164    pub sec_fetch_mode: Vec<String>,
165    #[serde(rename = "sec-fetch-site")]
166    pub sec_fetch_site: Vec<String>,
167    #[serde(rename = "upgrade-insecure-requests")]
168    pub upgrade_insecure_requests: Vec<String>,
169    #[serde(rename = "User-Agent")]
170    pub user_agent: Vec<String>,
171    #[serde(rename = "X-Amzn-Trace-Id")]
172    pub x_amzn_trace_id: Vec<String>,
173    #[serde(rename = "X-Forwarded-For")]
174    pub x_forwarded_for: Vec<String>,
175    #[serde(rename = "X-Forwarded-Port")]
176    pub x_forwarded_port: Vec<String>,
177    #[serde(rename = "X-Forwarded-Proto")]
178    pub x_forwarded_proto: Vec<String>,
179}
180
181#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
182#[serde(rename_all = "camelCase")]
183pub struct RequestContext {
184    pub resource_id: String,
185    pub resource_path: String,
186    pub http_method: String,
187    pub extended_request_id: String,
188    pub request_time: String,
189    pub path: String,
190    pub account_id: String,
191    pub protocol: String,
192    pub stage: String,
193    pub domain_prefix: String,
194    pub request_time_epoch: i64,
195    pub request_id: String,
196    pub identity: Identity,
197    pub domain_name: String,
198    pub api_id: String,
199}
200
201#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
202#[serde(rename_all = "camelCase")]
203pub struct Identity {
204    pub cognito_identity_pool_id: ::serde_json::Value,
205    pub account_id: ::serde_json::Value,
206    pub cognito_identity_id: ::serde_json::Value,
207    pub caller: ::serde_json::Value,
208    pub source_ip: String,
209    pub principal_org_id: ::serde_json::Value,
210    pub access_key: ::serde_json::Value,
211    pub cognito_authentication_type: ::serde_json::Value,
212    pub cognito_authentication_provider: ::serde_json::Value,
213    pub user_arn: ::serde_json::Value,
214    pub user_agent: String,
215    pub user: ::serde_json::Value,
216}