mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-27 16:26:16 +08:00
fix(proxy): resolve 404 error and auto-setup proxy targets
Issues fixed: 1. Route prefix mismatch - Live config was set to use /claude, /codex, /gemini prefixes but server only had routes without prefixes 2. Proxy targets not auto-configured - start_with_takeover only modified Live config but didn't set is_proxy_target=true for current providers Changes: - Add prefixed routes (/claude/v1/messages, /codex/v1/*, /gemini/v1beta/*) to server.rs for backward compatibility - Remove URL prefixes from takeover_live_configs() - server can route by API endpoint path alone (/v1/messages=Claude, /v1/chat/completions=Codex) - Add setup_proxy_targets() method that automatically sets current providers as proxy targets when starting proxy with takeover - Unify proxy toggle in SettingsPage to use takeover mode (same as main UI) - Fix error message extraction in useProxyStatus hooks - Fix provider switch logic to check both takeover flag AND proxy running state
This commit is contained in:
@@ -525,7 +525,10 @@ fn validate_request_url(request_url: &str, base_url: &str) -> Result<(), AppErro
|
||||
|
||||
// 检查端口是否匹配(考虑默认端口)
|
||||
// 使用 port_or_known_default() 会自动处理默认端口(http->80, https->443)
|
||||
match (parsed_request.port_or_known_default(), parsed_base.port_or_known_default()) {
|
||||
match (
|
||||
parsed_request.port_or_known_default(),
|
||||
parsed_base.port_or_known_default(),
|
||||
) {
|
||||
(Some(request_port), Some(base_port)) if request_port == base_port => {
|
||||
// 端口匹配,继续执行
|
||||
}
|
||||
@@ -534,13 +537,11 @@ fn validate_request_url(request_url: &str, base_url: &str) -> Result<(), AppErro
|
||||
"usage_script.request_port_mismatch",
|
||||
format!(
|
||||
"请求端口 {} 必须与 base_url 端口 {} 匹配",
|
||||
request_port,
|
||||
base_port
|
||||
request_port, base_port
|
||||
),
|
||||
format!(
|
||||
"Request port {} must match base_url port {}",
|
||||
request_port,
|
||||
base_port
|
||||
request_port, base_port
|
||||
),
|
||||
));
|
||||
}
|
||||
@@ -774,22 +775,25 @@ mod tests {
|
||||
fn test_https_bypass_prevention() {
|
||||
// 非本地域名的 HTTP 应该被拒绝
|
||||
let result = validate_base_url("http://127.0.0.1.evil.com/api");
|
||||
assert!(result.is_err(), "Should reject HTTP for non-localhost domains");
|
||||
assert!(
|
||||
result.is_err(),
|
||||
"Should reject HTTP for non-localhost domains"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_edge_cases() {
|
||||
// 边界情况测试
|
||||
assert!(is_private_ip("172.16.0.0")); // RFC1918起始
|
||||
assert!(is_private_ip("172.16.0.0")); // RFC1918起始
|
||||
assert!(is_private_ip("172.31.255.255")); // RFC1918结束
|
||||
assert!(is_private_ip("10.0.0.0")); // 10.0.0.0/8起始
|
||||
assert!(is_private_ip("10.0.0.0")); // 10.0.0.0/8起始
|
||||
assert!(is_private_ip("10.255.255.255")); // 10.0.0.0/8结束
|
||||
assert!(is_private_ip("192.168.0.0")); // 192.168.0.0/16起始
|
||||
assert!(is_private_ip("192.168.0.0")); // 192.168.0.0/16起始
|
||||
assert!(is_private_ip("192.168.255.255")); // 192.168.0.0/16结束
|
||||
|
||||
// 紧邻RFC1918的公网地址 - 应该返回false
|
||||
assert!(!is_private_ip("172.15.255.255")); // 172.16.0.0的前一个
|
||||
assert!(!is_private_ip("172.32.0.0")); // 172.31.255.255的后一个
|
||||
assert!(!is_private_ip("172.32.0.0")); // 172.31.255.255的后一个
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -815,27 +819,57 @@ mod tests {
|
||||
// 测试用例:(base_url, request_url, should_match)
|
||||
let test_cases = vec![
|
||||
// HTTPS默认端口测试
|
||||
("https://api.example.com", "https://api.example.com/v1/test", true),
|
||||
("https://api.example.com", "https://api.example.com:443/v1/test", true),
|
||||
("https://api.example.com:443", "https://api.example.com/v1/test", true),
|
||||
("https://api.example.com:443", "https://api.example.com:443/v1/test", true),
|
||||
|
||||
(
|
||||
"https://api.example.com",
|
||||
"https://api.example.com/v1/test",
|
||||
true,
|
||||
),
|
||||
(
|
||||
"https://api.example.com",
|
||||
"https://api.example.com:443/v1/test",
|
||||
true,
|
||||
),
|
||||
(
|
||||
"https://api.example.com:443",
|
||||
"https://api.example.com/v1/test",
|
||||
true,
|
||||
),
|
||||
(
|
||||
"https://api.example.com:443",
|
||||
"https://api.example.com:443/v1/test",
|
||||
true,
|
||||
),
|
||||
// 端口不匹配测试
|
||||
("https://api.example.com", "https://api.example.com:8443/v1/test", false),
|
||||
("https://api.example.com:443", "https://api.example.com:8443/v1/test", false),
|
||||
(
|
||||
"https://api.example.com",
|
||||
"https://api.example.com:8443/v1/test",
|
||||
false,
|
||||
),
|
||||
(
|
||||
"https://api.example.com:443",
|
||||
"https://api.example.com:8443/v1/test",
|
||||
false,
|
||||
),
|
||||
];
|
||||
|
||||
for (base_url, request_url, should_match) in test_cases {
|
||||
let result = validate_request_url(request_url, base_url);
|
||||
|
||||
if should_match {
|
||||
assert!(result.is_ok(),
|
||||
assert!(
|
||||
result.is_ok(),
|
||||
"应该匹配的URL被拒绝: base_url={}, request_url={}, error={}",
|
||||
base_url, request_url, result.unwrap_err());
|
||||
base_url,
|
||||
request_url,
|
||||
result.unwrap_err()
|
||||
);
|
||||
} else {
|
||||
assert!(result.is_err(),
|
||||
assert!(
|
||||
result.is_err(),
|
||||
"应该不匹配的URL被允许: base_url={}, request_url={}",
|
||||
base_url, request_url);
|
||||
base_url,
|
||||
request_url
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user