Skip to main content

brooks_lib/verifying/
imdv.rs

1// brooks, Copyright 2026, Will Hawkins
2//
3// This file is part of brooks.
4
5// This file is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program. If not, see <https://www.gnu.org/licenses/>.
17
18//! Verification of [Interconnection Metadata](https://datatracker.ietf.org/doc/rfc8006/)
19
20use crate::verifying::cors::verify::CrossoriginPolicyMetadataAnalyzer;
21use crate::verifying::mel::verify::SetVariableMetadataAnalyzer;
22use crate::verifying::verify::{
23    CdniVerificationKey, MetadataAnalysisContext, MetadataVerificationError, Verifier,
24};
25use crate::{environment::scope::Scopes, mel::types::Type};
26
27use crate::verifying::original::verify::SourceMetadataAnalyzer;
28use crate::verifying::ps::verify::PsMetadataAnalyzer;
29
30use crate::cdni::{gmd::spec::TypedGenericMetadata, imd::spec::HostMetadata};
31
32/// Verify a piece of [Interconnection Metadata](https://datatracker.ietf.org/doc/rfc8006/).
33///
34/// TODO: Make clear in the documentation that this function is a _major_ entry point for library clients.
35pub fn verify_interconnection_metadata(
36    metadata: &HostMetadata<()>,
37    scopes: Scopes<Type>,
38) -> Result<(HostMetadata<CdniVerificationKey>, Scopes<Type>), Box<MetadataVerificationError>> {
39    let mut analyzed_md_elements: Vec<TypedGenericMetadata<CdniVerificationKey>> = vec![];
40
41    let processors: Vec<&dyn Verifier<MetadataAnalysisContext, MetadataVerificationError>> = vec![
42        &PsMetadataAnalyzer {} as &dyn Verifier<MetadataAnalysisContext, MetadataVerificationError>,
43        &SourceMetadataAnalyzer {}
44            as &dyn Verifier<MetadataAnalysisContext, MetadataVerificationError>,
45        &SetVariableMetadataAnalyzer {}
46            as &dyn Verifier<MetadataAnalysisContext, MetadataVerificationError>,
47        &CrossoriginPolicyMetadataAnalyzer {}
48            as &dyn Verifier<MetadataAnalysisContext, MetadataVerificationError>,
49    ];
50
51    let mut analysis_context = MetadataAnalysisContext { scopes };
52    for md in &metadata.metadata {
53        let mut no_processor = true;
54        for processor in &processors {
55            if !processor.type_name(&md.tpe) {
56                continue;
57            }
58
59            no_processor = false;
60
61            let (new_analysis_context, analyzed_md) = processor.analyze(md, analysis_context)?;
62
63            analysis_context = new_analysis_context;
64
65            analyzed_md_elements.push(TypedGenericMetadata {
66                tpe: md.tpe.clone(),
67                value: md.value.clone(),
68                aug: analyzed_md,
69            });
70        }
71
72        if no_processor {
73            return Err(MetadataVerificationError::NoProcessor(md.tpe.clone()).into());
74        }
75    }
76
77    Ok((
78        HostMetadata {
79            metadata: analyzed_md_elements,
80            aug: Default::default(),
81        },
82        analysis_context.scopes,
83    ))
84}