(proxyUrl: string)
| 192 | * 通过代理请求一个可靠的 HTTPS 地址来验证代理是否可用 |
| 193 | */ |
| 194 | export async function testProxyConnection(proxyUrl: string): Promise<{ success: boolean; error?: string }> { |
| 195 | // 先验证格式 |
| 196 | const validation = validateProxyUrl(proxyUrl) |
| 197 | if (!validation.valid) { |
| 198 | return { success: false, error: validation.error } |
| 199 | } |
| 200 | |
| 201 | return await proxyApplyQueue.apply(async () => { |
| 202 | // 测试 URL 列表(按优先级) |
| 203 | const testUrls = ['https://www.google.com', 'https://www.cloudflare.com', 'https://api.deepseek.com'] |
| 204 | |
| 205 | try { |
| 206 | // 临时设置代理 |
| 207 | await session.defaultSession.setProxy({ |
| 208 | proxyRules: proxyUrl, |
| 209 | }) |
| 210 | |
| 211 | // 使用 Electron 的 net 模块测试连接 |
| 212 | const { net } = await import('electron') |
| 213 | |
| 214 | let lastError: string = '' |
| 215 | |
| 216 | for (const testUrl of testUrls) { |
| 217 | try { |
| 218 | const result = await new Promise<{ success: boolean; error?: string }>((resolve) => { |
| 219 | const request = net.request({ |
| 220 | method: 'HEAD', |
| 221 | url: testUrl, |
| 222 | }) |
| 223 | |
| 224 | const timeout = setTimeout(() => { |
| 225 | request.abort() |
| 226 | resolve({ success: false, error: '连接超时' }) |
| 227 | }, 10000) |
| 228 | |
| 229 | request.on('response', (response) => { |
| 230 | clearTimeout(timeout) |
| 231 | // 任何响应都说明代理可用 |
| 232 | if (response.statusCode < 500) { |
| 233 | resolve({ success: true }) |
| 234 | } else { |
| 235 | resolve({ success: false, error: `HTTP ${response.statusCode}` }) |
| 236 | } |
| 237 | }) |
| 238 | |
| 239 | request.on('error', (error) => { |
| 240 | clearTimeout(timeout) |
| 241 | resolve({ success: false, error: error.message }) |
| 242 | }) |
| 243 | |
| 244 | request.end() |
| 245 | }) |
| 246 | |
| 247 | if (result.success) return { success: true } |
| 248 | |
| 249 | lastError = result.error || '' |
| 250 | } catch (e) { |
| 251 | lastError = e instanceof Error ? e.message : String(e) |
no test coverage detected