openwhisk_rust/client/
wasmtime_client.rs

1use super::common::{whisk_errors, OpenWhisk};
2use crate::api::{HttpMethods, Service};
3use bytes::Bytes;
4use http::{HeaderMap, Request, StatusCode};
5use serde_json::{Error, Value};
6use wasi_experimental_http::request as wasi_request;
7
8#[derive(Debug, Default, Clone)]
9pub struct WasmClient {
10    headers: http::HeaderMap,
11}
12impl OpenWhisk for WasmClient {
13    type Output = WasmClient;
14
15    fn new_whisk_client(insecure: Option<bool>) -> Self::Output {
16        let mut header_map = HeaderMap::new();
17        match insecure {
18            Some(x) => match x {
19                true => header_map.insert("Upgrade-Insecure-Requests", "1".parse().unwrap()),
20                false => header_map.insert("upgrade-insecure-requests", "0".parse().unwrap()),
21            },
22            None => todo!(),
23        };
24        WasmClient {
25            headers: header_map,
26        }
27    }
28}
29
30impl Service for WasmClient {
31    type Output = Request<Option<Bytes>>;
32
33    fn new_request(
34        &self,
35        method: Option<HttpMethods>,
36        url: &str,
37        user_auth: Option<(&str, &str)>,
38        body: Option<Value>,
39    ) -> Result<Self::Output, String> {
40        let mut req = http::request::Builder::new().header("Content-Type", "application/json");
41        for (key, value) in self.headers.iter() {
42            req = req.header(key, value);
43        }
44        let body = Bytes::from(serde_json::to_vec(&body).unwrap());
45        match user_auth {
46            Some(auth) => {
47                let user = auth.0;
48                let pass = auth.1;
49                let bse64_encode = base64::encode(format!("{}:{}", user, pass));
50
51                match method {
52                    Some(http_methods) => match http_methods {
53                        HttpMethods::GET => {
54                            let req = req
55                                .header("Authorization", format!("Basic {}", bse64_encode))
56                                .method("GET")
57                                .uri(url)
58                                .body(Some(body));
59                            match req {
60                                Ok(req) => Ok(req),
61                                Err(error) => Err(format!("{}", error)),
62                            }
63                        }
64                        HttpMethods::PUT => {
65                            let req = req
66                                .header("Authorization", format!("Basic {}", bse64_encode))
67                                .method("PUT")
68                                .uri(url)
69                                .body(Some(body));
70                            match req {
71                                Ok(req) => Ok(req),
72                                Err(error) => Err(format!("{}", error)),
73                            }
74                        }
75                        HttpMethods::POST => {
76                            let req = req
77                                .header("Authorization", format!("Basic {}", bse64_encode))
78                                .method("POST")
79                                .uri(url)
80                                .body(Some(body));
81                            match req {
82                                Ok(req) => Ok(req),
83                                Err(error) => Err(format!("{}", error)),
84                            }
85                        }
86                        HttpMethods::DELETE => {
87                            let req = req
88                                .header("Authorization", format!("Basic {}", bse64_encode))
89                                .method("DELETE")
90                                .uri(url)
91                                .body(Some(body));
92                            match req {
93                                Ok(req) => Ok(req),
94                                Err(error) => Err(format!("{}", error)),
95                            }
96                        }
97                    },
98                    None => Err("Falied to create request".to_string()),
99                }
100            }
101            None => match method {
102                Some(http_methods) => match http_methods {
103                    HttpMethods::GET => {
104                        let req = req.method("GET").uri(url).body(Some(body));
105                        match req {
106                            Ok(req) => Ok(req),
107                            Err(error) => Err(format!("{}", error)),
108                        }
109                    }
110                    HttpMethods::PUT => {
111                        let req = req.method("PUT").uri(url).body(Some(body));
112                        match req {
113                            Ok(req) => Ok(req),
114                            Err(error) => Err(format!("{}", error)),
115                        }
116                    }
117                    HttpMethods::POST => {
118                        let req = req.method("POST").uri(url).body(Some(body));
119                        match req {
120                            Ok(req) => Ok(req),
121                            Err(error) => Err(format!("{}", error)),
122                        }
123                    }
124                    HttpMethods::DELETE => {
125                        let req = req.method("DELETE").uri(url).body(Some(body));
126                        match req {
127                            Ok(req) => Ok(req),
128                            Err(error) => Err(format!("{}", error)),
129                        }
130                    }
131                },
132                None => Err("Falied to create request".to_string()),
133            },
134        }
135    }
136
137    fn invoke_request(&self, request: Self::Output) -> Result<Value, String> {
138        match wasi_request(request) {
139            Ok(mut response) => match response.status_code {
140                StatusCode::OK => match response.body_read_all() {
141                    Ok(response) => match String::from_utf8(response) {
142                        Ok(response) => {
143                            let response_to_value: Result<Value, Error> =
144                                serde_json::from_str(&response);
145                            match response_to_value {
146                                Ok(value) => Ok(value),
147                                Err(error) => Err(error.to_string()),
148                            }
149                        }
150                        Err(error) => Err(error.to_string()),
151                    },
152                    Err(error) => return Err(format!("{}", error)),
153                },
154                _ => {
155                    let code = response.status_code;
156                    let error = response.body_read_all().unwrap();
157                    let s = match std::str::from_utf8(&error) {
158                        Ok(v) => v,
159                        Err(error) => return Err(format!("{}", error)),
160                    };
161
162                    Err(whisk_errors(code, s.to_string()))
163                }
164            },
165            Err(error) => Err(error.to_string()),
166        }
167    }
168}