mockforge_core/
proxy.rs

1//! Proxy functionality for forwarding requests to upstream services
2//!
3//! This module has been refactored into sub-modules for better organization:
4//! - config: Proxy configuration and rule management
5//! - handler: Request/response handling and processing
6//! - client: HTTP client functionality for upstream requests
7//! - middleware: Proxy middleware and request transformation
8//! - routing: Route matching and rule evaluation
9
10// Re-export sub-modules for backward compatibility
11pub mod body_transform;
12pub mod client;
13pub mod conditional;
14pub mod config;
15pub mod handler;
16pub mod middleware;
17pub mod routing;
18
19// Re-export commonly used types
20pub use body_transform::BodyTransformationMiddleware;
21pub use config::{BodyTransform, BodyTransformRule, MigrationMode, TransformOperation};
22pub use middleware::*;
23pub use routing::*;
24
25// Legacy imports for compatibility
26
27pub use client::{ProxyClient, ProxyResponse};
28pub use conditional::{evaluate_proxy_condition, find_matching_rule};
29/// Legacy types and structures - moved to sub-modules
30/// These are kept for backward compatibility
31// Re-export the main types from sub-modules
32pub use config::{ProxyConfig, ProxyRule};
33pub use handler::ProxyHandler;
34
35// The config and handler modules provide the methods directly
36
37#[cfg(test)]
38mod tests {
39    use super::*;
40    use axum::http::Method;
41
42    #[test]
43    fn test_proxy_config() {
44        let mut config = ProxyConfig::new("http://api.example.com".to_string());
45        config.enabled = true;
46        assert!(config.should_proxy(&Method::GET, "/proxy/users"));
47        assert!(!config.should_proxy(&Method::GET, "/api/users"));
48
49        let stripped = config.strip_prefix("/proxy/users");
50        assert_eq!(stripped, "/users");
51    }
52
53    #[test]
54    fn test_proxy_config_no_prefix() {
55        let mut config = ProxyConfig::new("http://api.example.com".to_string());
56        config.prefix = None;
57        config.enabled = true;
58
59        assert!(config.should_proxy(&Method::GET, "/api/users"));
60        assert!(config.should_proxy(&Method::GET, "/any/path"));
61
62        let stripped = config.strip_prefix("/api/users");
63        assert_eq!(stripped, "/api/users");
64    }
65
66    #[test]
67    fn test_proxy_config_with_rules() {
68        let mut config = ProxyConfig::new("http://default.example.com".to_string());
69        config.enabled = true;
70        config.rules.push(ProxyRule {
71            path_pattern: "/api/users/*".to_string(),
72            target_url: "http://users.example.com".to_string(),
73            enabled: true,
74            pattern: "/api/users/*".to_string(),
75            upstream_url: "http://users.example.com".to_string(),
76            migration_mode: MigrationMode::Auto,
77            migration_group: None,
78            condition: None,
79        });
80        config.rules.push(ProxyRule {
81            path_pattern: "/api/orders/*".to_string(),
82            target_url: "http://orders.example.com".to_string(),
83            enabled: true,
84            pattern: "/api/orders/*".to_string(),
85            upstream_url: "http://orders.example.com".to_string(),
86            migration_mode: MigrationMode::Auto,
87            migration_group: None,
88            condition: None,
89        });
90
91        assert!(config.should_proxy(&Method::GET, "/api/users/123"));
92        assert!(config.should_proxy(&Method::GET, "/api/orders/456"));
93
94        assert_eq!(config.get_upstream_url("/api/users/123"), "http://users.example.com");
95        assert_eq!(config.get_upstream_url("/api/orders/456"), "http://orders.example.com");
96        assert_eq!(config.get_upstream_url("/api/products"), "http://default.example.com");
97    }
98
99    #[test]
100    fn test_proxy_config_passthrough() {
101        let mut config = ProxyConfig::new("http://api.example.com".to_string());
102        config.passthrough_by_default = true;
103        config.prefix = None;
104        config.enabled = true;
105
106        // With passthrough enabled, all requests should be proxied
107        assert!(config.should_proxy(&Method::GET, "/api/users"));
108        assert!(config.should_proxy(&Method::POST, "/api/orders"));
109
110        // Disable passthrough
111        config.passthrough_by_default = false;
112        config.prefix = Some("/proxy".to_string());
113
114        // Now only requests with the prefix should be proxied
115        assert!(config.should_proxy(&Method::GET, "/proxy/users"));
116        assert!(!config.should_proxy(&Method::GET, "/api/users"));
117    }
118}