diff --git a/src/routes/admin.js b/src/routes/admin.js index 77707fa1..d7eff858 100644 --- a/src/routes/admin.js +++ b/src/routes/admin.js @@ -7183,6 +7183,7 @@ router.post('/openai-accounts/exchange-code', authenticateAdmin, async (req, res // 配置代理(如果有) const proxyAgent = ProxyHelper.createProxyAgent(sessionData.proxy) if (proxyAgent) { + axiosConfig.httpAgent = proxyAgent axiosConfig.httpsAgent = proxyAgent axiosConfig.proxy = false } diff --git a/src/routes/openaiRoutes.js b/src/routes/openaiRoutes.js index bfebcd0f..6367241e 100644 --- a/src/routes/openaiRoutes.js +++ b/src/routes/openaiRoutes.js @@ -332,6 +332,7 @@ const handleResponses = async (req, res) => { // 如果有代理,添加代理配置 if (proxyAgent) { + axiosConfig.httpAgent = proxyAgent axiosConfig.httpsAgent = proxyAgent axiosConfig.proxy = false logger.info(`🌐 Using proxy for OpenAI request: ${ProxyHelper.getProxyDescription(proxy)}`) diff --git a/src/services/azureOpenaiRelayService.js b/src/services/azureOpenaiRelayService.js index b6e9ecd5..e1a09e02 100644 --- a/src/services/azureOpenaiRelayService.js +++ b/src/services/azureOpenaiRelayService.js @@ -82,7 +82,9 @@ async function handleAzureOpenAIRequest({ // 如果有代理,添加代理配置 if (proxyAgent) { + axiosConfig.httpAgent = proxyAgent axiosConfig.httpsAgent = proxyAgent + axiosConfig.proxy = false // 为代理添加额外的keep-alive设置 if (proxyAgent.options) { proxyAgent.options.keepAlive = true diff --git a/src/services/ccrRelayService.js b/src/services/ccrRelayService.js index 8fca408d..50ad7b58 100644 --- a/src/services/ccrRelayService.js +++ b/src/services/ccrRelayService.js @@ -121,12 +121,17 @@ class CcrRelayService { 'User-Agent': userAgent, ...filteredHeaders }, - httpsAgent: proxyAgent, timeout: config.requestTimeout || 600000, signal: abortController.signal, validateStatus: () => true // 接受所有状态码 } + if (proxyAgent) { + requestConfig.httpAgent = proxyAgent + requestConfig.httpsAgent = proxyAgent + requestConfig.proxy = false + } + // 根据 API Key 格式选择认证方式 if (account.apiKey && account.apiKey.startsWith('sk-ant-')) { // Anthropic 官方 API Key 使用 x-api-key @@ -345,12 +350,17 @@ class CcrRelayService { 'User-Agent': userAgent, ...filteredHeaders }, - httpsAgent: proxyAgent, timeout: config.requestTimeout || 600000, responseType: 'stream', validateStatus: () => true // 接受所有状态码 } + if (proxyAgent) { + requestConfig.httpAgent = proxyAgent + requestConfig.httpsAgent = proxyAgent + requestConfig.proxy = false + } + // 根据 API Key 格式选择认证方式 if (account.apiKey && account.apiKey.startsWith('sk-ant-')) { // Anthropic 官方 API Key 使用 x-api-key diff --git a/src/services/claudeAccountService.js b/src/services/claudeAccountService.js index 40b6a59c..e36f9832 100644 --- a/src/services/claudeAccountService.js +++ b/src/services/claudeAccountService.js @@ -248,6 +248,24 @@ class ClaudeAccountService { // 创建代理agent const agent = this._createProxyAgent(accountData.proxy) + const axiosConfig = { + headers: { + 'Content-Type': 'application/json', + Accept: 'application/json, text/plain, */*', + 'User-Agent': 'claude-cli/1.0.56 (external, cli)', + 'Accept-Language': 'en-US,en;q=0.9', + Referer: 'https://claude.ai/', + Origin: 'https://claude.ai' + }, + timeout: 30000 + } + + if (agent) { + axiosConfig.httpAgent = agent + axiosConfig.httpsAgent = agent + axiosConfig.proxy = false + } + const response = await axios.post( this.claudeApiUrl, { @@ -255,18 +273,7 @@ class ClaudeAccountService { refresh_token: refreshToken, client_id: this.claudeOauthClientId }, - { - headers: { - 'Content-Type': 'application/json', - Accept: 'application/json, text/plain, */*', - 'User-Agent': 'claude-cli/1.0.56 (external, cli)', - 'Accept-Language': 'en-US,en;q=0.9', - Referer: 'https://claude.ai/', - Origin: 'https://claude.ai' - }, - httpsAgent: agent, - timeout: 30000 - } + axiosConfig ) if (response.status === 200) { @@ -1824,7 +1831,7 @@ class ClaudeAccountService { logger.debug(`📊 Fetching OAuth usage for account: ${accountData.name} (${accountId})`) // 请求 OAuth usage 接口 - const response = await axios.get('https://api.anthropic.com/api/oauth/usage', { + const axiosConfig = { headers: { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/json', @@ -1833,9 +1840,16 @@ class ClaudeAccountService { 'User-Agent': 'claude-cli/1.0.56 (external, cli)', 'Accept-Language': 'en-US,en;q=0.9' }, - httpsAgent: agent, timeout: 15000 - }) + } + + if (agent) { + axiosConfig.httpAgent = agent + axiosConfig.httpsAgent = agent + axiosConfig.proxy = false + } + + const response = await axios.get('https://api.anthropic.com/api/oauth/usage', axiosConfig) if (response.status === 200 && response.data) { logger.debug('✅ Successfully fetched OAuth usage data:', { @@ -2003,7 +2017,7 @@ class ClaudeAccountService { logger.info(`📊 Fetching profile info for account: ${accountData.name} (${accountId})`) // 请求 profile 接口 - const response = await axios.get('https://api.anthropic.com/api/oauth/profile', { + const axiosConfig = { headers: { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/json', @@ -2011,9 +2025,16 @@ class ClaudeAccountService { 'User-Agent': 'claude-cli/1.0.56 (external, cli)', 'Accept-Language': 'en-US,en;q=0.9' }, - httpsAgent: agent, timeout: 15000 - }) + } + + if (agent) { + axiosConfig.httpAgent = agent + axiosConfig.httpsAgent = agent + axiosConfig.proxy = false + } + + const response = await axios.get('https://api.anthropic.com/api/oauth/profile', axiosConfig) if (response.status === 200 && response.data) { const profileData = response.data diff --git a/src/services/claudeConsoleRelayService.js b/src/services/claudeConsoleRelayService.js index f1d3da96..0a63aae3 100644 --- a/src/services/claudeConsoleRelayService.js +++ b/src/services/claudeConsoleRelayService.js @@ -127,12 +127,17 @@ class ClaudeConsoleRelayService { 'User-Agent': userAgent, ...filteredHeaders }, - httpsAgent: proxyAgent, timeout: config.requestTimeout || 600000, signal: abortController.signal, validateStatus: () => true // 接受所有状态码 } + if (proxyAgent) { + requestConfig.httpAgent = proxyAgent + requestConfig.httpsAgent = proxyAgent + requestConfig.proxy = false + } + // 根据 API Key 格式选择认证方式 if (account.apiKey && account.apiKey.startsWith('sk-ant-')) { // Anthropic 官方 API Key 使用 x-api-key @@ -414,12 +419,17 @@ class ClaudeConsoleRelayService { 'User-Agent': userAgent, ...filteredHeaders }, - httpsAgent: proxyAgent, timeout: config.requestTimeout || 600000, responseType: 'stream', validateStatus: () => true // 接受所有状态码 } + if (proxyAgent) { + requestConfig.httpAgent = proxyAgent + requestConfig.httpsAgent = proxyAgent + requestConfig.proxy = false + } + // 根据 API Key 格式选择认证方式 if (account.apiKey && account.apiKey.startsWith('sk-ant-')) { // Anthropic 官方 API Key 使用 x-api-key diff --git a/src/services/droidAccountService.js b/src/services/droidAccountService.js index a27ac935..25e33485 100644 --- a/src/services/droidAccountService.js +++ b/src/services/droidAccountService.js @@ -438,6 +438,7 @@ class DroidAccountService { if (proxyAgent) { requestOptions.httpAgent = proxyAgent requestOptions.httpsAgent = proxyAgent + requestOptions.proxy = false logger.info( `🌐 使用代理验证 Droid Refresh Token: ${ProxyHelper.getProxyDescription(proxyConfig)}` ) @@ -506,6 +507,7 @@ class DroidAccountService { if (proxyAgent) { requestOptions.httpAgent = proxyAgent requestOptions.httpsAgent = proxyAgent + requestOptions.proxy = false } } diff --git a/src/services/droidRelayService.js b/src/services/droidRelayService.js index 45f1b229..04b62699 100644 --- a/src/services/droidRelayService.js +++ b/src/services/droidRelayService.js @@ -309,7 +309,8 @@ class DroidRelayService { responseType: 'json', ...(proxyAgent && { httpAgent: proxyAgent, - httpsAgent: proxyAgent + httpsAgent: proxyAgent, + proxy: false }) } diff --git a/src/services/geminiAccountService.js b/src/services/geminiAccountService.js index d15970c8..2e35966e 100644 --- a/src/services/geminiAccountService.js +++ b/src/services/geminiAccountService.js @@ -1081,7 +1081,9 @@ async function loadCodeAssist(client, projectId = null, proxyConfig = null) { } if (proxyAgent) { + tokenInfoConfig.httpAgent = proxyAgent tokenInfoConfig.httpsAgent = proxyAgent + tokenInfoConfig.proxy = false } try { @@ -1102,7 +1104,9 @@ async function loadCodeAssist(client, projectId = null, proxyConfig = null) { } if (proxyAgent) { + userInfoConfig.httpAgent = proxyAgent userInfoConfig.httpsAgent = proxyAgent + userInfoConfig.proxy = false } try { @@ -1146,7 +1150,9 @@ async function loadCodeAssist(client, projectId = null, proxyConfig = null) { // 添加代理配置 if (proxyAgent) { + axiosConfig.httpAgent = proxyAgent axiosConfig.httpsAgent = proxyAgent + axiosConfig.proxy = false logger.info( `🌐 Using proxy for Gemini loadCodeAssist: ${ProxyHelper.getProxyDescription(proxyConfig)}` ) @@ -1220,7 +1226,9 @@ async function onboardUser(client, tierId, projectId, clientMetadata, proxyConfi // 添加代理配置 const proxyAgent = ProxyHelper.createProxyAgent(proxyConfig) if (proxyAgent) { + baseAxiosConfig.httpAgent = proxyAgent baseAxiosConfig.httpsAgent = proxyAgent + baseAxiosConfig.proxy = false logger.info( `🌐 Using proxy for Gemini onboardUser: ${ProxyHelper.getProxyDescription(proxyConfig)}` ) @@ -1351,7 +1359,9 @@ async function countTokens(client, contents, model = 'gemini-2.0-flash-exp', pro // 添加代理配置 const proxyAgent = ProxyHelper.createProxyAgent(proxyConfig) if (proxyAgent) { + axiosConfig.httpAgent = proxyAgent axiosConfig.httpsAgent = proxyAgent + axiosConfig.proxy = false logger.info( `🌐 Using proxy for Gemini countTokens: ${ProxyHelper.getProxyDescription(proxyConfig)}` ) @@ -1426,7 +1436,9 @@ async function generateContent( // 添加代理配置 const proxyAgent = ProxyHelper.createProxyAgent(proxyConfig) if (proxyAgent) { + axiosConfig.httpAgent = proxyAgent axiosConfig.httpsAgent = proxyAgent + axiosConfig.proxy = false logger.info( `🌐 Using proxy for Gemini generateContent: ${ProxyHelper.getProxyDescription(proxyConfig)}` ) @@ -1500,7 +1512,9 @@ async function generateContentStream( // 添加代理配置 const proxyAgent = ProxyHelper.createProxyAgent(proxyConfig) if (proxyAgent) { + axiosConfig.httpAgent = proxyAgent axiosConfig.httpsAgent = proxyAgent + axiosConfig.proxy = false logger.info( `🌐 Using proxy for Gemini streamGenerateContent: ${ProxyHelper.getProxyDescription(proxyConfig)}` ) diff --git a/src/services/geminiRelayService.js b/src/services/geminiRelayService.js index eec99a9c..b98b6673 100644 --- a/src/services/geminiRelayService.js +++ b/src/services/geminiRelayService.js @@ -279,7 +279,9 @@ async function sendGeminiRequest({ // 添加代理配置 const proxyAgent = createProxyAgent(proxy) if (proxyAgent) { + axiosConfig.httpAgent = proxyAgent axiosConfig.httpsAgent = proxyAgent + axiosConfig.proxy = false logger.info(`🌐 Using proxy for Gemini API request: ${ProxyHelper.getProxyDescription(proxy)}`) } else { logger.debug('🌐 No proxy configured for Gemini API request') @@ -387,7 +389,9 @@ async function getAvailableModels(accessToken, proxy, projectId, location = 'us- const proxyAgent = createProxyAgent(proxy) if (proxyAgent) { + axiosConfig.httpAgent = proxyAgent axiosConfig.httpsAgent = proxyAgent + axiosConfig.proxy = false logger.info( `🌐 Using proxy for Gemini models request: ${ProxyHelper.getProxyDescription(proxy)}` ) @@ -488,7 +492,9 @@ async function countTokens({ // 添加代理配置 const proxyAgent = createProxyAgent(proxy) if (proxyAgent) { + axiosConfig.httpAgent = proxyAgent axiosConfig.httpsAgent = proxyAgent + axiosConfig.proxy = false logger.info( `🌐 Using proxy for Gemini countTokens request: ${ProxyHelper.getProxyDescription(proxy)}` ) diff --git a/src/services/openaiAccountService.js b/src/services/openaiAccountService.js index cf045e9c..08c93387 100644 --- a/src/services/openaiAccountService.js +++ b/src/services/openaiAccountService.js @@ -223,6 +223,7 @@ async function refreshAccessToken(refreshToken, proxy = null) { // 配置代理(如果有) const proxyAgent = ProxyHelper.createProxyAgent(proxy) if (proxyAgent) { + requestOptions.httpAgent = proxyAgent requestOptions.httpsAgent = proxyAgent requestOptions.proxy = false logger.info( diff --git a/src/services/openaiResponsesRelayService.js b/src/services/openaiResponsesRelayService.js index 433242e6..e7b01d62 100644 --- a/src/services/openaiResponsesRelayService.js +++ b/src/services/openaiResponsesRelayService.js @@ -107,6 +107,7 @@ class OpenAIResponsesRelayService { if (fullAccount.proxy) { const proxyAgent = ProxyHelper.createProxyAgent(fullAccount.proxy) if (proxyAgent) { + requestOptions.httpAgent = proxyAgent requestOptions.httpsAgent = proxyAgent requestOptions.proxy = false logger.info( diff --git a/src/utils/oauthHelper.js b/src/utils/oauthHelper.js index ac33b71e..f15357f6 100644 --- a/src/utils/oauthHelper.js +++ b/src/utils/oauthHelper.js @@ -173,7 +173,7 @@ async function exchangeCodeForTokens(authorizationCode, codeVerifier, state, pro proxyType: proxyConfig?.type || 'none' }) - const response = await axios.post(OAUTH_CONFIG.TOKEN_URL, params, { + const axiosConfig = { headers: { 'Content-Type': 'application/json', 'User-Agent': 'claude-cli/1.0.56 (external, cli)', @@ -182,9 +182,16 @@ async function exchangeCodeForTokens(authorizationCode, codeVerifier, state, pro Referer: 'https://claude.ai/', Origin: 'https://claude.ai' }, - httpsAgent: agent, timeout: 30000 - }) + } + + if (agent) { + axiosConfig.httpAgent = agent + axiosConfig.httpsAgent = agent + axiosConfig.proxy = false + } + + const response = await axios.post(OAUTH_CONFIG.TOKEN_URL, params, axiosConfig) // 记录完整的响应数据到专门的认证详细日志 logger.authDetail('OAuth token exchange response', response.data) @@ -378,7 +385,7 @@ async function exchangeSetupTokenCode(authorizationCode, codeVerifier, state, pr proxyType: proxyConfig?.type || 'none' }) - const response = await axios.post(OAUTH_CONFIG.TOKEN_URL, params, { + const axiosConfig = { headers: { 'Content-Type': 'application/json', 'User-Agent': 'claude-cli/1.0.56 (external, cli)', @@ -387,9 +394,16 @@ async function exchangeSetupTokenCode(authorizationCode, codeVerifier, state, pr Referer: 'https://claude.ai/', Origin: 'https://claude.ai' }, - httpsAgent: agent, timeout: 30000 - }) + } + + if (agent) { + axiosConfig.httpAgent = agent + axiosConfig.httpsAgent = agent + axiosConfig.proxy = false + } + + const response = await axios.post(OAUTH_CONFIG.TOKEN_URL, params, axiosConfig) // 记录完整的响应数据到专门的认证详细日志 logger.authDetail('Setup Token exchange response', response.data) diff --git a/src/utils/workosOAuthHelper.js b/src/utils/workosOAuthHelper.js index 8ce33c4d..ffd0f4d6 100644 --- a/src/utils/workosOAuthHelper.js +++ b/src/utils/workosOAuthHelper.js @@ -40,13 +40,20 @@ async function startDeviceAuthorization(proxyConfig = null) { hasProxy: !!agent }) - const response = await axios.post(WORKOS_DEVICE_AUTHORIZE_URL, form.toString(), { + const axiosConfig = { headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, - httpsAgent: agent, timeout: 15000 - }) + } + + if (agent) { + axiosConfig.httpAgent = agent + axiosConfig.httpsAgent = agent + axiosConfig.proxy = false + } + + const response = await axios.post(WORKOS_DEVICE_AUTHORIZE_URL, form.toString(), axiosConfig) const data = response.data || {} @@ -108,13 +115,20 @@ async function pollDeviceAuthorization(deviceCode, proxyConfig = null) { const agent = ProxyHelper.createProxyAgent(proxyConfig) try { - const response = await axios.post(WORKOS_TOKEN_URL, form.toString(), { + const axiosConfig = { headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, - httpsAgent: agent, timeout: 15000 - }) + } + + if (agent) { + axiosConfig.httpAgent = agent + axiosConfig.httpsAgent = agent + axiosConfig.proxy = false + } + + const response = await axios.post(WORKOS_TOKEN_URL, form.toString(), axiosConfig) const data = response.data || {}