Spaces:
Paused
Paused
| /** | |
| * 简化的代理池类,支持 HTTP 和 SOCKS5 代理 | |
| */ | |
| class ProxyPool { | |
| constructor() { | |
| // 从环境变量读取完整的代理URL | |
| this.proxyUrl = process.env.HTTP_PROXY || process.env.HTTPS_PROXY || ''; | |
| this.isInitialized = false; | |
| // 解析代理URL | |
| this.parseProxyUrl(); | |
| } | |
| /** | |
| * 解析代理URL | |
| */ | |
| parseProxyUrl() { | |
| if (!this.proxyUrl) { | |
| console.log('未设置代理URL环境变量 (HTTP_PROXY)'); | |
| return; | |
| } | |
| try { | |
| const url = new URL(this.proxyUrl); | |
| this.proxyInfo = { | |
| protocol: url.protocol.replace(':', ''), | |
| host: url.hostname, | |
| port: parseInt(url.port), | |
| username: url.username, | |
| password: url.password, | |
| full: this.proxyUrl | |
| }; | |
| console.log(`代理配置解析成功: ${this.proxyInfo.protocol}://${this.proxyInfo.host}:${this.proxyInfo.port}`); | |
| } catch (error) { | |
| console.error(`代理URL解析失败: ${error.message}`); | |
| this.proxyInfo = null; | |
| } | |
| } | |
| /** | |
| * 初始化代理池 | |
| */ | |
| async initialize() { | |
| if (this.isInitialized) return true; | |
| if (!this.proxyUrl) { | |
| console.log('未配置代理,将使用直连模式'); | |
| this.isInitialized = true; | |
| return true; | |
| } | |
| if (!this.proxyInfo) { | |
| console.error('代理配置无效'); | |
| return false; | |
| } | |
| // 测试代理连接 | |
| const isValid = await this.testProxyConnection(); | |
| if (isValid) { | |
| this.isInitialized = true; | |
| console.log('代理池初始化成功'); | |
| return true; | |
| } else { | |
| console.error('代理连接测试失败'); | |
| // 即使测试失败,也标记为已初始化,让实际使用时验证 | |
| this.isInitialized = true; | |
| console.log('跳过测试失败,继续使用配置的代理'); | |
| return true; | |
| } | |
| } | |
| /** | |
| * 测试代理连接 | |
| */ | |
| async testProxyConnection() { | |
| if (!this.proxyInfo) return false; | |
| try { | |
| let agent; | |
| // 根据协议选择不同的代理 Agent | |
| if (this.proxyUrl.startsWith('socks5://')) { | |
| const { SocksProxyAgent } = await import('socks-proxy-agent'); | |
| agent = new SocksProxyAgent(this.proxyUrl); | |
| console.log('使用 SOCKS5 代理进行测试...'); | |
| } else if (this.proxyUrl.startsWith('socks4://')) { | |
| const { SocksProxyAgent } = await import('socks-proxy-agent'); | |
| agent = new SocksProxyAgent(this.proxyUrl); | |
| console.log('使用 SOCKS4 代理进行测试...'); | |
| } else { | |
| const HttpProxyAgent = (await import('http-proxy-agent')).default; | |
| agent = new HttpProxyAgent(this.proxyUrl); | |
| console.log('使用 HTTP 代理进行测试...'); | |
| } | |
| const fetch = (await import('node-fetch')).default; | |
| // 尝试多个测试URL | |
| const testUrls = [ | |
| 'http://httpbin.org/ip', | |
| 'https://api.ipify.org?format=json', | |
| 'http://icanhazip.com' | |
| ]; | |
| for (const testUrl of testUrls) { | |
| try { | |
| console.log(`测试代理连接到: ${testUrl}`); | |
| const response = await fetch(testUrl, { | |
| agent, | |
| timeout: 15000, | |
| headers: { | |
| 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', | |
| 'Accept': '*/*', | |
| 'Connection': 'close' | |
| } | |
| }); | |
| if (response.ok) { | |
| const data = await response.text(); | |
| let ip = data.trim(); | |
| // 尝试解析JSON格式的响应 | |
| try { | |
| const jsonData = JSON.parse(data); | |
| ip = jsonData.ip || jsonData.origin || ip; | |
| } catch (e) { | |
| // 如果不是JSON,使用原始文本 | |
| } | |
| console.log(`${this.proxyInfo.protocol.toUpperCase()} 代理连接测试成功!`); | |
| console.log(`测试URL: ${testUrl}`); | |
| console.log(`出口IP: ${ip}`); | |
| return true; | |
| } else { | |
| console.log(`测试URL ${testUrl} 失败,状态码: ${response.status}`); | |
| } | |
| } catch (urlError) { | |
| console.log(`测试URL ${testUrl} 出错: ${urlError.message}`); | |
| } | |
| } | |
| console.error('所有测试URL都失败了'); | |
| return false; | |
| } catch (error) { | |
| console.error(`代理连接测试失败: ${error.message}`); | |
| return false; | |
| } | |
| } | |
| /** | |
| * 获取代理(每次调用返回相同的代理) | |
| */ | |
| getProxy() { | |
| if (!this.proxyInfo) { | |
| return null; | |
| } | |
| return { | |
| ip: this.proxyInfo.host, | |
| port: this.proxyInfo.port, | |
| protocol: this.proxyInfo.protocol, | |
| full: this.proxyInfo.full | |
| }; | |
| } | |
| /** | |
| * 移除代理(记录错误) | |
| */ | |
| removeProxy(ip, port) { | |
| console.log(`记录代理问题: ${ip}:${port}`); | |
| return true; | |
| } | |
| /** | |
| * 获取代理数量 | |
| */ | |
| getValidCount() { | |
| return this.proxyInfo ? 1 : 0; | |
| } | |
| /** | |
| * 获取状态信息 | |
| */ | |
| getStatus() { | |
| if (!this.proxyInfo) { | |
| return []; | |
| } | |
| return [{ | |
| index: 0, | |
| host: this.proxyInfo.host, | |
| port: this.proxyInfo.port, | |
| protocol: this.proxyInfo.protocol, | |
| active: true | |
| }]; | |
| } | |
| /** | |
| * 停止代理池 | |
| */ | |
| stop() { | |
| console.log('代理池已停止'); | |
| } | |
| } | |
| // 导出 | |
| export default ProxyPool; | |
| export const proxyPool = new ProxyPool(); | |