brooks_lib/dcdn/processors/
source.rs1use reqwest::dns::{Addrs, Resolve};
21
22use crate::{
23 cdni::original::spec::TypedSourceMetadata,
24 dcdn::{
25 imdi,
26 interpret::{Error, MetadataInformationResultElements, ProcessedRequestResponse, Stages},
27 processors::SimpleProcessorsInterpreterContext,
28 },
29 processing::interpret::{self, InterpretationResult},
30 prr::{self, Prr},
31 verifying::original::verify::SourceVerificationKey,
32};
33
34use std::fmt::Debug;
35use std::net::SocketAddr;
36
37#[derive(Debug, Clone)]
38pub struct SourceMetadataResolver {
39 pub addr: SocketAddr,
40}
41
42impl Resolve for SourceMetadataResolver {
43 fn resolve(&self, _name: reqwest::dns::Name) -> reqwest::dns::Resolving {
44 let addrs: Addrs = Box::new(vec![self.addr].into_iter());
45 Box::pin(std::future::ready(Ok(addrs)))
46 }
47}
48
49impl
50 interpret::Interpreter<
51 SimpleProcessorsInterpreterContext<'_>,
52 (imdi::ResultValue, MetadataInformationResultElements),
53 Stages,
54 Error,
55 > for TypedSourceMetadata<SourceVerificationKey>
56{
57 fn interpret<'a>(
58 &self,
59 input: SimpleProcessorsInterpreterContext<'a>,
60 ) -> InterpretationResult<
61 SimpleProcessorsInterpreterContext<'a>,
62 (imdi::ResultValue, MetadataInformationResultElements),
63 Error,
64 > {
65 let req = &*input.req;
66
67 let req: reqwest::Request = req
68 .try_into()
69 .map_err(|e: prr::Error| Error::InvalidInput(e.into()))?;
70
71 let req_method = req.method().clone();
72 let req_url = req.url().clone();
73
74 let mut clientb = reqwest::Client::builder();
75
76 let resolver = SourceMetadataResolver {
77 addr: *self
78 .value
79 .aug
80 .sources
81 .first()
82 .ok_or(Error::AssertionFailure(
83 "Missing sources".to_string().into(),
84 ))?
85 .0
86 .first()
87 .ok_or(Error::AssertionFailure(
88 "Missing endpoints".to_string().into(),
89 ))?,
90 };
91
92 clientb = clientb.dns_resolver(resolver);
93
94 let client = clientb.build().map_err(|e| Error::RuntimeError(e.into()))?;
95
96 let result: Result<ProcessedRequestResponse, Error> = input.runtime.block_on(async {
97 let r = client
98 .execute(req)
99 .await
100 .map_err(|e| Error::RuntimeError(e.into()))?;
101
102 let mut result = ProcessedRequestResponse::new_response(&req_url, &req_method);
103
104 result.oheaders = r.headers().clone();
105
106 result
107 .set_status(&r.status().as_u16())
108 .map_err(|_| Error::RuntimeError(prr::Error::BadStatus.into()))?;
109
110 let b = r.bytes().await.map_err(|e| Error::RuntimeError(e.into()))?;
111 result.obody = b.to_vec();
112 Ok(result)
113 });
114
115 Ok((
116 input.with_res(Box::new(result?)),
117 (None, MetadataInformationResultElements::default()),
118 ))
119 }
120
121 fn at(&self, stage: Stages) -> bool {
122 stage == Stages::Source
123 }
124}