1use crate::dcdn::error::{ImdInterpretError, ImdInterpretResult};
21use crate::dcdn::interpret::{Error, MetadataInformationResultElements, Stages};
22use crate::dcdn::processors::SimpleProcessorsInterpreterContext;
23use crate::environment::scope::Scopes;
24use crate::logging::{LogLevel, LogMsg, LogMsgs};
25use crate::processing::interpret::{InterpretationResult, Interpreter};
26use crate::verifying::verify::CdniVerificationKey;
27
28use crate::prr;
29use crate::{cdni::imd::spec::HostMetadata, mel::interpreter::values::TypedValue};
30
31pub type ResultValue = Option<http::Response<Vec<u8>>>;
32
33#[derive(Debug, Clone)]
34pub enum InterpretMode {
35 Request,
36 Response,
37}
38
39impl
42 Interpreter<
43 SimpleProcessorsInterpreterContext<'_>,
44 (ResultValue, MetadataInformationResultElements),
45 Stages,
46 Error,
47 > for CdniVerificationKey
48{
49 fn interpret<'a>(
50 &self,
51 input: SimpleProcessorsInterpreterContext<'a>,
52 ) -> InterpretationResult<
53 SimpleProcessorsInterpreterContext<'a>,
54 (ResultValue, MetadataInformationResultElements),
55 Error,
56 > {
57 match &self {
58 CdniVerificationKey::Stage(typed_stage) => typed_stage.interpret(input),
59 CdniVerificationKey::Source(typed_source) => typed_source.interpret(input),
60 CdniVerificationKey::SetVariable(typed_set_variable) => {
61 typed_set_variable.interpret(input)
62 }
63 CdniVerificationKey::CrossoriginPolicy(typed_crossorigin_policy) => {
64 typed_crossorigin_policy.interpret(input)
65 }
66 CdniVerificationKey::None => todo!(),
67 }
68 }
69
70 fn at(&self, stage: Stages) -> bool {
71 match &self {
72 CdniVerificationKey::Stage(typed_stage) => typed_stage.at(stage),
73 CdniVerificationKey::Source(typed_source) => typed_source.at(stage),
74 CdniVerificationKey::SetVariable(typed_set_variable) => typed_set_variable.at(stage),
75 CdniVerificationKey::CrossoriginPolicy(typed_crossorigin_policy) => {
76 typed_crossorigin_policy.at(stage)
77 }
78 CdniVerificationKey::None => todo!(),
79 }
80 }
81}
82
83pub fn interpret_interconnection_metadata(
87 hmd: &HostMetadata<CdniVerificationKey>,
88 mel_scopes: Scopes<TypedValue>,
89 request: Box<dyn prr::Prr<Vec<u8>>>,
90 runtime: &tokio::runtime::Handle,
91 mut log: LogMsgs,
92) -> ImdInterpretResult {
93 let mut request_context = SimpleProcessorsInterpreterContext {
94 scopes: mel_scopes,
95 mode: InterpretMode::Request,
96 runtime,
97 req: request,
98 res: None,
99 };
100
101 for hmd in &hmd.metadata {
103 if hmd.aug.at(Stages::Pre) {
104 (request_context, _) = match hmd.aug.interpret(request_context) {
105 Ok((c, r)) => (c, r),
106 Err(e) => return Err((ImdInterpretError::MetadataProcessingError(e).into(), log)),
107 };
108 }
109 }
110
111 for stage in &hmd.metadata {
113 #[allow(clippy::collapsible_if)]
115 if stage.aug.at(Stages::ClientRequest) {
116 (request_context, _) = match stage.aug.interpret(request_context) {
118 Ok((c, r)) => (c, r),
119 Err(e) => return Err((ImdInterpretError::MetadataProcessingError(e).into(), log)),
120 };
121
122 }
124 }
125
126 if false {
128 todo!("Implement caching.")
129 }
130
131 log = debug!(log, "Start: processing origin request stages.");
132
133 for stage in &hmd.metadata {
135 if stage.aug.at(Stages::OriginRequest) {
137 (request_context, _) = match stage.aug.interpret(request_context) {
139 Ok((c, r)) => (c, r),
140 Err(e) => return Err((ImdInterpretError::MetadataProcessingError(e).into(), log)),
141 };
142 }
143 }
144
145 log = debug!(log, "Stop: processing origin request stages.");
146
147 log = debug!(log, "Start: processing source stages.");
148
149 let mut source_context = SimpleProcessorsInterpreterContext {
150 scopes: request_context.scopes,
151 mode: InterpretMode::Request,
152 req: request_context.req,
153 res: None,
154 runtime: request_context.runtime,
155 };
156
157 let mut source_processor = false;
158
159 for hmd in &hmd.metadata {
160 if hmd.aug.at(Stages::Source) {
162 source_processor = true;
163 (source_context, _) = match hmd.aug.interpret(source_context) {
164 Ok((c, r)) => (c, r),
165 Err(e) => {
166 return Err((ImdInterpretError::MetadataProcessingError(e).into(), log));
167 }
168 };
169 break;
171 }
172 }
173
174 log = debug!(
175 log,
176 &format!(
177 "There was{}a source processor available.",
178 if source_processor { " " } else { " not " }
179 )
180 );
181
182 log = debug!(
183 log,
184 &format!(
185 "There was{}data retrieved by the source processor.",
186 if let Some(res) = &source_context.res
187 && res.tpe() == prr::PrrType::Response
188 {
189 " "
190 } else {
191 " not "
192 }
193 )
194 );
195
196 let mut response_context = SimpleProcessorsInterpreterContext {
199 scopes: source_context.scopes,
200 mode: InterpretMode::Response,
201 req: source_context.req,
202 res: source_context.res,
203 runtime: source_context.runtime,
204 };
205
206 log = debug!(log, "Stop: processing source stages.");
207
208 log = debug!(log, "Start: processing origin response stages.");
209 for stage in &hmd.metadata {
212 if stage.aug.at(Stages::OriginResponse) {
214 let (updated_response_context, result) = match stage.aug.interpret(response_context) {
215 Ok((c, r)) => (c, r),
216 Err(e) => {
217 return Err((ImdInterpretError::MetadataProcessingError(e).into(), log));
218 }
219 };
220
221 if let Some(result) = result.0 {
223 log = debug!(log, "Got a response from an origin response stage.");
224 return Ok((result.status(), result, log));
225 }
226
227 response_context = updated_response_context;
228
229 }
232 }
233 log = debug!(log, "Stop: processing origin response stages.");
234
235 if false {
237 todo!("Implement caching.")
238 }
239
240 log = debug!(log, "Start: processing client response stages.");
241 for stage in &hmd.metadata {
245 if stage.aug.at(Stages::ClientResponse) {
247 let (updated_response_context, result) = match stage.aug.interpret(response_context) {
248 Ok((c, r)) => (c, r),
249 Err(e) => return Err((ImdInterpretError::MetadataProcessingError(e).into(), log)),
250 };
251
252 if let Some(result) = result.0 {
254 log = debug!(log, "Got a response from an origin response stage.");
255 return Ok((result.status(), result, log));
256 }
257
258 response_context = updated_response_context;
262 }
263 }
264
265 log = debug!(log, "Stop: processing client response stages.");
266
267 log = debug!(log, "Start: processing post stages.");
268
269 for stage in &hmd.metadata {
273 if stage.aug.at(Stages::Post) {
275 let (updated_response_context, _) = match stage.aug.interpret(response_context) {
276 Ok((c, r)) => (c, r),
277 Err(e) => return Err((ImdInterpretError::MetadataProcessingError(e).into(), log)),
278 };
279
280 response_context = updated_response_context;
284 }
285 }
286 log = debug!(log, "Stop: processing post stages.");
287
288 log = debug!(log, "Trying to convert a response into a response!");
289
290 let processed_http_response = match response_context.res {
291 Some(res) => res,
292 None => todo!(),
293 };
294 let interpreted_http_response: http::Response<Vec<u8>> =
295 match (&*processed_http_response as &dyn prr::Prr<Vec<u8>>).try_into() {
296 Ok(o) => o,
297 Err(e) => {
298 return Err((ImdInterpretError::TransformError(e.into()).into(), log));
299 }
300 };
301
302 log = debug!(
303 log,
304 &format!("Response code: {}", interpreted_http_response.status())
305 );
306
307 Ok((
308 interpreted_http_response.status(),
309 interpreted_http_response,
310 log,
311 ))
312}