dmsc/gateway/
middleware.rs

1//! Copyright © 2025-2026 Wenze Wei. All Rights Reserved.
2//!
3//! This file is part of DMSC.
4//! The DMSC project belongs to the Dunimd Team.
5//!
6//! Licensed under the Apache License, Version 2.0 (the "License");
7//! You may not use this file except in compliance with the License.
8//! You may obtain a copy of the License at
9//!
10//!     http://www.apache.org/licenses/LICENSE-2.0
11//!
12//! Unless required by applicable law or agreed to in writing, software
13//! distributed under the License is distributed on an "AS IS" BASIS,
14//! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15//! See the License for the specific language governing permissions and
16//! limitations under the License.
17
18#![allow(non_snake_case)]
19
20//! # Middleware Module
21//! 
22//! This module provides a flexible middleware system for the DMSC gateway, allowing for
23//! request processing and modification through a chain of middleware components.
24//! 
25//! ## Key Components
26//! 
27//! - **DMSCMiddleware**: Trait defining the middleware interface
28//! - **DMSCMiddlewareChain**: Manages a chain of middleware components
29//! - **Built-in Middleware**: Auth, CORS, Logging, Request ID, and Rate Limiting implementations
30//! 
31//! ## Design Principles
32//! 
33//! 1. **Async Trait**: Uses async_trait for async middleware execution
34//! 2. **Flexible Chain**: Allows dynamic addition and removal of middleware
35//! 3. **Extensible**: Easy to implement custom middleware
36//! 4. **Thread Safe**: Uses Arc for safe sharing of middleware instances
37//! 5. **Modular**: Built-in middleware implementations can be used independently
38//! 6. **Request Modification**: Middleware can modify requests before they reach the target service
39//! 7. **Error Handling**: Middleware can return errors to abort request processing
40//! 8. **Order Matters**: Middleware is executed in the order they are added to the chain
41//! 
42//! ## Usage
43//! 
44//! ```rust
45//! use dmsc::prelude::*;
46//! use std::sync::Arc;
47//! 
48//! async fn example() -> DMSCResult<()> {
49//!     // Create a middleware chain
50//!     let mut chain = DMSCMiddlewareChain::new();
51//!     
52//!     // Add built-in middleware
53//!     chain.add(Arc::new(DMSCLoggingMiddleware::new("info".to_string())));
54//!     chain.add(Arc::new(DMSCAuthMiddleware::new("Authorization".to_string())));
55//!     chain.add(Arc::new(DMSCCorsMiddleware::new(
56//!         vec!["*".to_string()],
57//!         vec!["GET".to_string(), "POST".to_string()],
58//!         vec!["Content-Type".to_string(), "Authorization".to_string()]
59//!     )));
60//!     
61//!     // Create a request and execute the middleware chain
62//!     let mut request = DMSCGatewayRequest::new("GET".to_string(), "/api/v1/resource".to_string());
63//!     chain.execute(&mut request).await?;
64//!     
65//!     Ok(())
66//! }
67//! ```
68
69use super::DMSCGatewayRequest;
70use crate::core::DMSCResult;
71use async_trait::async_trait;
72use std::sync::Arc;
73
74/// Trait defining the middleware interface for request processing.
75/// 
76/// All middleware components must implement this trait, which provides methods for
77/// executing middleware logic and identifying the middleware.
78#[async_trait]
79pub trait DMSCMiddleware: Send + Sync {
80    /// Executes the middleware logic on a request.
81    /// 
82    /// This method is called for each request passing through the middleware chain.
83    /// Middleware can modify the request, validate it, or return an error to abort processing.
84    /// 
85    /// # Parameters
86    /// 
87    /// - `request`: Mutable reference to the request being processed
88    /// 
89    /// # Returns
90    /// 
91    /// A `DMSCResult<()>` indicating success or failure
92    async fn execute(&self, request: &mut DMSCGatewayRequest) -> DMSCResult<()>;
93    
94    /// Gets the name of the middleware.
95    /// 
96    /// This method returns a static string identifier for the middleware, useful for logging
97    /// and debugging purposes.
98    /// 
99    /// # Returns
100    /// 
101    /// A static string containing the middleware name
102    fn name(&self) -> &'static str;
103}
104
105/// Manages a chain of middleware components.
106/// 
107/// This struct maintains a list of middleware instances and provides methods for
108/// adding, removing, and executing middleware in sequence.
109pub struct DMSCMiddlewareChain {
110    /// Vector of middleware instances in the order they should be executed
111    middlewares: Vec<Arc<dyn DMSCMiddleware>>,
112}
113
114impl Default for DMSCMiddlewareChain {
115    fn default() -> Self {
116        Self::new()
117    }
118}
119
120impl DMSCMiddlewareChain {
121    /// Creates a new empty middleware chain.
122    /// 
123    /// # Returns
124    /// 
125    /// A new `DMSCMiddlewareChain` instance with no middleware
126    pub fn new() -> Self {
127        Self {
128            middlewares: Vec::new(),
129        }
130    }
131
132    /// Adds a middleware to the end of the chain.
133    /// 
134    /// # Parameters
135    /// 
136    /// - `middleware`: The middleware to add to the chain
137    pub fn add(&mut self, middleware: Arc<dyn DMSCMiddleware>) {
138        self.middlewares.push(middleware);
139    }
140
141    /// Executes all middleware in the chain on a request.
142    /// 
143    /// Middleware is executed in the order they were added to the chain.
144    /// If any middleware returns an error, execution stops and the error is returned.
145    /// 
146    /// # Parameters
147    /// 
148    /// - `request`: Mutable reference to the request being processed
149    /// 
150    /// # Returns
151    /// 
152    /// A `DMSCResult<()>` indicating success or failure
153    pub async fn execute(&self, request: &mut DMSCGatewayRequest) -> DMSCResult<()> {
154        for middleware in &self.middlewares {
155            // Record middleware execution time
156            let start = std::time::Instant::now();
157            
158            middleware.execute(request).await?;
159            
160            let duration = start.elapsed();
161            let _duration_ms = duration.as_secs_f64() * 1000.0;
162            
163            // Middleware execution time is tracked by the observability module
164            // The metrics are automatically collected when the observability feature is enabled
165        }
166        Ok(())
167    }
168
169    /// Clears all middleware from the chain.
170    pub fn clear(&mut self) {
171        self.middlewares.clear();
172    }
173
174    /// Gets the number of middleware in the chain.
175    /// 
176    /// # Returns
177    /// 
178    /// The number of middleware in the chain
179    pub fn len(&self) -> usize {
180        self.middlewares.len()
181    }
182
183    /// Checks if the middleware chain is empty.
184    /// 
185    /// # Returns
186    /// 
187    /// `true` if the chain contains no middleware, `false` otherwise
188    pub fn is_empty(&self) -> bool {
189        self.middlewares.is_empty()
190    }
191}
192
193// Built-in middleware implementations
194
195/// Authentication middleware for validating request credentials.
196/// 
197/// This middleware checks for and validates authorization headers in requests.
198pub struct DMSCAuthMiddleware {
199    /// Name of the authorization header to check
200    auth_header: String,
201}
202
203impl DMSCAuthMiddleware {
204    /// Creates a new authentication middleware instance.
205    /// 
206    /// # Parameters
207    /// 
208    /// - `auth_header`: Name of the authorization header to check
209    /// 
210    /// # Returns
211    /// 
212    /// A new `DMSCAuthMiddleware` instance
213    pub fn new(auth_header: String) -> Self {
214        Self { auth_header }
215    }
216}
217
218#[async_trait]
219impl DMSCMiddleware for DMSCAuthMiddleware {
220    /// Validates the authorization header in the request.
221    /// 
222    /// This implementation checks for a Bearer token in the specified authorization header.
223    /// In a production environment, this would validate JWT tokens using the auth module.
224    /// 
225    /// # Parameters
226    /// 
227    /// - `request`: Mutable reference to the request being processed
228    /// 
229    /// # Returns
230    /// 
231    /// A `DMSCResult<()>` indicating success or failure
232    async fn execute(&self, request: &mut DMSCGatewayRequest) -> DMSCResult<()> {
233        // Check for authorization header
234        if let Some(auth_header) = request.headers.get(&self.auth_header) {
235            // Basic auth validation - in a real implementation, this would validate JWT tokens
236            if let Some(token) = auth_header.strip_prefix("Bearer ") {
237                if token.is_empty() {
238                    return Err(crate::core::DMSCError::Other("Empty bearer token".to_string()));
239                }
240                // Here you would validate the JWT token using your auth module
241            } else {
242                return Err(crate::core::DMSCError::Other("Invalid authorization header format".to_string()));
243            }
244        } else {
245            // Allow requests without auth for public endpoints
246            // In a real implementation, you'd check if the route requires authentication
247        }
248        Ok(())
249    }
250
251    /// Gets the name of the middleware.
252    /// 
253    /// # Returns
254    /// 
255    /// The string "AuthMiddleware"
256    fn name(&self) -> &'static str {
257        "AuthMiddleware"
258    }
259}
260
261/// CORS (Cross-Origin Resource Sharing) middleware.
262/// 
263/// This middleware validates CORS headers and ensures requests come from allowed origins.
264pub struct DMSCCorsMiddleware {
265    /// List of allowed origins for CORS requests
266    allowed_origins: Vec<String>,
267    /// List of allowed HTTP methods for CORS requests
268    #[allow(dead_code)]
269    allowed_methods: Vec<String>,
270    /// List of allowed headers for CORS requests
271    #[allow(dead_code)]
272    allowed_headers: Vec<String>,
273}
274
275impl DMSCCorsMiddleware {
276    /// Creates a new CORS middleware instance.
277    /// 
278    /// # Parameters
279    /// 
280    /// - `allowed_origins`: List of allowed origins for CORS requests
281    /// - `allowed_methods`: List of allowed HTTP methods for CORS requests
282    /// - `allowed_headers`: List of allowed headers for CORS requests
283    /// 
284    /// # Returns
285    /// 
286    /// A new `DMSCCorsMiddleware` instance
287    pub fn new(
288        allowed_origins: Vec<String>,
289        allowed_methods: Vec<String>,
290        allowed_headers: Vec<String>,
291    ) -> Self {
292        Self {
293            allowed_origins,
294            allowed_methods,
295            allowed_headers,
296        }
297    }
298    
299    /// Checks if an origin is allowed.
300    /// 
301    /// # Parameters
302    /// 
303    /// - `origin`: The origin to check
304    /// 
305    /// # Returns
306    /// 
307    /// `true` if the origin is allowed, `false` otherwise
308    fn is_origin_allowed(&self, origin: &str) -> bool {
309        self.allowed_origins.contains(&"*".to_string()) || 
310        self.allowed_origins.iter().any(|allowed| allowed == origin)
311    }
312}
313
314#[async_trait]
315impl DMSCMiddleware for DMSCCorsMiddleware {
316    /// Validates CORS headers in the request.
317    /// 
318    /// This implementation checks if the request origin is in the list of allowed origins.
319    /// 
320    /// # Parameters
321    /// 
322    /// - `request`: Mutable reference to the request being processed
323    /// 
324    /// # Returns
325    /// 
326    /// A `DMSCResult<()>` indicating success or failure
327    async fn execute(&self, request: &mut DMSCGatewayRequest) -> DMSCResult<()> {
328        // CORS preflight handling would be done at the response level
329        // This middleware just validates the request
330        
331        if let Some(origin) = request.headers.get("origin") {
332            if !self.is_origin_allowed(origin) {
333                return Err(crate::core::DMSCError::Other("Origin not allowed".to_string()));
334            }
335        }
336        
337        Ok(())
338    }
339
340    /// Gets the name of the middleware.
341    /// 
342    /// # Returns
343    /// 
344    /// The string "CorsMiddleware"
345    fn name(&self) -> &'static str {
346        "CorsMiddleware"
347    }
348}
349
350/// Logging middleware for recording request details.
351/// 
352/// This middleware logs request information such as method, path, and remote address.
353pub struct DMSCLoggingMiddleware {
354    /// Log level for the middleware
355    #[allow(dead_code)]
356    log_level: String,
357}
358
359impl DMSCLoggingMiddleware {
360    /// Creates a new logging middleware instance.
361    /// 
362    /// # Parameters
363    /// 
364    /// - `log_level`: Log level for the middleware
365    /// 
366    /// # Returns
367    /// 
368    /// A new `DMSCLoggingMiddleware` instance
369    pub fn new(log_level: String) -> Self {
370        Self { log_level }
371    }
372}
373
374#[async_trait]
375impl DMSCMiddleware for DMSCLoggingMiddleware {
376    /// Logs request details.
377    /// 
378    /// This implementation prints request information to the console.
379    /// In a production environment, this would use a proper logging framework.
380    /// 
381    /// # Parameters
382    /// 
383    /// - `request`: Mutable reference to the request being processed
384    /// 
385    /// # Returns
386    /// 
387    /// A `DMSCResult<()>` indicating success or failure
388    async fn execute(&self, request: &mut DMSCGatewayRequest) -> DMSCResult<()> {
389        // In a real implementation, this would log the request details
390        // For now, we'll just allow it through
391        log::info!("[{}] {} {} from {}", 
392            chrono::Utc::now().format("%Y-%m-%d %H:%M:%S"),
393            request.method,
394            request.path,
395            request.remote_addr
396        );
397        Ok(())
398    }
399
400    /// Gets the name of the middleware.
401    /// 
402    /// # Returns
403    /// 
404    /// The string "LoggingMiddleware"
405    fn name(&self) -> &'static str {
406        "LoggingMiddleware"
407    }
408}
409
410/// Request ID middleware for processing request IDs.
411/// 
412/// This middleware handles request ID generation and processing.
413/// Note: Request IDs are already generated in `DMSCGatewayRequest::new`.
414pub struct DMSCRequestIdMiddleware;
415
416impl Default for DMSCRequestIdMiddleware {
417    fn default() -> Self {
418        Self::new()
419    }
420}
421
422impl DMSCRequestIdMiddleware {
423    /// Creates a new request ID middleware instance.
424    /// 
425    /// # Returns
426    /// 
427    /// A new `DMSCRequestIdMiddleware` instance
428    pub fn new() -> Self {
429        Self
430    }
431}
432
433#[async_trait]
434impl DMSCMiddleware for DMSCRequestIdMiddleware {
435    /// Processes the request ID in the request.
436    /// 
437    /// This implementation is a no-op since request IDs are generated in `DMSCGatewayRequest::new`.
438    /// It can be extended for additional request ID processing.
439    /// 
440    /// # Parameters
441    /// 
442    /// - `_request`: Mutable reference to the request being processed
443    /// 
444    /// # Returns
445    /// 
446    /// A `DMSCResult<()>` indicating success or failure
447    async fn execute(&self, _request: &mut DMSCGatewayRequest) -> DMSCResult<()> {
448        // Request ID is already generated in DMSCGatewayRequest::new
449        // This middleware can be used for additional request ID processing
450        Ok(())
451    }
452
453    /// Gets the name of the middleware.
454    /// 
455    /// # Returns
456    /// 
457    /// The string "RequestIdMiddleware"
458    fn name(&self) -> &'static str {
459        "RequestIdMiddleware"
460    }
461}
462
463/// Rate limiting middleware for controlling request rates.
464/// 
465/// This middleware limits the number of requests from a client within a specified time window.
466pub struct DMSCRateLimitMiddleware {
467    /// Rate limiter instance for enforcing rate limits
468    rate_limiter: Arc<crate::gateway::DMSCRateLimiter>,
469}
470
471impl DMSCRateLimitMiddleware {
472    /// Creates a new rate limiting middleware instance.
473    /// 
474    /// # Parameters
475    /// 
476    /// - `rate_limiter`: Rate limiter instance for enforcing rate limits
477    /// 
478    /// # Returns
479    /// 
480    /// A new `DMSCRateLimitMiddleware` instance
481    pub fn new(rate_limiter: Arc<crate::gateway::DMSCRateLimiter>) -> Self {
482        Self {
483            rate_limiter,
484        }
485    }
486}
487
488#[async_trait]
489impl DMSCMiddleware for DMSCRateLimitMiddleware {
490    /// Applies rate limiting to the request.
491    /// 
492    /// This implementation uses the DMSCRateLimiter to check if the request should be allowed
493    /// based on rate limiting rules. If the request exceeds the rate limit, an error is returned.
494    /// 
495    /// # Parameters
496    /// 
497    /// - `request`: Mutable reference to the request being processed
498    /// 
499    /// # Returns
500    /// 
501    /// A `DMSCResult<()>` indicating success or failure. Returns error if rate limit exceeded.
502    async fn execute(&self, request: &mut DMSCGatewayRequest) -> DMSCResult<()> {
503        // Check rate limit using the rate limiter
504        if !self.rate_limiter.check_request(request).await {
505            return Err(crate::core::DMSCError::Other("Rate limit exceeded".to_string()));
506        }
507        
508        Ok(())
509    }
510
511    /// Gets the name of the middleware.
512    /// 
513    /// # Returns
514    /// 
515    /// The string "RateLimitMiddleware"
516    fn name(&self) -> &'static str {
517        "RateLimitMiddleware"
518    }
519}