You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fixed tunnel://127.0.0.1:0 (port 0 placeholder for xray) always failing with ECONNREFUSED 127.0.0.1 even after setting.xrayPort was set. Root cause: getTunnelAgent in packages/mitmproxy/src/lib/proxy/common/util.js used global single-variable caches (httpsOverHttpAgent, httpsOverHttpsAgent, httpOverHttpsAgent) — the first call (before xray started, port still 0) cached a dead agent that was reused forever, ignoring the port 0 → xrayPort replacement done by doProxy. Replaced with a Map cache keyed by ${agentType}:${hostname}:${port}, so port 0 and port 10801 get separate agents. Verified: tunnel://127.0.0.1:0 now works correctly, port is auto-replaced by setting.xrayPort at runtime.
Fixed mitmproxy child process crashing with SIGABRT (V8 heap OOM) roughly 10 minutes after a machine reboot under high-concurrency HTTPS browsing (e.g. navigating github.com with many simultaneous image/asset sub-requests). Root cause: 22 log.info call sites in the mitmproxy package printed full per-request data on the hot path — the two biggest offenders were createRequestHandler.js (logged the complete request headers JSON, including ~1 KB GitHub _gh_sess/user_session cookies) and util.match.js (logged the full interceptOpts JSON for every match, with 3–6 KB of tampermonkey/cache/rule config per request). Under high concurrency these strings (plus log4js's 50 MB maxLogSize file buffer) accumulated in the V8 heap faster than GC could reclaim them, exhausting the 96 MB --max-old-space-size cap set on the mitmproxy child process. The previous v2.2.3 safeROptionsForLog fix only covered the error path (stringify2 fallback to util.inspect); this fix covers the normal INFO path. Demoted 57 hot-path log.info calls to log.debug across 22 files in packages/mitmproxy/src/: lib/proxy/mitmproxy/{createRequestHandler,createConnectHandler,createUpgradeHandler,dnsLookup}.js, lib/dns/base.js, lib/proxy/common/util.js, lib/proxy/middleware/overwall.js, lib/interceptor/impl/req/{OPTIONS,abort,cacheRequest,proxy,redirect,requestReplace,sni,success,unVerifySsl}.js, lib/interceptor/impl/res/{AfterOPTIONSHeaders,cacheResponse,responseReplace,script}.js, utils/util.match.js, options.js. Codebase knowledge-graph trace of requestHandler outbound callees was used to verify full hot-path coverage with no omissions (and no over-demotion of startup-once / per-domain-once logs). Verified by codebase-memo MCP. Verified by local deploy: under the same browsing pattern that previously crashed in ~10 min, the new build ran with no SIGABRT.
Added
Added observatoryProbeUrl config option to the Xray plugin (packages/core/src/modules/plugin/xray/config.js). When set, the Stage1/observatory runtime probe uses this URL instead of probeUrl (Stage3 cache probe remains unchanged). This allows using a stricter probe target (e.g. https://chatgpt.com/) for runtime node selection while keeping the lenient probe (gstatic.com/generate_204) for cache-wide screening. xray observatory treats any HTTP response (including 403) as "alive", only timeout/reset marks a node as dead — so a CF-protected site like chatgpt.com filters out junk HTTP proxies that pass simple 204 probes but fail on real targets. Default: empty (falls back to probeUrl). Three genConfig() call sites in packages/core/src/modules/plugin/xray/index.js were updated to pass cfg.observatoryProbeUrl || cfg.probeUrl.
Changed
Added mitmproxy child-process auto-respawn in packages/core/src/modules/server/index.js. Previously, when the mitmproxy child process crashed (SIGABRT/SIGSEGV/non-zero exit), the main service-entry.js process stayed alive but the proxy port 31181 was dead — every browser request got ECONNREFUSED while systemctl status dev-sidecar reported active (running) (systemd's Restart=on-failure only watches the main PID, not grandchild processes forked via child_process.fork()). The serverProcess.on('exit') handler now detects abnormal exits (code !== 0 or signal !== null) and re-forks the mitmproxy child process by calling serverApi.start(...). A 30-second sliding window limits respawn to at most 3 attempts; if exceeded, the handler fires an error event (value: 'respawn_exceeded') and stops retrying to avoid restart storms. The kill()/close()/restart() paths set an intentionalStop flag so that graceful shutdowns don't trigger self-healing. Verified by local deploy: manually kill -SIGABRT on the mitmproxy PID triggered respawn within ~23 ms with zero browser-visible downtime (curl -x http://127.0.0.1:31181 https://github.com returned 200 before and after the kill).
Removed dead maxOldSpaceSizeMB field from STAGE3_BATCH_LEVEL_TABLE in packages/core/src/modules/plugin/xray/config.js. This field was a leftover from v2.2.0's per-level dynamic --max-old-space-size adjustment, which v2.2.3 replaced with a fixed 96MB in packages/core/src/modules/server/index.js (and removed STAGE3_MAX_OLD_SPACE_BY_LEVEL). The maxOldSpaceSizeMB field was never read by any code after v2.2.3 — only batchSize and stage3GcThresholdMB are used. Also fixed stale comments: level=N 对应 batchSize=N*64 → batchSize = 64 << (level-1); removed the misleading mitmproxy 子进程与 Stage3 探测共用同一 fork 路径 note (xray probe is a Go binary with no V8 heap). Verified by codebase-memo MCP knowledge-graph trace: confirmed maxOldSpaceSizeMB has zero references outside config.js, and stage3GcThresholdMB is read by refreshCacheFromCacheOnly in index.js.