mirror of
https://github.com/Wei-Shaw/claude-relay-service.git
synced 2026-01-22 16:43:35 +00:00
fix: 修复因代理ip不可用导致axios的proxy回退到环境变量代理问题
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)}`)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -248,14 +248,7 @@ class ClaudeAccountService {
|
||||
// 创建代理agent
|
||||
const agent = this._createProxyAgent(accountData.proxy)
|
||||
|
||||
const response = await axios.post(
|
||||
this.claudeApiUrl,
|
||||
{
|
||||
grant_type: 'refresh_token',
|
||||
refresh_token: refreshToken,
|
||||
client_id: this.claudeOauthClientId
|
||||
},
|
||||
{
|
||||
const axiosConfig = {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Accept: 'application/json, text/plain, */*',
|
||||
@@ -264,9 +257,23 @@ class ClaudeAccountService {
|
||||
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(
|
||||
this.claudeApiUrl,
|
||||
{
|
||||
grant_type: 'refresh_token',
|
||||
refresh_token: refreshToken,
|
||||
client_id: this.claudeOauthClientId
|
||||
},
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -309,7 +309,8 @@ class DroidRelayService {
|
||||
responseType: 'json',
|
||||
...(proxyAgent && {
|
||||
httpAgent: proxyAgent,
|
||||
httpsAgent: proxyAgent
|
||||
httpsAgent: proxyAgent,
|
||||
proxy: false
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -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)}`
|
||||
)
|
||||
|
||||
@@ -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)}`
|
||||
)
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 || {}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user