Skip to main content

pdk_cors_lib/
check.rs

1// Copyright (c) 2026, Salesforce, Inc.,
2// All rights reserved.
3// For full license text, see the LICENSE.txt file
4
5//! CORS checking utilities
6//!
7//! Provides the [`Cors`] checker which evaluates request headers against a
8//! [`Configuration`] and produces the
9//! appropriate CORS response headers. The result of a check is a [`Check`]
10//! indicating the [`ResponseType`] (`Preflight` or `Main`) plus the headers to
11//! attach to the outbound response.
12
13use crate::{
14    configuration::Configuration,
15    error::CorsError,
16    model::{
17        cors::CorsResourceFactory, request::request_processor::RequestProcessor,
18        resource::protected_resource::ResponseType as InnerResponseType,
19    },
20};
21
22/// Represents the CORS response variants.
23#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
24pub enum ResponseType {
25    /// Preflight CORS response.
26    Preflight,
27
28    /// Main CORS response.
29    Main,
30}
31
32/// Output type for [`Cors::check_headers`].
33#[derive(Debug, Clone)]
34pub struct Check {
35    response_type: ResponseType,
36    headers: Vec<(String, String)>,
37}
38
39impl Check {
40    fn from_response_type(response_type: InnerResponseType) -> Self {
41        match response_type {
42            InnerResponseType::Main(headers) => Self {
43                response_type: ResponseType::Main,
44                headers,
45            },
46            InnerResponseType::Preflight(headers) => Self {
47                response_type: ResponseType::Preflight,
48                headers,
49            },
50        }
51    }
52
53    /// Retuns the checked CORS response type.
54    pub fn response_type(&self) -> ResponseType {
55        self.response_type
56    }
57
58    /// Returns the checked headers.
59    pub fn headers(&self) -> &[(String, String)] {
60        &self.headers
61    }
62
63    /// Consumes this check and returns the internal list checked of headers.
64    pub fn into_headers(self) -> Vec<(String, String)> {
65        self.headers
66    }
67}
68
69/// CORS checker.
70pub struct Cors<'a> {
71    processor: RequestProcessor<'a>,
72}
73
74impl<'a> Cors<'a> {
75    /// Creates a new CORS checker.
76    pub fn new(config: &'a Configuration<'a>) -> Self {
77        Cors {
78            processor: RequestProcessor::new(CorsResourceFactory::from_configuration(config)),
79        }
80    }
81
82    /// Performs a CORS checking of request headers.
83    pub fn check_headers(&self, headers: &[(String, String)]) -> Result<Check, CorsError> {
84        let header_map: Vec<_> = headers
85            .iter()
86            .map(|(n, v)| (n.as_str(), v.as_str()))
87            .collect();
88
89        self.processor
90            .process_request(header_map.as_slice())
91            .map(Check::from_response_type)
92    }
93}