use pdk_core::logger;
use crate::error::CorsError;
use crate::model::cors::CorsResourceTypeEnum;
use crate::model::request::request_selector::RequestSelector;
use crate::model::resource::cors_resource::CorsRequestType;
use crate::model::resource::protected_resource::ResponseType;
use crate::{HeaderMap, HeaderValue};
pub(crate) const METHOD_HEADER: &str = ":method";
pub struct RequestProcessor<'a> {
cors: CorsResourceTypeEnum<'a>,
request_selector: RequestSelector,
}
impl RequestProcessor<'_> {
pub(crate) fn new(cors_type: CorsResourceTypeEnum<'_>) -> RequestProcessor {
RequestProcessor {
cors: cors_type,
request_selector: RequestSelector::default(),
}
}
pub fn process_request(&self, headers: &HeaderMap) -> Result<ResponseType, CorsError> {
let request_method = self.get_method(headers);
match request_method {
None => Err(CorsError::RequestMethodNotFound),
Some(method) => {
logger::debug!("Processing incoming request [headers = {headers:?}]");
let incoming_request = self.request_selector.get_type(headers, method);
incoming_request.access_resource(&self.cors)
}
}
}
fn get_method<'a>(&self, headers: &'a HeaderMap<'a>) -> Option<&'a HeaderValue> {
headers
.iter()
.find_map(|(k, v)| (*k == METHOD_HEADER).then_some(*v))
}
}
#[cfg(test)]
mod request_processor_tests {
use crate::model::cors::CorsResourceTypeEnum;
use crate::model::request::request_processor::{RequestProcessor, METHOD_HEADER};
use crate::model::resource::public_resource::PublicResource;
#[test]
fn if_no_method_is_found_then_error_is_returned() {
let request_processor = request_processor();
assert!(request_processor.process_request(&[]).is_err())
}
#[test]
fn if_method_is_found_request_is_processed() {
let request_processor = request_processor();
let headers = [(METHOD_HEADER, "get")];
assert!(request_processor.process_request(&headers).is_ok())
}
fn request_processor<'a>() -> RequestProcessor<'a> {
RequestProcessor::new(CorsResourceTypeEnum::PublicResource(PublicResource::new(
false,
)))
}
}