fix: support esm socks-proxy-agent in niupanel
This commit is contained in:
@@ -5,10 +5,27 @@ const vm = require('vm');
|
|||||||
const { AsyncLocalStorage } = require('async_hooks');
|
const { AsyncLocalStorage } = require('async_hooks');
|
||||||
|
|
||||||
let SocksProxyAgent = null;
|
let SocksProxyAgent = null;
|
||||||
|
let socksProxyAgentImportPromise = null;
|
||||||
try {
|
try {
|
||||||
({ SocksProxyAgent } = require('socks-proxy-agent'));
|
({ SocksProxyAgent } = require('socks-proxy-agent'));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// 未配置代理时不需要安装;配置 SOCKS5 代理时会给出明确提示。
|
// socks-proxy-agent v8+ 是 ESM,CommonJS require 会失败;真正配置代理时再用 dynamic import 加载。
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadSocksProxyAgent() {
|
||||||
|
if (SocksProxyAgent) return SocksProxyAgent;
|
||||||
|
if (!socksProxyAgentImportPromise) {
|
||||||
|
socksProxyAgentImportPromise = import('socks-proxy-agent')
|
||||||
|
.then(mod => {
|
||||||
|
SocksProxyAgent = mod.SocksProxyAgent;
|
||||||
|
return SocksProxyAgent;
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
socksProxyAgentImportPromise = null;
|
||||||
|
throw err;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return socksProxyAgentImportPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================
|
// ============================================
|
||||||
@@ -74,7 +91,6 @@ const AXIOS_COMMON_OPTS = {
|
|||||||
// ========== 账号级 SOCKS5 代理 ==========
|
// ========== 账号级 SOCKS5 代理 ==========
|
||||||
const accountContext = new AsyncLocalStorage();
|
const accountContext = new AsyncLocalStorage();
|
||||||
const socksAgentCache = new Map();
|
const socksAgentCache = new Map();
|
||||||
const axiosRequestRaw = axios.request.bind(axios);
|
|
||||||
|
|
||||||
function normalizeSocksProxy(proxyUrl) {
|
function normalizeSocksProxy(proxyUrl) {
|
||||||
const raw = String(proxyUrl || '').trim();
|
const raw = String(proxyUrl || '').trim();
|
||||||
@@ -99,24 +115,27 @@ function maskProxyUrl(proxyUrl) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSocksAgent(proxyUrl) {
|
async function getSocksAgent(proxyUrl) {
|
||||||
const normalized = normalizeSocksProxy(proxyUrl);
|
const normalized = normalizeSocksProxy(proxyUrl);
|
||||||
if (!normalized) return null;
|
if (!normalized) return null;
|
||||||
if (!SocksProxyAgent) {
|
const AgentCtor = await loadSocksProxyAgent().catch(err => {
|
||||||
throw new Error('已配置SOCKS5代理,但缺少依赖 socks-proxy-agent,请先执行: npm install');
|
throw new Error(`已配置SOCKS5代理,但加载依赖 socks-proxy-agent 失败,请先在脚本目录执行 npm install socks-proxy-agent。原始错误: ${err.message}`);
|
||||||
|
});
|
||||||
|
if (!AgentCtor) {
|
||||||
|
throw new Error('已配置SOCKS5代理,但缺少依赖 socks-proxy-agent,请先在脚本目录执行: npm install socks-proxy-agent');
|
||||||
}
|
}
|
||||||
if (!socksAgentCache.has(normalized)) {
|
if (!socksAgentCache.has(normalized)) {
|
||||||
socksAgentCache.set(normalized, new SocksProxyAgent(normalized));
|
socksAgentCache.set(normalized, new AgentCtor(normalized));
|
||||||
}
|
}
|
||||||
return socksAgentCache.get(normalized);
|
return socksAgentCache.get(normalized);
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyCurrentAccountProxy(config = {}) {
|
async function applyCurrentAccountProxy(config = {}) {
|
||||||
const ctx = accountContext.getStore();
|
const ctx = accountContext.getStore();
|
||||||
const proxyUrl = ctx && ctx.socksProxy;
|
const proxyUrl = ctx && ctx.socksProxy;
|
||||||
if (!proxyUrl) return config;
|
if (!proxyUrl) return config;
|
||||||
|
|
||||||
const agent = getSocksAgent(proxyUrl);
|
const agent = await getSocksAgent(proxyUrl);
|
||||||
return {
|
return {
|
||||||
...config,
|
...config,
|
||||||
proxy: false,
|
proxy: false,
|
||||||
@@ -125,9 +144,6 @@ function applyCurrentAccountProxy(config = {}) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
axios.request = function patchedAxiosRequest(config) {
|
|
||||||
return axiosRequestRaw(applyCurrentAccountProxy(config || {}));
|
|
||||||
};
|
|
||||||
axios.interceptors.request.use(config => applyCurrentAccountProxy(config || {}));
|
axios.interceptors.request.use(config => applyCurrentAccountProxy(config || {}));
|
||||||
|
|
||||||
function runWithAccountProxy(socksProxy, fn) {
|
function runWithAccountProxy(socksProxy, fn) {
|
||||||
|
|||||||
Reference in New Issue
Block a user