1use std::{
19 fmt::{Debug, Display},
20 str::FromStr,
21};
22
23use crate::{
24 prr::{self, Prr, PrrType, ValueType},
25 utils::try_to_url,
26};
27
28pub trait MetadataInformationResultElement: Debug {}
30
31#[derive(Debug, Default)]
33pub struct MetadataInformationResultElements {
34 pub elements: Vec<Box<dyn MetadataInformationResultElement>>,
35}
36
37#[derive(Debug, PartialEq)]
39pub enum Stages {
40 Pre,
41 PreClientRequest,
42 ClientRequest,
43 PostClientRequest,
44 PreOriginRequest,
45 OriginRequest,
46 PostOriginRequest,
47 Source,
48 PreOriginResponse,
49 OriginResponse,
50 PostOriginResponse,
51 PreClientResponse,
52 ClientResponse,
53 PostClientResponse,
54 Post,
55}
56
57#[derive(Debug)]
65pub struct InterpreterContext<C> {
66 pub request: Option<http::Request<Vec<u8>>>,
67 pub response: Option<reqwest::Response>,
68 pub runtime: tokio::runtime::Runtime,
69 pub cookie: C,
70}
71
72#[derive(Debug)]
74pub enum Error {
75 InvalidType(String , String ),
76 InvalidMetadata(Box<dyn std::error::Error>),
77 NoProcessor(String ),
78 InvalidInput(Box<dyn std::error::Error>),
79 AssertionFailure(Box<dyn std::error::Error>),
80 NotImplemented(String),
81 InvalidOutput,
82 RuntimeError(Box<dyn std::error::Error>),
83}
84
85impl Display for Error {
86 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
87 match self {
88 Error::NotImplemented(feature) => write!(f, "Feature {feature} is not yet implemented"),
89 Error::InvalidType(_, _) => write!(f, "Invalid type"),
90 Error::InvalidMetadata(_) => write!(f, "Invalid metadata"),
91 Error::NoProcessor(_) => write!(f, "No processor"),
92 Error::InvalidInput(e) => write!(f, "Invalid input: {e}"),
93 Error::InvalidOutput => write!(f, "Invalid output"),
94 Error::AssertionFailure(e) => write!(f, "Assertion failure: {e}"),
95 Error::RuntimeError(e) => write!(f, "Runtime error: {e}"),
96 }
97 }
98}
99
100impl std::error::Error for Error {}
101
102#[derive(Debug)]
104pub struct ProcessedRequestResponse {
105 pub oheaders: http::HeaderMap<http::HeaderValue>,
106 pub obody: Vec<u8>,
107 pub ourl: url::Url,
108 pub ostatus: Option<http::StatusCode>,
109 pub omethod: http::Method,
110 pub tpe: prr::PrrType,
111}
112
113impl ProcessedRequestResponse {
114 pub fn new_request(url: &url::Url, method: &http::Method) -> Self {
115 ProcessedRequestResponse {
116 oheaders: http::HeaderMap::<http::HeaderValue>::default(),
117 obody: vec![],
118 ourl: url.clone(),
119 ostatus: None,
120 tpe: prr::PrrType::Request,
121 omethod: method.clone(),
122 }
123 }
124
125 pub fn new_response(url: &url::Url, method: &http::Method) -> Self {
126 ProcessedRequestResponse {
127 oheaders: http::HeaderMap::<http::HeaderValue>::default(),
128 obody: vec![],
129 ourl: url.clone(),
130 ostatus: None,
131 tpe: prr::PrrType::Response,
132 omethod: method.clone(),
133 }
134 }
135}
136
137impl TryFrom<&http::Request<Vec<u8>>> for ProcessedRequestResponse {
138 type Error = url::ParseError;
139
140 fn try_from(value: &http::Request<Vec<u8>>) -> Result<Self, Self::Error> {
141 let mut result =
142 ProcessedRequestResponse::new_request(&try_to_url(value.uri())?, value.method());
143
144 let mut headers = http::HeaderMap::<http::HeaderValue>::default();
145 for (k, v) in value.headers() {
146 headers.insert(k, v.clone());
147 }
148
149 result.oheaders = headers;
150 result.ostatus = None;
151 result.obody = value.body().clone();
152
153 Ok(result)
154 }
155}
156
157impl prr::Prr<Vec<u8>> for ProcessedRequestResponse {
158 fn headers(&self) -> Vec<(String, http::HeaderValue)> {
159 self.oheaders
160 .iter()
161 .map(|(k, v)| (k.to_string(), v.clone()))
162 .collect()
163 }
164
165 fn set_header_value(&mut self, header: &str, value: &str) -> prr::Result<()> {
166 let header_to_set = http::HeaderName::from_str(header).map_err(|_| {
167 prr::Error::BadValue(prr::Value {
168 tpe: prr::ValueType::HeaderName,
169 value: Some(header.to_string()),
170 })
171 })?;
172 let header_to_set_value = http::HeaderValue::from_str(value).map_err(|_| {
173 prr::Error::BadValue(prr::Value {
174 tpe: prr::ValueType::HeaderValue,
175 value: Some(value.to_string()),
176 })
177 })?;
178
179 self.oheaders.insert(header_to_set, header_to_set_value);
180 Ok(())
181 }
182
183 fn remove_header(&mut self, header: &str) -> prr::Result<()> {
184 let header_to_remove = http::HeaderName::from_str(header).map_err(|_| {
185 prr::Error::BadValue(prr::Value {
186 tpe: prr::ValueType::HeaderName,
187 value: Some(header.to_string()),
188 })
189 })?;
190 self.oheaders.remove(header_to_remove);
191 Ok(())
192 }
193
194 fn add_header(&mut self, header: &str, value: &str) -> prr::Result<()> {
195 self.set_header_value(header, value)
196 }
197
198 fn url(&self) -> prr::Result<url::Url> {
199 Ok(self.ourl.clone())
200 }
201
202 fn set_url(&mut self, url: &url::Url) -> prr::Result<()> {
203 self.ourl = url.clone();
204 Ok(())
205 }
206
207 fn set_status(&mut self, response: &u16) -> prr::Result<()> {
208 self.ostatus = Some(http::StatusCode::from_u16(*response).map_err(|_| {
209 prr::Error::BadValue(prr::Value {
210 tpe: prr::ValueType::Status,
211 value: Some(response.to_string()),
212 })
213 })?);
214 Ok(())
215 }
216
217 fn clear_headers(&mut self) -> prr::Result<()> {
218 self.oheaders.clear();
219 Ok(())
220 }
221
222 fn set_body(&mut self, body: &Vec<u8>) -> prr::Result<()> {
223 self.obody = body.clone();
224 Ok(())
225 }
226
227 fn get_body(&self) -> prr::Result<&Vec<u8>> {
228 Ok(&self.obody)
229 }
230
231 fn get_status(&self) -> prr::Result<http::StatusCode> {
232 self.ostatus
233 .ok_or(prr::Error::MissingValue(prr::ValueType::Status))
234 }
235
236 fn tpe(&self) -> prr::PrrType {
237 self.tpe.clone()
238 }
239
240 fn set_method(&mut self, method: &http::Method) -> prr::Result<()> {
241 self.omethod = method.clone();
242 Ok(())
243 }
244
245 fn get_method(&self) -> http::Method {
246 self.omethod.clone()
247 }
248}
249
250impl TryFrom<&dyn Prr<Vec<u8>>> for reqwest::Request {
251 type Error = prr::Error;
252
253 fn try_from(value: &dyn Prr<Vec<u8>>) -> std::result::Result<Self, Self::Error> {
254 if value.tpe() != PrrType::Request {
255 return Err(prr::Error::InvalidMode);
256 }
257
258 let url = value
259 .url()
260 .map_err(|_| prr::Error::MissingValue(ValueType::Url))?;
261
262 let mut request = reqwest::Request::new(reqwest::Method::GET, url);
263
264 for (header_key, header_value) in value.headers() {
266 request.headers_mut().insert(
267 http::HeaderName::from_str(&header_key).map_err(|_| {
268 prr::Error::BadValue(prr::Value {
269 tpe: ValueType::HeaderName,
270 value: Some(header_key.clone()),
271 })
272 })?,
273 header_value,
274 );
275 }
276
277 request.body_mut().replace(
279 value
280 .get_body()
281 .map_err(|_| prr::Error::MissingValue(ValueType::Body))?
282 .clone()
283 .into(),
284 );
285
286 Ok(request)
287 }
288}