openwhisk_rust/client/
wasmtime_client.rs1use 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}