|
|
@@ -1,6 +1,6 @@
|
|
|
const axios = require('axios')
|
|
|
-const HttpsProxyAgent = require('https-proxy-agent')
|
|
|
const QgProxyManager = require('./QgProxyManager')
|
|
|
+const { buildAxiosOutboundConfig } = require('./outboundAxiosConfig')
|
|
|
|
|
|
function sleep(ms) {
|
|
|
return new Promise(r => setTimeout(r, ms))
|
|
|
@@ -20,29 +20,6 @@ async function getOutboundWithBackoff(qgOpts, rounds = 2) {
|
|
|
throw lastErr
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- * Axios 对「HTTPS 目标 + 内置 proxy」在部分环境下会引发 ERR_FR_TOO_MANY_REDIRECTS,
|
|
|
- * 改用 HttpsProxyAgent 走 CONNECT 隧道。
|
|
|
- */
|
|
|
-function buildAxiosOutboundConfig(fragment) {
|
|
|
- if (!fragment || fragment.proxy === false || !fragment.proxy) {
|
|
|
- return { proxy: false }
|
|
|
- }
|
|
|
- const { host, port, auth } = fragment.proxy
|
|
|
- let userPart = ''
|
|
|
- if (auth && String(auth.username || '').length > 0) {
|
|
|
- const u = encodeURIComponent(auth.username)
|
|
|
- const p = encodeURIComponent(auth.password != null ? String(auth.password) : '')
|
|
|
- userPart = `${u}:${p}@`
|
|
|
- }
|
|
|
- const proxyUrl = `http://${userPart}${host}:${port}`
|
|
|
- const rejectUnauthorized = process.env.NODE_TLS_REJECT_UNAUTHORIZED !== '0'
|
|
|
- return {
|
|
|
- proxy: false,
|
|
|
- httpsAgent: new HttpsProxyAgent(proxyUrl, { rejectUnauthorized })
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
function debugProxyEnabled() {
|
|
|
return String(process.env.LEPAO_DEBUG_PROXY || '').trim() === '1'
|
|
|
}
|
|
|
@@ -86,7 +63,7 @@ function isQgProxyEligibleFailure(err) {
|
|
|
if (status === 502 || status === 503 || status === 504) return true
|
|
|
if (
|
|
|
err.code &&
|
|
|
- ['ECONNRESET', 'ECONNABORTED', 'ETIMEDOUT', 'ENOTFOUND', 'EAI_AGAIN', 'ECONNREFUSED', 'EPROTO', 'ERR_FR_TOO_MANY_REDIRECTS'].includes(
|
|
|
+ ['ECONNRESET', 'ECONNABORTED', 'ETIMEDOUT', 'ENOTFOUND', 'EAI_AGAIN', 'ECONNREFUSED', 'EPROTO', 'ERR_FR_TOO_MANY_REDIRECTS', 'ERR_INVALID_PROTOCOL'].includes(
|
|
|
err.code
|
|
|
)
|
|
|
) {
|