mirror of
https://github.com/hansjone/dsh-im-ops.git
synced 2026-10-09 05:20:46 +08:00
fix(feishu): honor NO_PROXY before proxying the long connection
webSocketProxyUrl() picks up https_proxy/HTTPS_PROXY/http_proxy/ HTTP_PROXY and forces the Feishu WSS long connection through the proxy, without consulting NO_PROXY/no_proxy. With a local proxy exported in the shell (Clash/V2Ray setups), every long-connection attempt is rejected by Feishu's server and the runtime force-closes and retries in a loop, so the bot never reaches a stable connected state. Resolve NO_PROXY/no_proxy for the long-connection endpoints (open.feishu.cn / open.larksuite.com) before falling back to the proxy env: exact host, parent-domain (.cn, feishu.cn) and * entries follow the common NO_PROXY semantics. - production.mjs: NO_PROXY gate in front of the proxy lookup - feishu-proxy.test.mjs: NO_PROXY exclusion and fallthrough cases - lib/index.js: regenerated host bundle
This commit is contained in:
parent
009f1abec9
commit
adc0a89f13
3 changed files with 351 additions and 217 deletions
|
|
@ -25,7 +25,34 @@ import {
|
|||
import { listAgentPresetCatalog } from '../../../../src/channels/shared/agent-preset.mjs';
|
||||
import { createDeliveryAdapter } from '../../delivery-adapter.mjs';
|
||||
|
||||
// The WebSocket agent built here is only used for the Feishu long connection,
|
||||
// whose endpoint is open.feishu.cn (Feishu) or open.larksuite.com (Lark).
|
||||
// Honor NO_PROXY/no_proxy for those hosts so users with blanket proxy
|
||||
// environments exported in their shell (Clash/V2Ray etc.) keep a direct
|
||||
// connection to Feishu instead of routing the WSS handshake through the proxy.
|
||||
const LONG_CONNECTION_HOSTS = ['open.feishu.cn', 'open.larksuite.com'];
|
||||
|
||||
function hostExcludedByNoProxyEntry(host, entry) {
|
||||
if (entry === '*') return true;
|
||||
const bare = entry.startsWith('.') ? entry.slice(1) : entry;
|
||||
if (!bare) return false;
|
||||
return host === bare || host.endsWith(`.${bare}`);
|
||||
}
|
||||
|
||||
function longConnectionExcludedByNoProxy(env) {
|
||||
for (const key of ['no_proxy', 'NO_PROXY']) {
|
||||
const value = env?.[key];
|
||||
if (typeof value !== 'string' || !value.trim()) continue;
|
||||
const entries = value.split(',').map((entry) => entry.trim().toLowerCase()).filter(Boolean);
|
||||
if (LONG_CONNECTION_HOSTS.some((host) => entries.some((entry) => hostExcludedByNoProxyEntry(host, entry)))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function webSocketProxyUrl(env) {
|
||||
if (longConnectionExcludedByNoProxy(env)) return undefined;
|
||||
for (const key of ['https_proxy', 'HTTPS_PROXY', 'http_proxy', 'HTTP_PROXY']) {
|
||||
const value = env?.[key];
|
||||
if (typeof value === 'string' && value.trim()) return value.trim();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue