AIClient-2-API/src/utils/proxy-utils.js
hex2077 2d317e0333 refactor(项目结构): 重构项目目录结构并优化代码组织
将常用工具函数移动到utils目录
重构提供商策略模式实现
新增docker-compose构建配置文件
优化UI配置选择器的样式和交互
重构代理工具和API管理模块
更新脚本路径和依赖引用
2026-01-10 18:19:06 +08:00

128 lines
3.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 代理工具模块
* 支持 HTTP、HTTPS 和 SOCKS5 代理
*/
import { HttpsProxyAgent } from 'https-proxy-agent';
import { HttpProxyAgent } from 'http-proxy-agent';
import { SocksProxyAgent } from 'socks-proxy-agent';
/**
* 解析代理URL并返回相应的代理配置
* @param {string} proxyUrl - 代理URL如 http://127.0.0.1:7890 或 socks5://127.0.0.1:1080
* @returns {Object|null} 代理配置对象,包含 httpAgent 和 httpsAgent
*/
export function parseProxyUrl(proxyUrl) {
if (!proxyUrl || typeof proxyUrl !== 'string') {
return null;
}
const trimmedUrl = proxyUrl.trim();
if (!trimmedUrl) {
return null;
}
try {
const url = new URL(trimmedUrl);
const protocol = url.protocol.toLowerCase();
if (protocol === 'socks5:' || protocol === 'socks4:' || protocol === 'socks:') {
// SOCKS 代理
const socksAgent = new SocksProxyAgent(trimmedUrl);
return {
httpAgent: socksAgent,
httpsAgent: socksAgent,
proxyType: 'socks'
};
} else if (protocol === 'http:' || protocol === 'https:') {
// HTTP/HTTPS 代理
return {
httpAgent: new HttpProxyAgent(trimmedUrl),
httpsAgent: new HttpsProxyAgent(trimmedUrl),
proxyType: 'http'
};
} else {
console.warn(`[Proxy] Unsupported proxy protocol: ${protocol}`);
return null;
}
} catch (error) {
console.error(`[Proxy] Failed to parse proxy URL: ${error.message}`);
return null;
}
}
/**
* 检查指定的提供商是否启用了代理
* @param {Object} config - 配置对象
* @param {string} providerType - 提供商类型
* @returns {boolean} 是否启用代理
*/
export function isProxyEnabledForProvider(config, providerType) {
if (!config || !config.PROXY_URL || !config.PROXY_ENABLED_PROVIDERS) {
return false;
}
const enabledProviders = config.PROXY_ENABLED_PROVIDERS;
if (!Array.isArray(enabledProviders)) {
return false;
}
return enabledProviders.includes(providerType);
}
/**
* 获取指定提供商的代理配置
* @param {Object} config - 配置对象
* @param {string} providerType - 提供商类型
* @returns {Object|null} 代理配置对象或 null
*/
export function getProxyConfigForProvider(config, providerType) {
if (!isProxyEnabledForProvider(config, providerType)) {
return null;
}
const proxyConfig = parseProxyUrl(config.PROXY_URL);
if (proxyConfig) {
console.log(`[Proxy] Using ${proxyConfig.proxyType} proxy for ${providerType}: ${config.PROXY_URL}`);
}
return proxyConfig;
}
/**
* 为 axios 配置代理
* @param {Object} axiosConfig - axios 配置对象
* @param {Object} config - 应用配置对象
* @param {string} providerType - 提供商类型
* @returns {Object} 更新后的 axios 配置
*/
export function configureAxiosProxy(axiosConfig, config, providerType) {
const proxyConfig = getProxyConfigForProvider(config, providerType);
if (proxyConfig) {
// 使用代理 agent
axiosConfig.httpAgent = proxyConfig.httpAgent;
axiosConfig.httpsAgent = proxyConfig.httpsAgent;
// 禁用 axios 内置的代理配置,使用我们的 agent
axiosConfig.proxy = false;
}
return axiosConfig;
}
/**
* 为 google-auth-library 配置代理
* @param {Object} config - 应用配置对象
* @param {string} providerType - 提供商类型
* @returns {Object|null} transporter 配置对象或 null
*/
export function getGoogleAuthProxyConfig(config, providerType) {
const proxyConfig = getProxyConfigForProvider(config, providerType);
if (proxyConfig) {
return {
agent: proxyConfig.httpsAgent
};
}
return null;
}