feat(middleware): add support of path patterns

This commit is contained in:
2025-10-28 22:33:10 +04:00
parent d1ef5c032e
commit 39c60ef939

View File

@@ -5,13 +5,13 @@ use actix_web::body::{BoxBody, EitherBody};
use actix_web::dev::{forward_ready, Service, ServiceRequest, ServiceResponse, Transform}; use actix_web::dev::{forward_ready, Service, ServiceRequest, ServiceResponse, Transform};
use actix_web::{web, Error, HttpRequest, ResponseError}; use actix_web::{web, Error, HttpRequest, ResponseError};
use database::entity::sea_orm_active_enums::UserRole; use database::entity::sea_orm_active_enums::UserRole;
use database::entity::UserType;
use database::query::Query; use database::query::Query;
use futures_util::future::LocalBoxFuture; use futures_util::future::LocalBoxFuture;
use std::future::{ready, Ready}; use std::future::{ready, Ready};
use std::ops::Deref; use std::ops::Deref;
use std::rc::Rc; use std::rc::Rc;
use std::sync::Arc; use std::sync::Arc;
use database::entity::UserType;
#[derive(Default, Clone)] #[derive(Default, Clone)]
pub struct ServiceConfig { pub struct ServiceConfig {
@@ -42,7 +42,11 @@ impl JWTAuthorizationBuilder {
self self
} }
pub fn add_paths(mut self, paths: impl AsRef<[&'static str]>, config: Option<ServiceConfig>) -> Self { pub fn add_paths(
mut self,
paths: impl AsRef<[&'static str]>,
config: Option<ServiceConfig>,
) -> Self {
self.path_configs.push((Arc::from(paths.as_ref()), config)); self.path_configs.push((Arc::from(paths.as_ref()), config));
self self
} }
@@ -176,11 +180,20 @@ where
fn call(&self, req: ServiceRequest) -> Self::Future { fn call(&self, req: ServiceRequest) -> Self::Future {
let service = Rc::clone(&self.service); let service = Rc::clone(&self.service);
let Some(config) = Self::find_config( let match_info = req.match_info();
req.match_info().unprocessed(), let path = if let Some(pattern) = req.match_pattern() {
&self.path_configs, let scope_start_idx = match_info
&self.default_config, .as_str()
) else { .find(match_info.unprocessed())
.unwrap_or(0);
pattern.as_str().split_at(scope_start_idx).1.to_owned()
} else {
match_info.unprocessed().to_owned()
};
let Some(config) = Self::find_config(&path, &self.path_configs, &self.default_config)
else {
let fut = self.service.call(req); let fut = self.service.call(req);
return Box::pin(async move { Ok(fut.await?.map_into_left_body()) }); return Box::pin(async move { Ok(fut.await?.map_into_left_body()) });
}; };