diff --git a/src/services/relay/claudeRelayService.js b/src/services/relay/claudeRelayService.js index 757fb09f..a0062514 100644 --- a/src/services/relay/claudeRelayService.js +++ b/src/services/relay/claudeRelayService.js @@ -2386,7 +2386,28 @@ class ClaudeRelayService { const requestedModel = body?.model || 'unknown' const { isRealClaudeCodeRequest } = requestOptions - res.on('data', (chunk) => { + // 🔧 处理上游 gzip/deflate 压缩:Anthropic (经 Cloudflare) 可能返回压缩响应 + const upstreamEncoding = res.headers['content-encoding'] + let dataSource = res + if (upstreamEncoding === 'gzip') { + dataSource = res.pipe(zlib.createGunzip()) + dataSource.on('error', (err) => { + logger.error('❌ Gzip decompression error in stream:', err.message) + if (isStreamWritable(responseStream)) { + responseStream.end() + } + }) + } else if (upstreamEncoding === 'deflate') { + dataSource = res.pipe(zlib.createInflate()) + dataSource.on('error', (err) => { + logger.error('❌ Deflate decompression error in stream:', err.message) + if (isStreamWritable(responseStream)) { + responseStream.end() + } + }) + } + + dataSource.on('data', (chunk) => { try { const chunkStr = chunk.toString() @@ -2531,7 +2552,7 @@ class ClaudeRelayService { } }) - res.on('end', async () => { + dataSource.on('end', async () => { try { // 处理缓冲区中剩余的数据 if (buffer.trim() && isStreamWritable(responseStream)) {