mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-24 12:44:18 +08:00
fix(codex): fix 404 errors and connection timeout with custom base_url (#760)
* fix(proxy): fix Codex 404 errors with custom base_url prefixes - handlers.rs:268: Remove hardcoded /v1 prefix in Codex forwarding - codex.rs:140: Only add /v1 for origin-only base_urls, dedupe /v1/v1 - stream_check.rs:364: Try /responses first, fallback to /v1/responses - provider.rs:427: Don't force /v1 for custom prefix base_urls Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(codex): always add /v1 for custom prefix base_urls Changed logic to always add /v1 prefix unless base_url already ends with /v1. This fixes 504 timeout errors with relay services that expect /v1 in the path. - Most relay services follow OpenAI standard format: /v1/responses - Users can opt-out by adding /v1 to their base_url configuration - Updated test case to reflect new behavior Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(proxy): allow system proxy on localhost with different ports - Only bypass system proxy if it points to CC Switch's own port (15721) - Allow other localhost proxies (e.g., Clash on 7890) to be used - Add INFO level logging for request URLs to aid debugging This fixes connection timeout issues when using local proxy tools. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(codex): don't add /v1 for custom prefix base_urls Reverted logic to not add /v1 for base_urls with custom prefixes. Many relay services use custom paths without /v1. - Pure origin (e.g., https://api.openai.com) → adds /v1 - With /v1 (e.g., https://api.openai.com/v1) → no change - Custom prefix (e.g., https://example.com/openai) → no /v1 This fixes 404 errors with relay services that don't use /v1 in their paths. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(proxy): use dynamic port for system proxy detection Instead of hardcoding port 15721, now uses the actual configured listen_port from proxy settings. - Added set_proxy_port() to update the port when proxy server starts - Added get_proxy_port() to retrieve current port for detection - Updated server.rs to call set_proxy_port() on startup - Updated tests to reflect new behavior This allows users to change the proxy port in settings without breaking the system proxy detection logic. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(proxy): change default proxy port from 15721 to 5000 Update the default fallback port in get_proxy_port() from 15721 to 5000 to match the project's standard default port configuration. Also updated test cases to use port 5000 consistently. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(proxy): revert default port back to 15721 Revert the default fallback port in get_proxy_port() from 5000 back to 15721 to align with the project's updated default port configuration. Also updated test cases to use port 15721 consistently. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> --------- Co-authored-by: ozbombor <ozbombor@users.noreply.github.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -141,10 +141,33 @@ impl ProviderAdapter for CodexAdapter {
|
||||
let base_trimmed = base_url.trim_end_matches('/');
|
||||
let endpoint_trimmed = endpoint.trim_start_matches('/');
|
||||
|
||||
let mut url = format!("{base_trimmed}/{endpoint_trimmed}");
|
||||
// OpenAI/Codex 的 base_url 可能是:
|
||||
// - 纯 origin: https://api.openai.com (需要自动补 /v1)
|
||||
// - 已含 /v1: https://api.openai.com/v1 (直接拼接)
|
||||
// - 自定义前缀: https://xxx/openai (不添加 /v1,直接拼接)
|
||||
|
||||
// 去除重复的 /v1/v1
|
||||
if url.contains("/v1/v1") {
|
||||
// 检查 base_url 是否已经包含 /v1
|
||||
let already_has_v1 = base_trimmed.ends_with("/v1");
|
||||
|
||||
// 检查是否是纯 origin(没有路径部分)
|
||||
let origin_only = match base_trimmed.split_once("://") {
|
||||
Some((_scheme, rest)) => !rest.contains('/'),
|
||||
None => !base_trimmed.contains('/'),
|
||||
};
|
||||
|
||||
let mut url = if already_has_v1 {
|
||||
// 已经有 /v1,直接拼接
|
||||
format!("{base_trimmed}/{endpoint_trimmed}")
|
||||
} else if origin_only {
|
||||
// 纯 origin,添加 /v1
|
||||
format!("{base_trimmed}/v1/{endpoint_trimmed}")
|
||||
} else {
|
||||
// 自定义前缀,不添加 /v1,直接拼接
|
||||
format!("{base_trimmed}/{endpoint_trimmed}")
|
||||
};
|
||||
|
||||
// 去除重复的 /v1/v1(可能由 base_url 与 endpoint 都带版本导致)
|
||||
while url.contains("/v1/v1") {
|
||||
url = url.replace("/v1/v1", "/v1");
|
||||
}
|
||||
|
||||
@@ -223,6 +246,20 @@ mod tests {
|
||||
assert_eq!(url, "https://api.openai.com/v1/responses");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_build_url_origin_adds_v1() {
|
||||
let adapter = CodexAdapter::new();
|
||||
let url = adapter.build_url("https://api.openai.com", "/responses");
|
||||
assert_eq!(url, "https://api.openai.com/v1/responses");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_build_url_custom_prefix_no_v1() {
|
||||
let adapter = CodexAdapter::new();
|
||||
let url = adapter.build_url("https://example.com/openai", "/responses");
|
||||
assert_eq!(url, "https://example.com/openai/responses");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_build_url_dedup_v1() {
|
||||
let adapter = CodexAdapter::new();
|
||||
|
||||
Reference in New Issue
Block a user