1use std::error;
21use std::fmt::{Debug, Display};
22use std::str::FromStr;
23
24use crate::cdni::gmd::spec::TypedGenericMetadata;
25use crate::cdni::ps::spec::{
26 TypedClientRequestStage, TypedClientResponseStage, TypedExpressionMatch, TypedHeader,
27 TypedHeaderTransform, TypedMatchGroup, TypedOriginRequestStage, TypedOriginResponseStage,
28 TypedProcessingStages, TypedRequestTransform, TypedResponseTransform, TypedStage,
29 TypedStageMetadata, TypedStageRules, TypedSyntheticResponse,
30};
31use crate::dcdn::imdi;
32use crate::dcdn::interpret::Stages::{
33 ClientRequest, ClientResponse, OriginRequest, OriginResponse,
34};
35use crate::dcdn::interpret::{
36 Error, MetadataInformationResultElement, MetadataInformationResultElements, Stages,
37};
38use crate::dcdn::processors::SimpleProcessorsInterpreterContext;
39use crate::environment::scope::Scopes;
40use crate::logging::LogMsgs;
41use crate::mel::analysis::Analyzed;
42use crate::mel::ast::Expr;
43use crate::mel::interpreter::error::{
44 InterpAssertion as MelInterpAssertion, InterpError as MelInterpError,
45 InterpLocatableError as MelInterpLocatableError,
46};
47use crate::mel::interpreter::interpret::MelInterpContext;
48use crate::mel::interpreter::values::{TypedValue, Value};
49use crate::mel::types::Type;
50use crate::processing::interpret::{self, Interpreter};
51use crate::verifying::ps::verify::PsVerificationKey;
52use crate::visitors::{PsVisitor, PsVisitorResult};
53use crate::{mel, prr};
54
55pub type PsInterpretResult =
56 Result<(PsInterpretValue, MetadataInformationResultElements), Box<PsInterpretError>>;
57
58#[derive(Debug, Clone)]
59pub enum PsInterpretAssertionFailures {
60 MissingAnalyzedExpression,
61 MissingInterpreterExpressionValue,
62 InvalidInterpreterMode,
63 MissingResult,
64}
65
66impl Display for PsInterpretAssertionFailures {
67 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
68 match self {
69 PsInterpretAssertionFailures::MissingAnalyzedExpression => {
70 write!(f, "Missing information about an analyzed expression")
71 }
72 PsInterpretAssertionFailures::MissingInterpreterExpressionValue => {
73 write!(f, "Missing value from an interpreted expression")
74 }
75 PsInterpretAssertionFailures::InvalidInterpreterMode => {
76 write!(f, "Invalid interpreter mode")
77 }
78 PsInterpretAssertionFailures::MissingResult => write!(f, "Missing result"),
79 }
80 }
81}
82
83#[derive(Debug, Default)]
84pub enum PsInterpretError {
85 #[default]
86 NoError,
87 AssertionFailure(PsInterpretAssertionFailures),
88 MelInterpreterError(Box<MelInterpLocatableError>),
89 InvalidRequest,
90 InvalidUri(url::ParseError),
91 InvalidResponse(String),
92 WrongType(PsInterpretValueType, PsInterpretValueType),
93 WrongMatchGroupValueType(PsInterpretValueType),
94 ProcessableRequestResponseError(prr::Error),
95}
96
97impl error::Error for PsInterpretError {}
98
99impl Display for PsInterpretError {
100 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
101 match self {
102 PsInterpretError::NoError => write!(f, "No Error"),
103 PsInterpretError::AssertionFailure(af) => {
104 write!(f, "Assertion failure: {af}")
105 }
106 PsInterpretError::MelInterpreterError(meli) => {
107 write!(f, "MEL Interpreter error: {}", meli)
108 }
109 PsInterpretError::InvalidRequest => write!(f, "Invalid HTTP request"),
110 PsInterpretError::InvalidUri(iuri) => write!(f, "Invalid URI: {iuri}"),
111 PsInterpretError::InvalidResponse(response) => {
112 write!(f, "Invalid Response: {response}")
113 }
114 PsInterpretError::WrongType(expected, actual) => {
115 write!(f, "Wrong type: expected: {expected} actual: {actual}",)
116 }
117 PsInterpretError::WrongMatchGroupValueType(actual) => {
118 write!(f, "Match group value should not have {actual} type")
119 }
120 PsInterpretError::ProcessableRequestResponseError(
121 processable_request_response_error,
122 ) => {
123 write!(
124 f,
125 "Error occurred when modifying the request/response: {processable_request_response_error}"
126 )
127 }
128 }
129 }
130}
131
132pub(crate) struct PsInterpreter<'a> {
135 pub rr: &'a mut dyn prr::Prr<Vec<u8>>,
136}
137
138impl<'a> PsInterpreter<'a> {
139 pub fn install_generic_visitors(&mut self) {}
140
141 fn evaluate_mel_expr(
142 &self,
143 mel_scopes: Scopes<TypedValue>,
144 expr: &Expr<Analyzed>,
145 expected: Type,
146 ) -> Result<TypedValue, PsInterpretError> {
147 let expr_context = MelInterpContext {
148 val: None,
149 scopes: mel_scopes,
150 log: LogMsgs::new(crate::logging::LogLevel::Trace),
151 };
152
153 let result_ctxt = mel::interpreter::interpret(expr, expr_context)
154 .map_err(PsInterpretError::MelInterpreterError)?;
155
156 let result_val = result_ctxt
157 .val
158 .as_ref()
159 .ok_or(PsInterpretError::AssertionFailure(
160 PsInterpretAssertionFailures::MissingInterpreterExpressionValue,
161 ))?;
162
163 if result_val.tpe == expected {
164 Ok(result_val.clone())
165 } else {
166 Err(PsInterpretError::MelInterpreterError(
167 MelInterpLocatableError {
168 error: MelInterpError::Assertion(
169 MelInterpAssertion::TypeMismatch(expected, result_val.tpe.clone()).into(),
170 )
171 .into(),
172 context: result_ctxt,
173 location: expr.location().clone(),
174 }
175 .into(),
176 ))
177 }
178 }
179
180 fn interpret_match_groups_in_stage(
181 &mut self,
182 mgs: &Vec<TypedMatchGroup<PsVerificationKey>>,
183 mut c: PsInterpretContext,
184 ) -> PsVisitorResult<PsInterpretContext, PsInterpretError> {
185 for mg in mgs {
186 c = self.visit_match_group(mg, c)?;
187 match c.result {
188 Some(PsInterpretValue::Terminate | PsInterpretValue::SyntheticResponse(_)) => {
189 break;
191 }
192 Some(PsInterpretValue::MatchYes | PsInterpretValue::MatchNo) => {
193 continue;
195 }
196 Some(r) => {
197 return Err(PsInterpretError::WrongType(
198 PsInterpretValueType::Terminate,
199 r.into(),
200 ));
201 }
202 None => {
203 return Err(PsInterpretError::AssertionFailure(
204 PsInterpretAssertionFailures::MissingResult,
205 ));
206 }
207 }
208 }
209 if let Some(result) = c.result {
210 Ok(PsInterpretContext {
211 mode: c.mode,
212 result: Some(result.clone()),
213 metadata: c.metadata,
214 mel_scopes: c.mel_scopes,
215 })
216 } else {
217 Err(PsInterpretError::AssertionFailure(
218 PsInterpretAssertionFailures::MissingResult,
219 ))
220 }
221 }
222}
223
224#[derive(Debug, Clone, Default, PartialEq)]
225pub enum PsInterpretMode {
226 Request,
227 Response,
228 HeaderAdd,
229 HeaderReplace,
230 HeaderCalculate,
231 #[default]
232 None,
233}
234
235impl From<imdi::InterpretMode> for PsInterpretMode {
236 fn from(value: imdi::InterpretMode) -> Self {
237 match value {
238 imdi::InterpretMode::Request => PsInterpretMode::Request,
239 imdi::InterpretMode::Response => PsInterpretMode::Response,
240 }
241 }
242}
243
244#[derive(Debug, Clone)]
245pub enum PsInterpretValueType {
246 SyntheticResponse,
247 Terminate,
248 MatchResult,
249 Header,
250}
251
252impl Display for PsInterpretValueType {
253 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
254 match &self {
255 PsInterpretValueType::SyntheticResponse => write!(f, "Synthetic response"),
256 PsInterpretValueType::Terminate => write!(f, "Terminate"),
257 PsInterpretValueType::MatchResult => write!(f, "Match result"),
258 PsInterpretValueType::Header => write!(f, "Header"),
259 }
260 }
261}
262
263#[derive(Debug, Clone)]
264pub enum PsInterpretValue {
265 SyntheticResponse(http::Response<Vec<u8>>),
266 Terminate,
267 MatchYes,
268 MatchNo,
269 Header(String, String),
270}
271
272impl From<PsInterpretValue> for PsInterpretValueType {
273 fn from(value: PsInterpretValue) -> Self {
274 match value {
275 PsInterpretValue::SyntheticResponse(_) => PsInterpretValueType::SyntheticResponse,
276 PsInterpretValue::Terminate => PsInterpretValueType::Terminate,
277 PsInterpretValue::MatchYes | PsInterpretValue::MatchNo => {
278 PsInterpretValueType::MatchResult
279 }
280 PsInterpretValue::Header(_, _) => PsInterpretValueType::Header,
281 }
282 }
283}
284
285impl From<bool> for PsInterpretValue {
286 fn from(value: bool) -> Self {
287 if value {
288 PsInterpretValue::MatchYes
289 } else {
290 PsInterpretValue::MatchNo
291 }
292 }
293}
294
295#[derive(Debug, Default)]
296pub(crate) struct PsInterpretContext {
297 pub mode: PsInterpretMode,
298 pub result: Option<PsInterpretValue>,
299 pub metadata: MetadataInformationResultElements,
300 pub mel_scopes: Scopes<TypedValue>,
301}
302
303impl PsInterpretContext {
304 fn update_mode(self, new_mode: PsInterpretMode) -> PsInterpretContext {
305 let mut nc = self;
306 nc.mode = new_mode;
307 nc
308 }
309 fn update_result(self, new_result: Option<PsInterpretValue>) -> PsInterpretContext {
310 let mut nc = self;
311 nc.result = new_result;
312 nc
313 }
314
315 fn update_metadata_elements(
316 self,
317 new_element: Box<dyn MetadataInformationResultElement>,
318 ) -> PsInterpretContext {
319 let mut nc = self;
320 nc.metadata.elements.push(new_element);
321 nc
322 }
323 fn replace_metadata_elements(
324 self,
325 new_elements: MetadataInformationResultElements,
326 ) -> PsInterpretContext {
327 let mut nc = self;
328 nc.metadata = new_elements;
329 nc
330 }
331}
332
333impl<'a> PsVisitor<PsVerificationKey, PsInterpretContext, PsInterpretContext, PsInterpretError>
334 for PsInterpreter<'a>
335{
336 fn visit_processing_stages(
337 &mut self,
338 _v: &TypedProcessingStages<PsVerificationKey>,
339 _c: PsInterpretContext,
340 ) -> PsVisitorResult<PsInterpretContext, PsInterpretError> {
341 todo!()
342 }
343
344 fn visit_stage_rules(
345 &mut self,
346 v: &TypedStageRules<PsVerificationKey>,
347 c: PsInterpretContext,
348 ) -> PsVisitorResult<PsInterpretContext, PsInterpretError> {
349 let doq = if let Some(mtch) = &v.value.mtch {
350 let expr = match &mtch.value.aug {
351 PsVerificationKey::Expr(expr) => expr,
352 _ => {
353 return Err(PsInterpretError::AssertionFailure(
354 PsInterpretAssertionFailures::MissingAnalyzedExpression,
355 ));
356 }
357 };
358 let result = self.evaluate_mel_expr(c.mel_scopes.clone(), expr, Type::Boolean)?;
359 match result {
360 TypedValue {
361 tpe: Type::Boolean,
362 value: Value::Boolean(v),
363 } => v,
364 _ => unreachable!(),
365 }
366 } else {
367 true
368 };
369
370 if doq {
371 self.visit_stage_metadata(&v.value.stage_metadata, c.update_result(Some(doq.into())))
372 } else {
373 Ok(c.update_result(Some(doq.into())))
374 }
375 }
376
377 fn visit_expression_match(
378 &mut self,
379 _v: &TypedExpressionMatch<PsVerificationKey>,
380 _c: PsInterpretContext,
381 ) -> PsVisitorResult<PsInterpretContext, PsInterpretError> {
382 todo!()
383 }
384
385 fn visit_stage_metadata(
386 &mut self,
387 v: &TypedStageMetadata<PsVerificationKey>,
388 mut c: PsInterpretContext,
389 ) -> PsVisitorResult<PsInterpretContext, PsInterpretError> {
390 if let Some(generic) = &v.value.generic {
391 for generic in generic {
392 c = self.visit_generic_metadata(generic, c)?;
393 }
394 }
395
396 match &c.mode {
397 PsInterpretMode::Request => {
398 if let Some(req_xform) = &v.value.request_xform {
399 return self.visit_request_transform(req_xform, c);
400 }
401 }
402 PsInterpretMode::Response => {
403 if let Some(res_xform) = &v.value.response_xform {
404 return self.visit_response_transform(res_xform, c);
405 }
406 }
407 _ => {
408 return Err(PsInterpretError::AssertionFailure(
409 PsInterpretAssertionFailures::InvalidInterpreterMode,
410 ));
411 }
412 }
413 Ok(c)
414 }
415
416 fn visit_request_transform(
417 &mut self,
418 v: &TypedRequestTransform<PsVerificationKey>,
419 mut c: PsInterpretContext,
420 ) -> PsVisitorResult<PsInterpretContext, PsInterpretError> {
421 if let Some(header_xform) = &v.value.xform {
422 c = self.visit_header_transform(
423 header_xform,
424 PsInterpretContext {
425 mode: PsInterpretMode::Request,
426 metadata: c.metadata,
427 result: c.result.clone(),
428 mel_scopes: c.mel_scopes,
429 },
430 )?;
431 }
432
433 if let Some(new_uri) = &v.value.uri {
434 let new_uri = if let Some(uri_is_expr) = &v.value.uri_is_expr
435 && *uri_is_expr
436 {
437 let expr = match &v.value.aug {
438 PsVerificationKey::Expr(expr) => expr,
439 _ => {
440 return Err(PsInterpretError::AssertionFailure(
441 PsInterpretAssertionFailures::MissingAnalyzedExpression,
442 ));
443 }
444 };
445 let result = self.evaluate_mel_expr(c.mel_scopes.clone(), expr, Type::String)?;
446 match result {
447 TypedValue {
448 tpe: Type::String,
449 value: Value::String(s),
450 } => url::Url::from_str(&s),
451 _ => unreachable!(),
452 }
453 } else {
454 url::Url::from_str(&new_uri.clone())
455 }
456 .map_err(PsInterpretError::InvalidUri)?;
457
458 self.rr
459 .set_url(&new_uri)
460 .map_err(PsInterpretError::ProcessableRequestResponseError)?
461 }
462
463 Ok(c)
464 }
465
466 fn visit_response_transform(
467 &mut self,
468 v: &TypedResponseTransform<PsVerificationKey>,
469 mut c: PsInterpretContext,
470 ) -> PsVisitorResult<PsInterpretContext, PsInterpretError> {
471 if let Some(synthetic_response) = &v.value.synthetic {
472 return self.visit_synthetic_response(synthetic_response, c);
473 }
474
475 if let Some(header_xform) = &v.value.xform {
476 c = self
477 .visit_header_transform(header_xform, c.update_mode(PsInterpretMode::Response))?;
478 }
479
480 if let Some(new_response) = &v.value.response_status {
481 let new_response = if let Some(response_is_expr) = &v.value.response_status_expr
482 && *response_is_expr
483 {
484 let expr = match &v.value.aug {
485 PsVerificationKey::Expr(expr) => expr,
486 _ => {
487 return Err(PsInterpretError::AssertionFailure(
488 PsInterpretAssertionFailures::MissingAnalyzedExpression,
489 ));
490 }
491 };
492 let result = self.evaluate_mel_expr(c.mel_scopes.clone(), expr, Type::Integer)?;
493 match result {
494 TypedValue {
495 tpe: Type::Integer,
496 value: Value::Integer(i),
497 } => Ok(i),
498 _ => unreachable!(),
499 }
500 } else {
501 new_response.parse::<i64>()
502 }
503 .map_err(|e| PsInterpretError::InvalidResponse(e.to_string()))?;
504 let new_response = u16::try_from(new_response).map_err(|e| {
505 PsInterpretError::InvalidResponse(format!(
506 "Could not convert {new_response} to unsigned 16-bit number: {e}"
507 ))
508 })?;
509 self.rr.set_status(&new_response).map_err(|_| {
510 PsInterpretError::ProcessableRequestResponseError(prr::Error::BadValue(
511 prr::Value {
512 tpe: prr::ValueType::Status,
513 value: Some(new_response.to_string()),
514 },
515 ))
516 })?;
517 }
518
519 Ok(c)
520 }
521
522 fn visit_generic_metadata(
523 &mut self,
524 _v: &TypedGenericMetadata<PsVerificationKey>,
525 _c: PsInterpretContext,
526 ) -> PsVisitorResult<PsInterpretContext, PsInterpretError> {
527 todo!()
528 }
529
530 fn visit_header_transform(
531 &mut self,
532 v: &TypedHeaderTransform<PsVerificationKey>,
533 mut c: PsInterpretContext,
534 ) -> PsVisitorResult<PsInterpretContext, PsInterpretError> {
535 if let Some(to_delete) = &v.value.delete {
536 for htr in to_delete {
537 self.rr
538 .remove_header(htr)
539 .map_err(PsInterpretError::ProcessableRequestResponseError)?
540 }
541 }
542
543 if let Some(to_add) = &v.value.add {
544 for htr in to_add {
545 c = self.visit_header(htr, c.update_mode(PsInterpretMode::HeaderAdd))?;
546 }
547 }
548
549 if let Some(to_replace) = &v.value.replace {
550 for htr in to_replace {
551 c = self.visit_header(htr, c.update_mode(PsInterpretMode::HeaderReplace))?;
552 }
553 }
554
555 Ok(c)
556 }
557
558 fn visit_header(
559 &mut self,
560 v: &TypedHeader<PsVerificationKey>,
561 c: PsInterpretContext,
562 ) -> PsVisitorResult<PsInterpretContext, PsInterpretError> {
563 let value = if let Some(expr) = &v.value.value_expr
564 && *expr
565 {
566 let expr = match &v.value.aug {
567 PsVerificationKey::Expr(expr) => expr,
568 _ => {
569 return Err(PsInterpretError::AssertionFailure(
570 PsInterpretAssertionFailures::MissingAnalyzedExpression,
571 ));
572 }
573 };
574 let result = self.evaluate_mel_expr(c.mel_scopes.clone(), expr, Type::String)?;
575 match result {
576 TypedValue {
577 tpe: Type::String,
578 value: Value::String(s),
579 } => s,
580 _ => unreachable!(),
581 }
582 } else {
583 v.value.value.clone()
584 };
585
586 match c.mode {
587 PsInterpretMode::HeaderAdd => {
588 self.rr
589 .add_header(&v.value.name, &value)
590 .map_err(PsInterpretError::ProcessableRequestResponseError)?;
591 Ok(c)
592 }
593 PsInterpretMode::HeaderReplace => {
594 self.rr
595 .set_header_value(&v.value.name, &value)
596 .map_err(PsInterpretError::ProcessableRequestResponseError)?;
597 Ok(c)
598 }
599 PsInterpretMode::HeaderCalculate => {
600 Ok(c.update_result(Some(PsInterpretValue::Header(v.value.name.clone(), value))))
601 }
602 _ => todo!(),
603 }
604 }
605
606 fn visit_synthetic_response(
607 &mut self,
608 v: &TypedSyntheticResponse<PsVerificationKey>,
609 mut c: PsInterpretContext,
610 ) -> PsVisitorResult<PsInterpretContext, PsInterpretError> {
611 let mut response = http::Response::builder();
612
613 if let Some(headers) = &v.value.headers {
614 for header in headers {
615 c = self.visit_header(header, c.update_mode(PsInterpretMode::HeaderCalculate))?;
618
619 match &c.result {
620 Some(PsInterpretValue::Header(name, value)) => {
621 response.headers_mut().unwrap().insert(
622 http::HeaderName::from_bytes(name.as_bytes()).expect("Todo"),
623 http::HeaderValue::from_str(value).expect("Todo"),
624 );
625 }
626 Some(r) => {
627 return Err(PsInterpretError::WrongType(
628 PsInterpretValueType::Header,
629 r.clone().into(),
630 ));
631 }
632 None => {
633 return Err(PsInterpretError::AssertionFailure(
634 PsInterpretAssertionFailures::MissingAnalyzedExpression,
635 ));
636 }
637 }
638 }
639 }
640
641 response = response.status(if let Some(new_response) = &v.value.response_status {
642 if let Some(response_is_expr) = &v.value.response_status_expr
643 && *response_is_expr
644 {
645 let expr = match &v.value.aug {
646 PsVerificationKey::ExprPair(Some(expr), _) => expr,
647 _ => {
648 return Err(PsInterpretError::AssertionFailure(
649 PsInterpretAssertionFailures::MissingAnalyzedExpression,
650 ));
651 }
652 };
653 let result = self.evaluate_mel_expr(c.mel_scopes.clone(), expr, Type::Integer)?;
654 match result {
655 TypedValue {
656 tpe: Type::Integer,
657 value: Value::Integer(i),
658 } => http::StatusCode::from_u16(i as u16),
659 _ => unreachable!(),
660 }
661 } else {
662 new_response.parse::<http::StatusCode>()
663 }
664 .map_err(|e| PsInterpretError::InvalidResponse(e.to_string()))?
665 } else {
666 http::StatusCode::OK
667 });
668
669 let response = response
670 .body(if let Some(body) = &v.value.body {
671 if let Some(body_is_expr) = &v.value.body_expr
672 && *body_is_expr
673 {
674 let expr = match &v.value.aug {
675 PsVerificationKey::ExprPair(_, Some(expr)) => expr,
676 _ => {
677 return Err(PsInterpretError::AssertionFailure(
678 PsInterpretAssertionFailures::MissingAnalyzedExpression,
679 ));
680 }
681 };
682 let result =
683 self.evaluate_mel_expr(c.mel_scopes.clone(), expr, Type::String)?;
684 match result {
685 TypedValue {
686 tpe: Type::String,
687 value: Value::String(s),
688 } => s.into_bytes(),
689 _ => unreachable!(),
690 }
691 } else {
692 body.to_owned().into_bytes()
693 }
694 } else {
695 "".to_string().into_bytes()
696 })
697 .expect("Could not create HTTP response");
698
699 Ok(c.update_result(Some(PsInterpretValue::SyntheticResponse(response))))
700 }
701
702 fn visit_match_group(
703 &mut self,
704 v: &TypedMatchGroup<PsVerificationKey>,
705 mut c: PsInterpretContext,
706 ) -> PsVisitorResult<PsInterpretContext, PsInterpretError> {
707 let else_ifs = v
708 .value
709 .else_ifs
710 .as_ref()
711 .map(|else_ifs| else_ifs.iter())
712 .unwrap_or([].iter());
713
714 let rules = [&v.value.if_rule].into_iter().chain(else_ifs);
715 for r in rules {
716 c = self.visit_stage_rules(r, c)?;
717 match &c.result {
718 Some(PsInterpretValue::MatchNo) => {
719 continue; }
721 Some(_) => {
722 break; }
724 None => {
725 return Err(PsInterpretError::AssertionFailure(
726 PsInterpretAssertionFailures::MissingResult,
727 ));
728 }
729 };
730 }
731 if let Some(result) = &c.result {
732 Ok(PsInterpretContext {
733 mode: c.mode,
734 result: Some(result.clone()),
735 metadata: c.metadata,
736 mel_scopes: c.mel_scopes,
737 })
738 } else {
739 Err(PsInterpretError::AssertionFailure(
740 PsInterpretAssertionFailures::MissingResult,
741 ))
742 }
743 }
744
745 fn visit_client_request_stage(
746 &mut self,
747 v: &TypedClientRequestStage<PsVerificationKey>,
748 c: PsInterpretContext,
749 ) -> PsVisitorResult<PsInterpretContext, PsInterpretError> {
750 self.interpret_match_groups_in_stage(&v.value.match_groups, c)
751 }
752
753 fn visit_origin_request_stage(
754 &mut self,
755 v: &TypedOriginRequestStage<PsVerificationKey>,
756 c: PsInterpretContext,
757 ) -> PsVisitorResult<PsInterpretContext, PsInterpretError> {
758 self.interpret_match_groups_in_stage(&v.value.match_groups, c)
759 }
760
761 fn visit_client_response_stage(
762 &mut self,
763 v: &TypedClientResponseStage<PsVerificationKey>,
764 c: PsInterpretContext,
765 ) -> PsVisitorResult<PsInterpretContext, PsInterpretError> {
766 self.interpret_match_groups_in_stage(&v.value.match_groups, c)
767 }
768
769 fn visit_origin_response_stage(
770 &mut self,
771 v: &TypedOriginResponseStage<PsVerificationKey>,
772 c: PsInterpretContext,
773 ) -> PsVisitorResult<PsInterpretContext, PsInterpretError> {
774 self.interpret_match_groups_in_stage(&v.value.match_groups, c)
775 }
776}
777
778pub fn interpret_stage(
780 ts: &TypedStage<PsVerificationKey>,
781 mel_scopes: &Scopes<TypedValue>,
782 reqres: &mut dyn prr::Prr<Vec<u8>>,
783 mode: PsInterpretMode,
784) -> PsInterpretResult {
785 let mut visitor = PsInterpreter { rr: reqres };
786
787 visitor.install_generic_visitors();
788
789 let context = PsInterpretContext {
790 mel_scopes: mel_scopes.clone(),
791 mode,
792 ..Default::default()
793 };
794
795 let result = match ts {
796 TypedStage::ClientRequest(typed_client_request_stage) => {
797 visitor.visit_client_request_stage(typed_client_request_stage, context)
798 }
799 TypedStage::ClientResponse(typed_client_response_stage) => {
800 visitor.visit_client_response_stage(typed_client_response_stage, context)
801 }
802 TypedStage::OriginRequest(typed_origin_request_stage) => {
803 visitor.visit_origin_request_stage(typed_origin_request_stage, context)
804 }
805 TypedStage::OriginResponse(typed_origin_response_stage) => {
806 visitor.visit_origin_response_stage(typed_origin_response_stage, context)
807 }
808 }?;
809
810 let md = result.metadata;
811 let result = result
812 .result
813 .ok_or(Box::new(PsInterpretError::AssertionFailure(
814 PsInterpretAssertionFailures::MissingResult,
815 )))?;
816 Ok((result, md))
817}
818
819#[derive(Debug)]
820pub(crate) enum EffectfulRequestActions {
821 DeleteHeader(String),
822 AddHeader(String, String),
823 ClearHeaders,
824 SetUri(String),
825 SetBody,
826 SetResponse(u16),
827}
828
829#[derive(Debug)]
830pub(crate) struct EffectfulProcessableRequestResponse {
831 log: Vec<EffectfulRequestActions>,
832 tpe: prr::PrrType,
833}
834
835impl EffectfulProcessableRequestResponse {
836 fn new_request() -> Self {
837 EffectfulProcessableRequestResponse {
838 log: Default::default(),
839 tpe: prr::PrrType::Request,
840 }
841 }
842
843 fn new_response() -> Self {
844 EffectfulProcessableRequestResponse {
845 log: Default::default(),
846 tpe: prr::PrrType::Response,
847 }
848 }
849}
850
851impl prr::Prr<Vec<u8>> for EffectfulProcessableRequestResponse {
852 fn headers(&self) -> Vec<(String, http::HeaderValue)> {
853 vec![]
854 }
855
856 fn set_header_value(&mut self, _header: &str, _value: &str) -> Result<(), prr::Error> {
857 Ok(())
858 }
859
860 fn clear_headers(&mut self) -> prr::Result<()> {
861 self.log.push(EffectfulRequestActions::ClearHeaders);
862 Ok(())
863 }
864
865 fn remove_header(&mut self, header: &str) -> Result<(), prr::Error> {
866 self.log
867 .push(EffectfulRequestActions::DeleteHeader(header.to_string()));
868 Ok(())
869 }
870
871 fn url(&self) -> Result<url::Url, prr::Error> {
872 Ok(url::Url::from_str("http://www.example.com/").expect("Could not make default URL"))
873 }
874
875 fn set_url(&mut self, url: &url::Url) -> Result<(), prr::Error> {
876 self.log
877 .push(EffectfulRequestActions::SetUri(url.to_string()));
878 Ok(())
879 }
880
881 fn set_status(&mut self, response: &u16) -> Result<(), prr::Error> {
882 self.log
883 .push(EffectfulRequestActions::SetResponse(*response));
884 Ok(())
885 }
886
887 fn add_header(&mut self, header: &str, value: &str) -> Result<(), prr::Error> {
888 self.log.push(EffectfulRequestActions::AddHeader(
889 header.to_string(),
890 value.to_string(),
891 ));
892 Ok(())
893 }
894
895 fn set_body(&mut self, _: &Vec<u8>) -> prr::Result<()> {
896 self.log.push(EffectfulRequestActions::SetBody);
897 Ok(())
898 }
899
900 fn get_body(&self) -> prr::Result<&Vec<u8>> {
901 todo!()
902 }
903
904 fn get_status(&self) -> prr::Result<http::StatusCode> {
905 todo!()
906 }
907
908 fn tpe(&self) -> prr::PrrType {
909 self.tpe.clone()
910 }
911
912 fn set_method(&mut self, _method: &http::Method) -> prr::Result<()> {
913 todo!()
914 }
915
916 fn get_method(&self) -> http::Method {
917 todo!()
918 }
919}
920
921impl
922 Interpreter<
923 SimpleProcessorsInterpreterContext<'_>,
924 (imdi::ResultValue, MetadataInformationResultElements),
925 Stages,
926 Error,
927 > for TypedStage<PsVerificationKey>
928{
929 fn interpret<'a>(
930 &self,
931 input: SimpleProcessorsInterpreterContext<'a>,
932 ) -> interpret::InterpretationResult<
933 SimpleProcessorsInterpreterContext<'a>,
934 (imdi::ResultValue, MetadataInformationResultElements),
935 Error,
936 > {
937 let (mut res, mut req) = (input.res, input.req);
938 let reqres = match input.mode {
939 imdi::InterpretMode::Request => &mut req,
940 imdi::InterpretMode::Response => {
941 if let Some(res) = &mut res {
942 res
943 } else {
944 return Err(Error::RuntimeError(
945 Error::AssertionFailure("Missing request".into()).into(),
946 )
947 .into());
948 }
949 }
950 };
951
952 let mut visitor = PsInterpreter { rr: &mut **reqres };
953
954 visitor.install_generic_visitors();
955
956 let context = PsInterpretContext {
957 mode: input.mode.clone().into(),
958 mel_scopes: input.scopes.clone(),
959 ..Default::default()
960 };
961
962 let result = match self {
963 TypedStage::ClientRequest(typed_client_request_stage) => {
964 visitor.visit_client_request_stage(typed_client_request_stage, context)
965 }
966 TypedStage::ClientResponse(typed_client_response_stage) => {
967 visitor.visit_client_response_stage(typed_client_response_stage, context)
968 }
969 TypedStage::OriginRequest(typed_origin_request_stage) => {
970 visitor.visit_origin_request_stage(typed_origin_request_stage, context)
971 }
972 TypedStage::OriginResponse(typed_origin_response_stage) => {
973 visitor.visit_origin_response_stage(typed_origin_response_stage, context)
974 }
975 }
976 .map_err(|e| Error::RuntimeError(e.into()))?;
977
978 let md = result.metadata;
979 let result = result.result.ok_or(Error::RuntimeError(
980 PsInterpretError::AssertionFailure(PsInterpretAssertionFailures::MissingResult).into(),
981 ))?;
982
983 let result = match result {
986 PsInterpretValue::SyntheticResponse(sr) => Some(sr),
987 _ => None,
988 };
989
990 let updated_context = SimpleProcessorsInterpreterContext {
991 scopes: input.scopes,
992 mode: input.mode,
993 runtime: input.runtime,
994 req,
995 res,
996 };
997 Ok((updated_context, (result, md)))
998 }
999
1000 fn at(&self, stage: Stages) -> bool {
1001 match &self {
1002 TypedStage::ClientRequest(_) => stage == ClientRequest || stage == ClientResponse,
1004 TypedStage::OriginRequest(_) => stage == OriginRequest || stage == OriginResponse,
1005 TypedStage::ClientResponse(_) => stage == ClientResponse,
1006 TypedStage::OriginResponse(_) => stage == OriginResponse,
1007 }
1008 }
1009}
1010
1011#[cfg(test)]
1012mod ps_interpreter_tests {
1013 use crate::{
1014 cdni::{
1015 ps::spec::{TypedGenericStage, TypedStage},
1016 tests::test_helpers::{
1017 client_request_stage, expression_match, match_group, request_transform,
1018 response_transform, stage_metadata, synthetic_response, typed_header,
1019 typed_stage_rule,
1020 },
1021 },
1022 dcdn::processors::ps::{
1023 EffectfulProcessableRequestResponse, EffectfulRequestActions, PsInterpretMode,
1024 PsInterpretValue, interpret_stage,
1025 },
1026 environment::scope::Scopes,
1027 mel::types::Type,
1028 tests::read_test_file,
1029 verifying::ps::verify::{PsVerifierContextValue, verifier, verify_ps_request_stage},
1030 visitors::PsVisitor,
1031 };
1032 use std::assert_matches;
1033 use std::path::Path;
1034
1035 #[test]
1036 fn test_interpret_client_request_stage() {
1037 let json = read_test_file(Path::new(
1038 "./tests/data/processing/client_request_stage/if.json",
1039 ));
1040
1041 let result = serde_json::from_str::<TypedGenericStage>(&json)
1042 .expect("Could not deserialize simple client request stage JSON");
1043
1044 let result = verify_ps_request_stage(&result, &Scopes::<Type>::default())
1045 .expect("Could not verify valid client request stage JSON");
1046
1047 let mut req = EffectfulProcessableRequestResponse::new_request();
1048 let result = interpret_stage(
1049 &result,
1050 &Scopes { scopes: vec![] },
1051 &mut req,
1052 PsInterpretMode::Request,
1053 )
1054 .expect("Could not interpret a valid client request");
1055
1056 assert_eq!(req.log.len(), 2);
1057 assert_matches!(req.log[0], EffectfulRequestActions::DeleteHeader(_));
1058 assert_matches!(req.log[1], EffectfulRequestActions::AddHeader(_, _));
1059 assert_matches!(result.0, PsInterpretValue::MatchYes);
1060 }
1061
1062 #[test]
1063 fn test_interpret_client_request_stage_request_response_header_transform() {
1064 let json = read_test_file(Path::new(
1065 "./tests/data/processing/client_request_stage/request_response_header_transform.json",
1066 ));
1067
1068 let result = serde_json::from_str::<TypedGenericStage>(&json)
1069 .expect("Could not deserialize simple client request stage JSON");
1070
1071 let result = verify_ps_request_stage(&result, &Scopes::<Type>::default())
1072 .expect("Could not verify valid client request stage JSON");
1073 let mut req = EffectfulProcessableRequestResponse::new_request();
1074 let result = interpret_stage(
1075 &result,
1076 &Scopes { scopes: vec![] },
1077 &mut req,
1078 PsInterpretMode::Request,
1079 )
1080 .expect("Could not interpret a valid client request");
1081
1082 assert_eq!(req.log.len(), 2);
1083 assert_matches!(req.log[0], EffectfulRequestActions::DeleteHeader(_));
1084 assert_matches!(req.log[1], EffectfulRequestActions::AddHeader(_, _));
1085 assert_matches!(result.0, PsInterpretValue::MatchYes);
1086 }
1087
1088 #[test]
1089 fn test_interpret_client_request_stage_request_uri_transform() {
1090 let mut request_xform_stage = stage_metadata();
1091
1092 let request_xform_match = expression_match("true");
1093 let request_xform = request_transform(
1094 None,
1095 Some("\"http://\" . \"example.com\"".to_string()),
1096 Some(true),
1097 );
1098 request_xform_stage.value.request_xform = Some(request_xform);
1099
1100 let request_xform_mg = match_group(
1101 typed_stage_rule(Some(request_xform_match), request_xform_stage),
1102 None,
1103 );
1104
1105 let crs = client_request_stage(vec![request_xform_mg]);
1106
1107 let (mut verifier, context) = verifier();
1108
1109 let result = verifier
1110 .visit_client_request_stage(&crs, context)
1111 .expect("Could not verify valid client request")
1112 .value
1113 .expect("Could not get value from verified client request");
1114
1115 let value = match result {
1116 PsVerifierContextValue::ClientRequestStage(typed_client_request_stage) => {
1117 typed_client_request_stage
1118 }
1119 _ => todo!(),
1120 };
1121 let mut req = EffectfulProcessableRequestResponse::new_request();
1122 let result = interpret_stage(
1123 &TypedStage::ClientRequest(value),
1124 &Scopes { scopes: vec![] },
1125 &mut req,
1126 PsInterpretMode::Request,
1127 )
1128 .expect("Could not interpret a valid client request");
1129
1130 assert_eq!(req.log.len(), 1);
1131 assert_matches!(&req.log[0], EffectfulRequestActions::SetUri(r) if r == "http://example.com/");
1132 assert_matches!(result.0, PsInterpretValue::MatchYes);
1133 }
1134
1135 #[test]
1136 fn test_interpret_client_request_stage_request_uri_transform_if() {
1137 let mut request_xform_false_stage = stage_metadata();
1138 let mut request_xform_true_stage = stage_metadata();
1139
1140 let request_xform_false_match = expression_match("true");
1141 let request_xform_false = request_transform(
1142 None,
1143 Some("\"http://\" . \"example.com\"".to_string()),
1144 Some(true),
1145 );
1146 request_xform_false_stage.value.request_xform = Some(request_xform_false);
1147
1148 let request_xform_true_match = expression_match("true");
1149 let request_xform_true = request_transform(
1150 None,
1151 Some("\"http://\" . \"example2.com\"".to_string()),
1152 Some(true),
1153 );
1154 request_xform_true_stage.value.request_xform = Some(request_xform_true);
1155
1156 let mg = match_group(
1157 typed_stage_rule(Some(request_xform_false_match), request_xform_false_stage),
1158 Some(vec![typed_stage_rule(
1159 Some(request_xform_true_match),
1160 request_xform_true_stage,
1161 )]),
1162 );
1163 let crs = client_request_stage(vec![mg]);
1164
1165 let (mut verifier, context) = verifier();
1166
1167 let result = verifier
1168 .visit_client_request_stage(&crs, context)
1169 .expect("Could not verify valid client request")
1170 .value
1171 .expect("Could not get value from verified client request");
1172
1173 let value = match result {
1174 PsVerifierContextValue::ClientRequestStage(typed_client_request_stage) => {
1175 typed_client_request_stage
1176 }
1177 _ => todo!(),
1178 };
1179 let mut req = EffectfulProcessableRequestResponse::new_request();
1180 let result = interpret_stage(
1181 &TypedStage::ClientRequest(value),
1182 &Scopes { scopes: vec![] },
1183 &mut req,
1184 PsInterpretMode::Request,
1185 )
1186 .expect("Could not interpret a valid client request");
1187
1188 assert_eq!(req.log.len(), 1);
1189 assert_matches!(&req.log[0], EffectfulRequestActions::SetUri(r) if r == "http://example.com/");
1190 assert_matches!(result.0, PsInterpretValue::MatchYes);
1191 }
1192
1193 #[test]
1194 fn test_interpret_client_request_stage_request_uri_transform_else() {
1195 let mut request_xform_false_stage = stage_metadata();
1196 let mut request_xform_false_false_stage = stage_metadata();
1197 let mut request_xform_true_stage = stage_metadata();
1198
1199 let request_xform_false_match = expression_match("false");
1200 let request_xform_false = request_transform(
1201 None,
1202 Some("\"http://\" . \"example.com\"".to_string()),
1203 Some(true),
1204 );
1205 request_xform_false_stage.value.request_xform = Some(request_xform_false);
1206
1207 let request_xform_false_false_match = expression_match("true");
1208 let request_xform_false_false = request_transform(
1209 None,
1210 Some("\"http://\" . \"example1.com\"".to_string()),
1211 Some(true),
1212 );
1213 request_xform_false_false_stage.value.request_xform = Some(request_xform_false_false);
1214
1215 let request_xform_true_match = expression_match("true");
1216 let request_xform_true = request_transform(
1217 None,
1218 Some("\"http://\" . \"example2.com\"".to_string()),
1219 Some(true),
1220 );
1221
1222 request_xform_true_stage.value.request_xform = Some(request_xform_true);
1223
1224 let mg = match_group(
1225 typed_stage_rule(Some(request_xform_false_match), request_xform_false_stage),
1226 Some(vec![
1227 typed_stage_rule(
1228 Some(request_xform_false_false_match),
1229 request_xform_false_false_stage,
1230 ),
1231 typed_stage_rule(Some(request_xform_true_match), request_xform_true_stage),
1232 ]),
1233 );
1234 let crs = client_request_stage(vec![mg]);
1235
1236 let (mut verifier, context) = verifier();
1237
1238 let result = verifier
1239 .visit_client_request_stage(&crs, context)
1240 .expect("Could not verify valid client request")
1241 .value
1242 .expect("Could not get value from verified client request");
1243
1244 let value = match result {
1245 PsVerifierContextValue::ClientRequestStage(typed_client_request_stage) => {
1246 typed_client_request_stage
1247 }
1248 _ => todo!(),
1249 };
1250 let mut req = EffectfulProcessableRequestResponse::new_request();
1251 let result = interpret_stage(
1252 &TypedStage::ClientRequest(value),
1253 &Scopes { scopes: vec![] },
1254 &mut req,
1255 PsInterpretMode::Request,
1256 )
1257 .expect("Could not interpret a valid client request");
1258
1259 assert_eq!(req.log.len(), 1);
1260 assert_matches!(&req.log[0], EffectfulRequestActions::SetUri(r) if r == "http://example1.com/");
1261 assert_matches!(result.0, PsInterpretValue::MatchYes);
1262 }
1263
1264 fn test_interpret_client_request_stage_request_uri_transform_else_if() {
1265 let mut request_xform_false_stage = stage_metadata();
1266 let mut request_xform_false_false_stage = stage_metadata();
1267 let mut request_xform_true_stage = stage_metadata();
1268
1269 let request_xform_false_match = expression_match("false");
1270 let request_xform_false = request_transform(
1271 None,
1272 Some("\"http://\" . \"example.com\"".to_string()),
1273 Some(true),
1274 );
1275 request_xform_false_stage.value.request_xform = Some(request_xform_false);
1276
1277 let request_xform_false_false_match = expression_match("false");
1278 let request_xform_false_false = request_transform(
1279 None,
1280 Some("\"http://\" . \"example1.com\"".to_string()),
1281 Some(true),
1282 );
1283 request_xform_false_false_stage.value.request_xform = Some(request_xform_false_false);
1284
1285 let request_xform_true_match = expression_match("true");
1286 let request_xform_true = request_transform(
1287 None,
1288 Some("\"http://\" . \"example2.com\"".to_string()),
1289 Some(true),
1290 );
1291
1292 request_xform_true_stage.value.request_xform = Some(request_xform_true);
1293
1294 let mg = match_group(
1295 typed_stage_rule(Some(request_xform_false_match), request_xform_false_stage),
1296 Some(vec![
1297 typed_stage_rule(
1298 Some(request_xform_false_false_match),
1299 request_xform_false_false_stage,
1300 ),
1301 typed_stage_rule(Some(request_xform_true_match), request_xform_true_stage),
1302 ]),
1303 );
1304 let crs = client_request_stage(vec![mg]);
1305
1306 let (mut verifier, context) = verifier();
1307
1308 let result = verifier
1309 .visit_client_request_stage(&crs, context)
1310 .expect("Could not verify valid client request")
1311 .value
1312 .expect("Could not get value from verified client request");
1313
1314 let value = match result {
1315 PsVerifierContextValue::ClientRequestStage(typed_client_request_stage) => {
1316 typed_client_request_stage
1317 }
1318 _ => todo!(),
1319 };
1320 let mut req = EffectfulProcessableRequestResponse::new_request();
1321 let result = interpret_stage(
1322 &TypedStage::ClientRequest(value),
1323 &Scopes { scopes: vec![] },
1324 &mut req,
1325 PsInterpretMode::Request,
1326 )
1327 .expect("Could not interpret a valid client request");
1328
1329 assert_eq!(req.log.len(), 1);
1330 assert_matches!(&req.log[0], EffectfulRequestActions::SetUri(r) if r == "http://example2.com/");
1331 assert_matches!(result.0, PsInterpretValue::MatchYes);
1332 }
1333
1334 #[test]
1335 fn test_interpret_client_request_stage_response_status_transform() {
1336 let mut response_xform_stage = stage_metadata();
1337
1338 let response_xform_match = expression_match("true");
1339 let response_xform = response_transform(None, Some("5 + 4".to_string()), Some(true), None);
1340 response_xform_stage.value.response_xform = Some(response_xform);
1341
1342 let response_xform_mg = match_group(
1343 typed_stage_rule(Some(response_xform_match), response_xform_stage),
1344 None,
1345 );
1346
1347 let crs = client_request_stage(vec![response_xform_mg]);
1348
1349 let (mut verifier, context) = verifier();
1350
1351 let result = verifier
1352 .visit_client_request_stage(&crs, context)
1353 .expect("Could not verify valid client request")
1354 .value
1355 .expect("Could not get value from verified client request");
1356
1357 let value = match result {
1358 PsVerifierContextValue::ClientRequestStage(typed_client_request_stage) => {
1359 typed_client_request_stage
1360 }
1361 _ => todo!(),
1362 };
1363 let mut req = EffectfulProcessableRequestResponse::new_request();
1364 interpret_stage(
1365 &TypedStage::ClientRequest(value),
1366 &Scopes { scopes: vec![] },
1367 &mut req,
1368 PsInterpretMode::Response,
1369 )
1370 .expect("Could not interpret a valid client request");
1371
1372 assert_eq!(req.log.len(), 1);
1373 assert_matches!(&req.log[0], EffectfulRequestActions::SetResponse(9));
1374 }
1375
1376 #[test]
1377 fn test_interpret_client_request_stage_response_status_transform_if() {
1378 let mut response_xform_false_stage = stage_metadata();
1379 let mut response_xform_true_stage = stage_metadata();
1380
1381 let response_xform_false_match = expression_match("true");
1382 let response_xform_false =
1383 response_transform(None, Some("5 + 4".to_string()), Some(true), None);
1384 response_xform_false_stage.value.response_xform = Some(response_xform_false);
1385
1386 let response_xform_true_match = expression_match("true");
1387 let response_xform_true =
1388 response_transform(None, Some("5 + 5".to_string()), Some(true), None);
1389 response_xform_true_stage.value.response_xform = Some(response_xform_true);
1390
1391 let mg = match_group(
1392 typed_stage_rule(Some(response_xform_false_match), response_xform_false_stage),
1393 Some(vec![typed_stage_rule(
1394 Some(response_xform_true_match),
1395 response_xform_true_stage,
1396 )]),
1397 );
1398 let crs = client_request_stage(vec![mg]);
1399
1400 let (mut verifier, context) = verifier();
1401
1402 let result = verifier
1403 .visit_client_request_stage(&crs, context)
1404 .expect("Could not verify valid client request")
1405 .value
1406 .expect("Could not get value from verified client request");
1407
1408 let value = match result {
1409 PsVerifierContextValue::ClientRequestStage(typed_client_request_stage) => {
1410 typed_client_request_stage
1411 }
1412 _ => todo!(),
1413 };
1414 let mut req = EffectfulProcessableRequestResponse::new_request();
1415 let result = interpret_stage(
1416 &TypedStage::ClientRequest(value),
1417 &Scopes { scopes: vec![] },
1418 &mut req,
1419 PsInterpretMode::Response,
1420 )
1421 .expect("Could not interpret a valid client request");
1422
1423 assert_eq!(req.log.len(), 1);
1424 assert_matches!(&req.log[0], EffectfulRequestActions::SetResponse(9));
1425 assert_matches!(result.0, PsInterpretValue::MatchYes);
1426 }
1427
1428 #[test]
1429 fn test_interpret_client_request_stage_response_status_transform_else() {
1430 let mut response_xform_false_stage = stage_metadata();
1431 let mut response_xform_false_false_stage = stage_metadata();
1432 let mut response_xform_true_stage = stage_metadata();
1433
1434 let response_xform_false_match = expression_match("false");
1435 let response_xform_false =
1436 response_transform(None, Some("5 + 4".to_string()), Some(true), None);
1437 response_xform_false_stage.value.response_xform = Some(response_xform_false);
1438
1439 let response_xform_false_false_match = expression_match("true");
1440 let response_xform_false_false =
1441 response_transform(None, Some("5 + 5".to_string()), Some(true), None);
1442 response_xform_false_false_stage.value.response_xform = Some(response_xform_false_false);
1443
1444 let response_xform_true_match = expression_match("true");
1445 let response_xform_true =
1446 response_transform(None, Some("5 + 6".to_string()), Some(true), None);
1447
1448 response_xform_true_stage.value.response_xform = Some(response_xform_true);
1449
1450 let mg = match_group(
1451 typed_stage_rule(Some(response_xform_false_match), response_xform_false_stage),
1452 Some(vec![
1453 typed_stage_rule(
1454 Some(response_xform_false_false_match),
1455 response_xform_false_false_stage,
1456 ),
1457 typed_stage_rule(Some(response_xform_true_match), response_xform_true_stage),
1458 ]),
1459 );
1460 let crs = client_request_stage(vec![mg]);
1461
1462 let (mut verifier, context) = verifier();
1463
1464 let result = verifier
1465 .visit_client_request_stage(&crs, context)
1466 .expect("Could not verify valid client request")
1467 .value
1468 .expect("Could not get value from verified client request");
1469
1470 let value = match result {
1471 PsVerifierContextValue::ClientRequestStage(typed_client_request_stage) => {
1472 typed_client_request_stage
1473 }
1474 _ => todo!(),
1475 };
1476 let mut req = EffectfulProcessableRequestResponse::new_request();
1477 let result = interpret_stage(
1478 &TypedStage::ClientRequest(value),
1479 &Scopes { scopes: vec![] },
1480 &mut req,
1481 PsInterpretMode::Response,
1482 )
1483 .expect("Could not interpret a valid client request");
1484
1485 assert_eq!(req.log.len(), 1);
1486 assert_matches!(&req.log[0], EffectfulRequestActions::SetResponse(10));
1487 assert_matches!(result.0, PsInterpretValue::MatchYes);
1488 }
1489
1490 fn test_interpret_client_request_stage_response_status_transform_else_if() {
1491 let mut response_xform_false_stage = stage_metadata();
1492 let mut response_xform_false_false_stage = stage_metadata();
1493 let mut response_xform_true_stage = stage_metadata();
1494
1495 let response_xform_false_match = expression_match("false");
1496 let response_xform_false =
1497 response_transform(None, Some("5 + 4".to_string()), Some(true), None);
1498 response_xform_false_stage.value.response_xform = Some(response_xform_false);
1499
1500 let response_xform_false_false_match = expression_match("false");
1501 let response_xform_false_false =
1502 response_transform(None, Some("5 + 5".to_string()), Some(true), None);
1503 response_xform_false_false_stage.value.response_xform = Some(response_xform_false_false);
1504
1505 let response_xform_true_match = expression_match("true");
1506 let response_xform_true =
1507 response_transform(None, Some("5 + 6".to_string()), Some(true), None);
1508
1509 response_xform_true_stage.value.response_xform = Some(response_xform_true);
1510
1511 let mg = match_group(
1512 typed_stage_rule(Some(response_xform_false_match), response_xform_false_stage),
1513 Some(vec![
1514 typed_stage_rule(
1515 Some(response_xform_false_false_match),
1516 response_xform_false_false_stage,
1517 ),
1518 typed_stage_rule(Some(response_xform_true_match), response_xform_true_stage),
1519 ]),
1520 );
1521 let crs = client_request_stage(vec![mg]);
1522
1523 let (mut verifier, context) = verifier();
1524
1525 let result = verifier
1526 .visit_client_request_stage(&crs, context)
1527 .expect("Could not verify valid client request")
1528 .value
1529 .expect("Could not get value from verified client request");
1530
1531 let value = match result {
1532 PsVerifierContextValue::ClientRequestStage(typed_client_request_stage) => {
1533 typed_client_request_stage
1534 }
1535 _ => todo!(),
1536 };
1537 let mut req = EffectfulProcessableRequestResponse::new_request();
1538 let result = interpret_stage(
1539 &TypedStage::ClientRequest(value),
1540 &Scopes { scopes: vec![] },
1541 &mut req,
1542 PsInterpretMode::Response,
1543 )
1544 .expect("Could not interpret a valid client request");
1545
1546 assert_eq!(req.log.len(), 1);
1547 assert_matches!(&req.log[0], EffectfulRequestActions::SetResponse(11));
1548 assert_matches!(result.0, PsInterpretValue::MatchYes);
1549 }
1550
1551 #[test]
1552 fn test_interpret_client_request_stage_response_synthetic() {
1553 let mut response_xform_true_stage = stage_metadata();
1554
1555 let response_xform_true_match = expression_match("true");
1556 let response_xform_true = response_transform(
1557 None,
1558 None,
1559 None,
1560 Some(synthetic_response(
1561 Some(vec![
1562 typed_header("X-custom1", "Custom value 1", None),
1563 typed_header("X-custom2", "Custom value 2", None),
1564 ]),
1565 Some("400 + 4".to_string()),
1566 Some(true),
1567 Some("\"This \" . \"is \" . \"a \" . \"test.\"".to_string()),
1568 Some(true),
1569 )),
1570 );
1571 response_xform_true_stage.value.response_xform = Some(response_xform_true);
1572
1573 let mg = match_group(
1574 typed_stage_rule(Some(response_xform_true_match), response_xform_true_stage),
1575 None,
1576 );
1577 let crs = client_request_stage(vec![mg]);
1578
1579 let (mut verifier, context) = verifier();
1580
1581 let result = verifier
1582 .visit_client_request_stage(&crs, context)
1583 .expect("Could not verify valid client request")
1584 .value
1585 .expect("Could not get value from verified client request");
1586
1587 let value = match result {
1588 PsVerifierContextValue::ClientRequestStage(typed_client_request_stage) => {
1589 typed_client_request_stage
1590 }
1591 _ => todo!(),
1592 };
1593 let mut req = EffectfulProcessableRequestResponse::new_request();
1594 let result = interpret_stage(
1595 &TypedStage::ClientRequest(value),
1596 &Scopes { scopes: vec![] },
1597 &mut req,
1598 PsInterpretMode::Response,
1599 )
1600 .expect("Could not interpret a valid client request");
1601
1602 assert_eq!(req.log.len(), 0);
1603 assert_matches!(&result.0, PsInterpretValue::SyntheticResponse(r)
1604 if r.status() == 404 && r.body() == &"This is a test.".to_string().into_bytes() && r.headers().len() == 2);
1605 }
1606}