mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-27 16:26:16 +08:00
refactor(proxy): remove unused request handlers and routes
- Remove unused GET/DELETE request forwarding methods - Remove count_tokens, get/delete response handlers - Simplify router by removing unused endpoints - Keep only essential routes: /v1/messages, /v1/responses, /v1beta/*
This commit is contained in:
@@ -462,205 +462,3 @@ enum AuthType {
|
||||
Gemini,
|
||||
Bearer,
|
||||
}
|
||||
|
||||
impl RequestForwarder {
|
||||
/// 转发 GET 请求(带重试和故障转移)
|
||||
pub async fn forward_get_request(
|
||||
&self,
|
||||
app_type: &AppType,
|
||||
endpoint: &str,
|
||||
headers: axum::http::HeaderMap,
|
||||
) -> Result<Response, ProxyError> {
|
||||
let mut failed_ids = Vec::new();
|
||||
|
||||
for attempt in 0..self.max_retries {
|
||||
let provider = self.router.select_provider(app_type, &failed_ids).await?;
|
||||
|
||||
log::debug!(
|
||||
"GET 尝试 {} - 使用Provider: {} ({})",
|
||||
attempt + 1,
|
||||
provider.name,
|
||||
provider.id
|
||||
);
|
||||
|
||||
match self.forward_get(&provider, endpoint, &headers).await {
|
||||
Ok(response) => {
|
||||
self.router
|
||||
.update_health(&provider, app_type, true, None)
|
||||
.await;
|
||||
return Ok(response);
|
||||
}
|
||||
Err(e) => {
|
||||
let category = self.categorize_proxy_error(&e);
|
||||
match category {
|
||||
ErrorCategory::Retryable => {
|
||||
self.router
|
||||
.update_health(&provider, app_type, false, Some(e.to_string()))
|
||||
.await;
|
||||
failed_ids.push(provider.id.clone());
|
||||
continue;
|
||||
}
|
||||
_ => return Err(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Err(ProxyError::MaxRetriesExceeded)
|
||||
}
|
||||
|
||||
/// 转发 DELETE 请求(带重试和故障转移)
|
||||
pub async fn forward_delete_request(
|
||||
&self,
|
||||
app_type: &AppType,
|
||||
endpoint: &str,
|
||||
headers: axum::http::HeaderMap,
|
||||
) -> Result<Response, ProxyError> {
|
||||
let mut failed_ids = Vec::new();
|
||||
|
||||
for attempt in 0..self.max_retries {
|
||||
let provider = self.router.select_provider(app_type, &failed_ids).await?;
|
||||
|
||||
log::debug!(
|
||||
"DELETE 尝试 {} - 使用Provider: {} ({})",
|
||||
attempt + 1,
|
||||
provider.name,
|
||||
provider.id
|
||||
);
|
||||
|
||||
match self.forward_delete(&provider, endpoint, &headers).await {
|
||||
Ok(response) => {
|
||||
self.router
|
||||
.update_health(&provider, app_type, true, None)
|
||||
.await;
|
||||
return Ok(response);
|
||||
}
|
||||
Err(e) => {
|
||||
let category = self.categorize_proxy_error(&e);
|
||||
match category {
|
||||
ErrorCategory::Retryable => {
|
||||
self.router
|
||||
.update_health(&provider, app_type, false, Some(e.to_string()))
|
||||
.await;
|
||||
failed_ids.push(provider.id.clone());
|
||||
continue;
|
||||
}
|
||||
_ => return Err(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Err(ProxyError::MaxRetriesExceeded)
|
||||
}
|
||||
|
||||
/// 转发单个 GET 请求
|
||||
async fn forward_get(
|
||||
&self,
|
||||
provider: &Provider,
|
||||
endpoint: &str,
|
||||
headers: &axum::http::HeaderMap,
|
||||
) -> Result<Response, ProxyError> {
|
||||
let base_url = self.extract_base_url(provider)?;
|
||||
let url = self.build_full_url(&base_url, endpoint);
|
||||
|
||||
log::info!("Proxy GET Request URL: {url}");
|
||||
|
||||
let mut request = self.client.get(&url);
|
||||
|
||||
// 透传 Headers
|
||||
for (key, value) in headers {
|
||||
let key_str = key.as_str().to_lowercase();
|
||||
if key_str == "host"
|
||||
|| key_str == "content-length"
|
||||
|| key_str == "accept-encoding"
|
||||
|| key_str == "x-api-key"
|
||||
|| key_str == "authorization"
|
||||
|| key_str == "x-goog-api-key"
|
||||
|| key_str == "anthropic-version"
|
||||
{
|
||||
continue;
|
||||
}
|
||||
request = request.header(key, value);
|
||||
}
|
||||
|
||||
request = self.add_auth_headers(request, provider)?;
|
||||
|
||||
let response = request.send().await.map_err(|e| {
|
||||
if e.is_timeout() {
|
||||
ProxyError::Timeout(format!("请求超时: {e}"))
|
||||
} else if e.is_connect() {
|
||||
ProxyError::ForwardFailed(format!("连接失败: {e}"))
|
||||
} else {
|
||||
ProxyError::ForwardFailed(e.to_string())
|
||||
}
|
||||
})?;
|
||||
|
||||
let status = response.status();
|
||||
if status.is_success() {
|
||||
Ok(response)
|
||||
} else {
|
||||
let status_code = status.as_u16();
|
||||
let body_text = response.text().await.ok();
|
||||
Err(ProxyError::UpstreamError {
|
||||
status: status_code,
|
||||
body: body_text,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// 转发单个 DELETE 请求
|
||||
async fn forward_delete(
|
||||
&self,
|
||||
provider: &Provider,
|
||||
endpoint: &str,
|
||||
headers: &axum::http::HeaderMap,
|
||||
) -> Result<Response, ProxyError> {
|
||||
let base_url = self.extract_base_url(provider)?;
|
||||
let url = self.build_full_url(&base_url, endpoint);
|
||||
|
||||
log::info!("Proxy DELETE Request URL: {url}");
|
||||
|
||||
let mut request = self.client.delete(&url);
|
||||
|
||||
// 透传 Headers
|
||||
for (key, value) in headers {
|
||||
let key_str = key.as_str().to_lowercase();
|
||||
if key_str == "host"
|
||||
|| key_str == "content-length"
|
||||
|| key_str == "accept-encoding"
|
||||
|| key_str == "x-api-key"
|
||||
|| key_str == "authorization"
|
||||
|| key_str == "x-goog-api-key"
|
||||
|| key_str == "anthropic-version"
|
||||
{
|
||||
continue;
|
||||
}
|
||||
request = request.header(key, value);
|
||||
}
|
||||
|
||||
request = self.add_auth_headers(request, provider)?;
|
||||
|
||||
let response = request.send().await.map_err(|e| {
|
||||
if e.is_timeout() {
|
||||
ProxyError::Timeout(format!("请求超时: {e}"))
|
||||
} else if e.is_connect() {
|
||||
ProxyError::ForwardFailed(format!("连接失败: {e}"))
|
||||
} else {
|
||||
ProxyError::ForwardFailed(e.to_string())
|
||||
}
|
||||
})?;
|
||||
|
||||
let status = response.status();
|
||||
if status.is_success() {
|
||||
Ok(response)
|
||||
} else {
|
||||
let status_code = status.as_u16();
|
||||
let body_text = response.text().await.ok();
|
||||
Err(ProxyError::UpstreamError {
|
||||
status: status_code,
|
||||
body: body_text,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,35 +64,6 @@ pub async fn handle_messages(
|
||||
Ok(builder.body(body).unwrap())
|
||||
}
|
||||
|
||||
/// 处理 /v1/messages/count_tokens 请求(透传)
|
||||
pub async fn handle_count_tokens(
|
||||
State(state): State<ProxyState>,
|
||||
headers: axum::http::HeaderMap,
|
||||
Json(body): Json<Value>,
|
||||
) -> Result<axum::response::Response, ProxyError> {
|
||||
let config = state.config.read().await.clone();
|
||||
let forwarder = RequestForwarder::new(
|
||||
state.db.clone(),
|
||||
config.request_timeout,
|
||||
config.max_retries,
|
||||
state.status.clone(),
|
||||
);
|
||||
|
||||
let response = forwarder
|
||||
.forward_with_retry(&AppType::Claude, "/v1/messages/count_tokens", body, headers)
|
||||
.await?;
|
||||
|
||||
// 透传响应
|
||||
let mut builder = axum::response::Response::builder().status(response.status());
|
||||
|
||||
for (key, value) in response.headers() {
|
||||
builder = builder.header(key, value);
|
||||
}
|
||||
|
||||
let body = axum::body::Body::from_stream(response.bytes_stream());
|
||||
Ok(builder.body(body).unwrap())
|
||||
}
|
||||
|
||||
/// 处理 Gemini API 请求(透传,包括查询参数)
|
||||
pub async fn handle_gemini(
|
||||
State(state): State<ProxyState>,
|
||||
@@ -159,93 +130,3 @@ pub async fn handle_responses(
|
||||
let body = axum::body::Body::from_stream(response.bytes_stream());
|
||||
Ok(builder.body(body).unwrap())
|
||||
}
|
||||
|
||||
/// 获取单个 Response(GET /v1/responses/:response_id 透传)
|
||||
pub async fn handle_get_response(
|
||||
State(state): State<ProxyState>,
|
||||
axum::extract::Path(response_id): axum::extract::Path<String>,
|
||||
headers: axum::http::HeaderMap,
|
||||
) -> Result<axum::response::Response, ProxyError> {
|
||||
let config = state.config.read().await.clone();
|
||||
let forwarder = RequestForwarder::new(
|
||||
state.db.clone(),
|
||||
config.request_timeout,
|
||||
config.max_retries,
|
||||
state.status.clone(),
|
||||
);
|
||||
|
||||
let endpoint = format!("/v1/responses/{response_id}");
|
||||
let response = forwarder
|
||||
.forward_get_request(&AppType::Codex, &endpoint, headers)
|
||||
.await?;
|
||||
|
||||
// 透传响应
|
||||
let mut builder = axum::response::Response::builder().status(response.status());
|
||||
|
||||
for (key, value) in response.headers() {
|
||||
builder = builder.header(key, value);
|
||||
}
|
||||
|
||||
let body = axum::body::Body::from_stream(response.bytes_stream());
|
||||
Ok(builder.body(body).unwrap())
|
||||
}
|
||||
|
||||
/// 删除 Response(DELETE /v1/responses/:response_id 透传)
|
||||
pub async fn handle_delete_response(
|
||||
State(state): State<ProxyState>,
|
||||
axum::extract::Path(response_id): axum::extract::Path<String>,
|
||||
headers: axum::http::HeaderMap,
|
||||
) -> Result<axum::response::Response, ProxyError> {
|
||||
let config = state.config.read().await.clone();
|
||||
let forwarder = RequestForwarder::new(
|
||||
state.db.clone(),
|
||||
config.request_timeout,
|
||||
config.max_retries,
|
||||
state.status.clone(),
|
||||
);
|
||||
|
||||
let endpoint = format!("/v1/responses/{response_id}");
|
||||
let response = forwarder
|
||||
.forward_delete_request(&AppType::Codex, &endpoint, headers)
|
||||
.await?;
|
||||
|
||||
// 透传响应
|
||||
let mut builder = axum::response::Response::builder().status(response.status());
|
||||
|
||||
for (key, value) in response.headers() {
|
||||
builder = builder.header(key, value);
|
||||
}
|
||||
|
||||
let body = axum::body::Body::from_stream(response.bytes_stream());
|
||||
Ok(builder.body(body).unwrap())
|
||||
}
|
||||
|
||||
/// 获取 Response 的输入项(GET /v1/responses/:response_id/input_items 透传)
|
||||
pub async fn handle_get_response_input_items(
|
||||
State(state): State<ProxyState>,
|
||||
axum::extract::Path(response_id): axum::extract::Path<String>,
|
||||
headers: axum::http::HeaderMap,
|
||||
) -> Result<axum::response::Response, ProxyError> {
|
||||
let config = state.config.read().await.clone();
|
||||
let forwarder = RequestForwarder::new(
|
||||
state.db.clone(),
|
||||
config.request_timeout,
|
||||
config.max_retries,
|
||||
state.status.clone(),
|
||||
);
|
||||
|
||||
let endpoint = format!("/v1/responses/{response_id}/input_items");
|
||||
let response = forwarder
|
||||
.forward_get_request(&AppType::Codex, &endpoint, headers)
|
||||
.await?;
|
||||
|
||||
// 透传响应
|
||||
let mut builder = axum::response::Response::builder().status(response.status());
|
||||
|
||||
for (key, value) in response.headers() {
|
||||
builder = builder.header(key, value);
|
||||
}
|
||||
|
||||
let body = axum::body::Body::from_stream(response.bytes_stream());
|
||||
Ok(builder.body(body).unwrap())
|
||||
}
|
||||
|
||||
@@ -148,22 +148,9 @@ impl ProxyServer {
|
||||
.route("/status", get(handlers::get_status))
|
||||
// Claude API
|
||||
.route("/v1/messages", post(handlers::handle_messages))
|
||||
.route(
|
||||
"/v1/messages/count_tokens",
|
||||
post(handlers::handle_count_tokens),
|
||||
)
|
||||
// OpenAI Responses API (Codex CLI)
|
||||
.route("/v1/responses", post(handlers::handle_responses))
|
||||
.route(
|
||||
"/v1/responses/:response_id",
|
||||
get(handlers::handle_get_response).delete(handlers::handle_delete_response),
|
||||
)
|
||||
.route(
|
||||
"/v1/responses/:response_id/input_items",
|
||||
get(handlers::handle_get_response_input_items),
|
||||
)
|
||||
// Gemini API (通配符路由)
|
||||
.route("/v1/*path", post(handlers::handle_gemini))
|
||||
// Gemini API
|
||||
.route("/v1beta/*path", post(handlers::handle_gemini))
|
||||
.layer(cors)
|
||||
.with_state(self.state.clone())
|
||||
|
||||
Reference in New Issue
Block a user