brooks_lib/dcdn/processors/
cors.rs1use crate::{
21 cdni::cors::spec::TypedCrossoriginPolicy,
22 dcdn::{
23 imdi,
24 interpret::{
25 Error::{self, NotImplemented},
26 MetadataInformationResultElements, Stages,
27 },
28 processors::SimpleProcessorsInterpreterContext,
29 },
30 processing::interpret::{InterpretationResult, Interpreter},
31 verifying::cors::verify::CrossoriginPolicyVerificationKey,
32};
33
34impl
35 Interpreter<
36 SimpleProcessorsInterpreterContext<'_>,
37 (imdi::ResultValue, MetadataInformationResultElements),
38 Stages,
39 Error,
40 > for TypedCrossoriginPolicy<CrossoriginPolicyVerificationKey>
41{
42 fn interpret<'a>(
43 &self,
44 input: SimpleProcessorsInterpreterContext<'a>,
45 ) -> InterpretationResult<
46 SimpleProcessorsInterpreterContext<'a>,
47 (imdi::ResultValue, MetadataInformationResultElements),
48 Error,
49 > {
50 if let Some(preflight_only) = self.value.preflight_only
51 && preflight_only
52 {
53 return Err(Error::RuntimeError(
54 NotImplemented("Missing response when processing MI.CrossoriginPolicy".into())
55 .into(),
56 )
57 .into());
58 }
59
60 let mut res = match input.res {
61 Some(res) => res,
62 None => {
63 return Err(Error::RuntimeError(
64 Error::AssertionFailure(
65 "Missing response when processing MI.CrossoriginPolicy".into(),
66 )
67 .into(),
68 )
69 .into());
70 }
71 };
72 let req = input.req;
73
74 let origin_value = match req
75 .headers()
76 .iter()
77 .find(|(name, _)| *name == http::header::ORIGIN.to_string())
78 {
79 Some(origin_value) => origin_value.1.clone(),
80 None => todo!(),
81 };
82
83 let origin_value = origin_value.to_str().map_err(|e| {
84 Error::InvalidInput(
85 format!("ORIGIN header value could not be converted to string: {e}").into(),
86 )
87 })?;
88
89 let apply = self
92 .value
93 .allow_origin
94 .allow_origin
95 .iter()
96 .any(|v| v.aug.as_ref().unwrap().is_match(origin_value));
97
98 if apply {
101 if self.value.allow_origin.wildcard_return {
102 res.set_header_value(http::header::ACCESS_CONTROL_ALLOW_ORIGIN.as_str(), "*")
103 .map_err(|e| Error::RuntimeError(e.into()))?;
104 } else {
105 res.set_header_value(
106 http::header::ACCESS_CONTROL_ALLOW_ORIGIN.as_str(),
107 origin_value,
108 )
109 .map_err(|e| Error::RuntimeError(e.into()))?;
110 }
111 }
112
113 let updated_context = SimpleProcessorsInterpreterContext {
114 scopes: input.scopes,
115 mode: input.mode,
116 runtime: input.runtime,
117 req,
118 res: Some(res),
119 };
120
121 Ok((
122 updated_context,
123 (None, MetadataInformationResultElements::default()),
124 ))
125 }
126
127 fn at(&self, stage: Stages) -> bool {
128 stage == Stages::Post
129 }
130}
131
132#[cfg(test)]
133mod test {}