fix: 修复因代理ip不可用导致axios的proxy回退到环境变量代理问题

This commit is contained in:
shaw
2025-10-18 11:00:43 +08:00
parent 6ea2012ab1
commit 1ed0ca31ec
14 changed files with 133 additions and 35 deletions

View File

@@ -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
}

View File

@@ -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)}`)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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
}
}

View File

@@ -309,7 +309,8 @@ class DroidRelayService {
responseType: 'json',
...(proxyAgent && {
httpAgent: proxyAgent,
httpsAgent: proxyAgent
httpsAgent: proxyAgent,
proxy: false
})
}

View File

@@ -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)}`
)

View File

@@ -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)}`
)

View File

@@ -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(

View File

@@ -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(

View File

@@ -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)

View File

@@ -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 || {}