mirror of
https://github.com/aiclientproxy/proxycast.git
synced 2026-09-24 23:10:56 +08:00
fix: improve streaming response stability for Windows
- Add proper HTTP client timeout configuration for ClaudeCustomProvider - connect_timeout: 30 seconds - timeout: 10 minutes (for long streaming responses) - tcp_keepalive: 60 seconds (keep connection alive) - Enhance SSE streaming response headers: - Cache-Control: no-cache, no-store, must-revalidate - X-Accel-Buffering: no (disable nginx proxy buffering) - Transfer-Encoding: chunked These changes should help resolve streaming truncation issues on Windows when using Kiro OAuth credentials through aiclient2api proxy. Fixes #68 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,7 @@ use crate::models::openai::{ChatCompletionRequest, ContentPart, MessageContent};
|
||||
use reqwest::Client;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::error::Error;
|
||||
use std::time::Duration;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||
pub struct ClaudeCustomConfig {
|
||||
@@ -17,11 +18,26 @@ pub struct ClaudeCustomProvider {
|
||||
pub client: Client,
|
||||
}
|
||||
|
||||
/// 创建配置好的 HTTP 客户端
|
||||
///
|
||||
/// 配置说明:
|
||||
/// - connect_timeout: 连接超时 30 秒
|
||||
/// - timeout: 总超时 10 分钟(流式响应可能很长)
|
||||
/// - 不设置 pool_idle_timeout 以保持连接活跃
|
||||
fn create_http_client() -> Client {
|
||||
Client::builder()
|
||||
.connect_timeout(Duration::from_secs(30))
|
||||
.timeout(Duration::from_secs(600)) // 10 分钟总超时,支持长时间流式响应
|
||||
.tcp_keepalive(Duration::from_secs(60)) // TCP keepalive 保持连接活跃
|
||||
.build()
|
||||
.unwrap_or_else(|_| Client::new())
|
||||
}
|
||||
|
||||
impl Default for ClaudeCustomProvider {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
config: ClaudeCustomConfig::default(),
|
||||
client: Client::new(),
|
||||
client: create_http_client(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -39,7 +55,7 @@ impl ClaudeCustomProvider {
|
||||
base_url,
|
||||
enabled: true,
|
||||
},
|
||||
client: Client::new(),
|
||||
client: create_http_client(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -611,8 +611,10 @@ pub async fn call_provider_anthropic(
|
||||
return Response::builder()
|
||||
.status(StatusCode::OK)
|
||||
.header(header::CONTENT_TYPE, "text/event-stream")
|
||||
.header(header::CACHE_CONTROL, "no-cache")
|
||||
.header(header::CACHE_CONTROL, "no-cache, no-store, must-revalidate")
|
||||
.header("Connection", "keep-alive")
|
||||
.header("X-Accel-Buffering", "no") // 禁用 nginx 等代理的缓冲
|
||||
.header("Transfer-Encoding", "chunked")
|
||||
.body(Body::from_stream(stream))
|
||||
.unwrap_or_else(|_| {
|
||||
(
|
||||
@@ -823,8 +825,10 @@ pub async fn call_provider_anthropic(
|
||||
return Response::builder()
|
||||
.status(StatusCode::OK)
|
||||
.header(header::CONTENT_TYPE, "text/event-stream")
|
||||
.header(header::CACHE_CONTROL, "no-cache")
|
||||
.header(header::CACHE_CONTROL, "no-cache, no-store, must-revalidate")
|
||||
.header("Connection", "keep-alive")
|
||||
.header("X-Accel-Buffering", "no") // 禁用 nginx 等代理的缓冲
|
||||
.header("Transfer-Encoding", "chunked")
|
||||
.body(Body::from_stream(stream))
|
||||
.unwrap_or_else(|_| {
|
||||
(
|
||||
@@ -1834,8 +1838,10 @@ pub async fn call_provider_openai(
|
||||
return Response::builder()
|
||||
.status(StatusCode::OK)
|
||||
.header(header::CONTENT_TYPE, "text/event-stream")
|
||||
.header(header::CACHE_CONTROL, "no-cache")
|
||||
.header(header::CACHE_CONTROL, "no-cache, no-store, must-revalidate")
|
||||
.header("Connection", "keep-alive")
|
||||
.header("X-Accel-Buffering", "no") // 禁用 nginx 等代理的缓冲
|
||||
.header("Transfer-Encoding", "chunked")
|
||||
.body(Body::from_stream(stream))
|
||||
.unwrap_or_else(|_| {
|
||||
(
|
||||
|
||||
Reference in New Issue
Block a user