From ce34d010ea41c0f4e0d5fe3658d2571df4ea8210 Mon Sep 17 00:00:00 2001 From: nosqli Date: Fri, 22 Aug 2025 00:00:03 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0Claude=E6=B8=A0=E9=81=93?= =?UTF-8?q?=E8=AF=B7=E6=B1=82=E7=A9=BF=E9=80=8F=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修改 relay/channel/claude/adaptor.go 支持请求头穿透 - 穿透模式下保持原始请求头完整性,仅替换必要的API密钥 - 非穿透模式保持原有逻辑不变 - 新增 docker-compose-custom.yml 用于自定义版本部署 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- docker-compose-custom.yml | 34 +++++++++++++++++++++++++++++++++ relay/channel/claude/adaptor.go | 34 ++++++++++++++++++++++++++------- 2 files changed, 61 insertions(+), 7 deletions(-) create mode 100644 docker-compose-custom.yml diff --git a/docker-compose-custom.yml b/docker-compose-custom.yml new file mode 100644 index 00000000..1ab3d859 --- /dev/null +++ b/docker-compose-custom.yml @@ -0,0 +1,34 @@ +version: '3.4' + +services: + new-api-custom: + image: new-api-custom:latest + container_name: new-api-custom + restart: always + command: --log-dir /app/logs + ports: + - "3099:3000" # 使用3099端口 + volumes: + - ./data:/data # 共享相同数据目录 + - ./logs-custom:/app/logs # 使用独立日志目录 + environment: + - SQL_DSN=root:123456@tcp(mysql:3306)/new-api # 连接现有的mysql容器 + - REDIS_CONN_STRING=redis://redis # 连接现有的redis容器 + - TZ=Asia/Shanghai + - ERROR_LOG_ENABLED=true + # - STREAMING_TIMEOUT=120 + # - SESSION_SECRET=random_string # 如果需要多机部署 + healthcheck: + test: ["CMD-SHELL", "wget -q -O - http://localhost:3000/api/status | grep -o '\"success\":\\s*true' | awk -F: '{print $$2}'"] + interval: 30s + timeout: 10s + retries: 3 + networks: + - new-api_default # 连接到现有的网络,复用现有的 redis 和 mysql + +# 不定义 redis 和 mysql 服务,直接使用现有运行的容器 +# 只需要连接到相同的网络即可访问 + +networks: + new-api_default: + external: true # 使用现有的网络 \ No newline at end of file diff --git a/relay/channel/claude/adaptor.go b/relay/channel/claude/adaptor.go index 540742d6..c715c0c9 100644 --- a/relay/channel/claude/adaptor.go +++ b/relay/channel/claude/adaptor.go @@ -55,14 +55,34 @@ func (a *Adaptor) GetRequestURL(info *relaycommon.RelayInfo) (string, error) { } func (a *Adaptor) SetupRequestHeader(c *gin.Context, req *http.Header, info *relaycommon.RelayInfo) error { - channel.SetupApiRequestHeader(info, c, req) - req.Set("x-api-key", info.ApiKey) - anthropicVersion := c.Request.Header.Get("anthropic-version") - if anthropicVersion == "" { - anthropicVersion = "2023-06-01" + if model_setting.GetGlobalSettings().PassThroughRequestEnabled { + // 穿透模式:直接复制原始请求头,但跳过系统级头信息 + for key, values := range c.Request.Header { + keyLower := strings.ToLower(key) + if keyLower == "host" || keyLower == "content-length" || keyLower == "connection" { + continue + } + for _, value := range values { + req.Add(key, value) + } + } + } else { + // 非穿透模式:使用通用设置 + channel.SetupApiRequestHeader(info, c, req) + } + + // 无论哪种模式都需要设置正确的API密钥 + req.Set("x-api-key", info.ApiKey) + + if !model_setting.GetGlobalSettings().PassThroughRequestEnabled { + // 非穿透模式才强制设置这些头 + anthropicVersion := c.Request.Header.Get("anthropic-version") + if anthropicVersion == "" { + anthropicVersion = "2023-06-01" + } + req.Set("anthropic-version", anthropicVersion) + model_setting.GetClaudeSettings().WriteHeaders(info.OriginModelName, req) } - req.Set("anthropic-version", anthropicVersion) - model_setting.GetClaudeSettings().WriteHeaders(info.OriginModelName, req) return nil }