@yina-npm/openrouterx 0.4.33 → 0.4.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +54 -0
- package/app/.next/BUILD_ID +1 -1
- package/app/.next/app-path-routes-manifest.json +2 -2
- package/app/.next/build-manifest.json +2 -2
- package/app/.next/required-server-files.json +1 -1
- package/app/.next/routes-manifest.json +27 -1
- package/app/.next/server/app/(dashboard)/dashboard/admin/keys/page.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/admin/keys/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/admin/users/page.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/admin/users/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/basic-chat/page.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/basic-chat/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/cli-tools/page.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/cli-tools/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/combos/page.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/combos/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/console-log/page.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/console-log/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/endpoint/page.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/endpoint/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/focus-ui/page.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/focus-ui/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/media-providers/[kind]/page.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/media-providers/[kind]/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/media-providers/web/page.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/media-providers/web/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/mitm/page.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/mitm/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/network-analysis/page.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/network-analysis/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/page.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/profile/page.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/profile/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/providers/[id]/page.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/providers/[id]/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/providers/new/page.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/providers/new/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/providers/page.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/providers/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/proxy-pools/page.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/proxy-pools/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/quota/page.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/quota/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/skills/page.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/skills/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/translator/page.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/translator/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/usage/page.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/usage/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/user/page.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/user/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/_global-error/page.js +1 -1
- package/app/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/_global-error.html +1 -1
- package/app/.next/server/app/_global-error.rsc +1 -1
- package/app/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/app/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/app/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/app/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/app/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/app/.next/server/app/_not-found/page.js +1 -1
- package/app/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/_not-found.html +1 -1
- package/app/.next/server/app/_not-found.rsc +3 -3
- package/app/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- package/app/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
- package/app/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/app/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/app/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/app/.next/server/app/api/auth/login/route.js +1 -1
- package/app/.next/server/app/api/auth/logout/route.js +1 -1
- package/app/.next/server/app/api/auth/me/route.js +1 -1
- package/app/.next/server/app/api/auth/oidc/callback/route.js +1 -1
- package/app/.next/server/app/api/auth/oidc/start/route.js +1 -1
- package/app/.next/server/app/api/auth/oidc/test/route.js +1 -1
- package/app/.next/server/app/api/auth/status/route.js +1 -1
- package/app/.next/server/app/api/cli-tools/all-statuses/route.js +1 -1
- package/app/.next/server/app/api/cli-tools/antigravity-mitm/alias/route.js +1 -1
- package/app/.next/server/app/api/cli-tools/antigravity-mitm/inject-auth/route.js +1 -1
- package/app/.next/server/app/api/cli-tools/antigravity-mitm/inject-auth/route.js.nft.json +1 -1
- package/app/.next/server/app/api/cli-tools/antigravity-mitm/restart/route.js +1 -1
- package/app/.next/server/app/api/cli-tools/antigravity-mitm/route.js +1 -1
- package/app/.next/server/app/api/cli-tools/antigravity-mitm/test/route.js +1 -1
- package/app/.next/server/app/api/cli-tools/claude-settings/route.js +1 -1
- package/app/.next/server/app/api/cli-tools/cline-settings/route.js +1 -1
- package/app/.next/server/app/api/cli-tools/codex-settings/activate-account/route.js +2 -2
- package/app/.next/server/app/api/cli-tools/codex-settings/route.js +1 -1
- package/app/.next/server/app/api/cli-tools/copilot-settings/route.js +1 -1
- package/app/.next/server/app/api/cli-tools/cowork-mcp-registry/route.js +1 -1
- package/app/.next/server/app/api/cli-tools/cowork-mcp-tools/route.js +1 -1
- package/app/.next/server/app/api/cli-tools/cowork-settings/route.js +1 -1
- package/app/.next/server/app/api/cli-tools/droid-settings/route.js +1 -1
- package/app/.next/server/app/api/cli-tools/hermes-settings/route.js +1 -1
- package/app/.next/server/app/api/cli-tools/kilo-settings/route.js +1 -1
- package/app/.next/server/app/api/cli-tools/openclaw-settings/route.js +1 -1
- package/app/.next/server/app/api/cli-tools/opencode-settings/route.js +1 -1
- package/app/.next/server/app/api/cloud/auth/route.js +1 -1
- package/app/.next/server/app/api/cloud/credentials/update/route.js +1 -1
- package/app/.next/server/app/api/cloud/model/resolve/route.js +1 -1
- package/app/.next/server/app/api/cloud/models/alias/route.js +1 -1
- package/app/.next/server/app/api/combos/[id]/route.js +1 -1
- package/app/.next/server/app/api/combos/route.js +1 -1
- package/app/.next/server/app/api/health/route.js +1 -1
- package/app/.next/server/app/api/init/route.js +1 -1
- package/app/.next/server/app/api/keys/[id]/route.js +1 -1
- package/app/.next/server/app/api/keys/route.js +1 -1
- package/app/.next/server/app/api/locale/route.js +1 -1
- package/app/.next/server/app/api/mcp/[plugin]/message/route.js +1 -1
- package/app/.next/server/app/api/mcp/[plugin]/sse/route.js +1 -1
- package/app/.next/server/app/api/media-providers/tts/deepgram/voices/route.js +1 -1
- package/app/.next/server/app/api/media-providers/tts/elevenlabs/voices/route.js +1 -1
- package/app/.next/server/app/api/media-providers/tts/inworld/voices/route.js +1 -1
- package/app/.next/server/app/api/media-providers/tts/voices/route.js +1 -1
- package/app/.next/server/app/api/models/alias/route.js +1 -1
- package/app/.next/server/app/api/models/availability/route.js +1 -1
- package/app/.next/server/app/api/models/custom/route.js +1 -1
- package/app/.next/server/app/api/models/disabled/route.js +1 -1
- package/app/.next/server/app/api/models/route.js +1 -1
- package/app/.next/server/app/api/models/test/route.js +1 -1
- package/app/.next/server/app/api/network-analysis/route.js +2 -2
- package/app/.next/server/app/api/oauth/[provider]/[action]/route.js +2 -2
- package/app/.next/server/app/api/oauth/cursor/auto-import/route.js +1 -1
- package/app/.next/server/app/api/oauth/cursor/import/route.js +1 -1
- package/app/.next/server/app/api/oauth/gitlab/pat/route.js +1 -1
- package/app/.next/server/app/api/oauth/iflow/cookie/route.js +1 -1
- package/app/.next/server/app/api/oauth/kiro/auto-import/route.js +1 -1
- package/app/.next/server/app/api/oauth/kiro/import/route.js +1 -1
- package/app/.next/server/app/api/oauth/kiro/social-authorize/route.js +1 -1
- package/app/.next/server/app/api/oauth/kiro/social-exchange/route.js +1 -1
- package/app/.next/server/app/api/pricing/route.js +1 -1
- package/app/.next/server/app/api/provider-nodes/[id]/route.js +1 -1
- package/app/.next/server/app/api/provider-nodes/route.js +1 -1
- package/app/.next/server/app/api/provider-nodes/validate/route.js +1 -1
- package/app/.next/server/app/api/providers/[id]/models/route.js +1 -1
- package/app/.next/server/app/api/providers/[id]/route.js +1 -1
- package/app/.next/server/app/api/providers/[id]/test/route.js +1 -1
- package/app/.next/server/app/api/providers/[id]/test-models/route.js +1 -1
- package/app/.next/server/app/api/providers/client/route.js +1 -1
- package/app/.next/server/app/api/providers/kilo/free-models/route.js +1 -1
- package/app/.next/server/app/api/providers/route.js +1 -1
- package/app/.next/server/app/api/providers/suggested-models/route.js +1 -1
- package/app/.next/server/app/api/providers/test-batch/route.js +1 -1
- package/app/.next/server/app/api/providers/validate/route.js +1 -1
- package/app/.next/server/app/api/proxy-pools/[id]/route.js +1 -1
- package/app/.next/server/app/api/proxy-pools/[id]/test/route.js +1 -1
- package/app/.next/server/app/api/proxy-pools/route.js +1 -1
- package/app/.next/server/app/api/proxy-pools/vercel-deploy/route.js +1 -1
- package/app/.next/server/app/api/settings/database/route.js +1 -1
- package/app/.next/server/app/api/settings/proxy-test/route.js +1 -1
- package/app/.next/server/app/api/settings/require-login/route.js +1 -1
- package/app/.next/server/app/api/settings/route.js +1 -1
- package/app/.next/server/app/api/shutdown/route.js +1 -1
- package/app/.next/server/app/api/startup-notices/route.js +1 -1
- package/app/.next/server/app/api/tags/route.js +1 -1
- package/app/.next/server/app/api/translator/console-logs/route.js +1 -1
- package/app/.next/server/app/api/translator/console-logs/stream/route.js +1 -1
- package/app/.next/server/app/api/translator/load/route.js +1 -1
- package/app/.next/server/app/api/translator/save/route.js +1 -1
- package/app/.next/server/app/api/translator/send/route.js +1 -1
- package/app/.next/server/app/api/translator/translate/route.js +1 -1
- package/app/.next/server/app/api/tunnel/disable/route.js +1 -1
- package/app/.next/server/app/api/tunnel/enable/route.js +1 -1
- package/app/.next/server/app/api/tunnel/status/route.js +1 -1
- package/app/.next/server/app/api/tunnel/tailscale-check/route.js +1 -1
- package/app/.next/server/app/api/tunnel/tailscale-disable/route.js +1 -1
- package/app/.next/server/app/api/tunnel/tailscale-enable/route.js +1 -1
- package/app/.next/server/app/api/tunnel/tailscale-install/route.js +2 -2
- package/app/.next/server/app/api/tunnel/tailscale-login/route.js +1 -1
- package/app/.next/server/app/api/tunnel/tailscale-start-daemon/route.js +1 -1
- package/app/.next/server/app/api/usage/[connectionId]/route.js +1 -1
- package/app/.next/server/app/api/usage/api-keys/route.js +1 -1
- package/app/.next/server/app/api/usage/chart/route.js +1 -1
- package/app/.next/server/app/api/usage/history/route.js +1 -1
- package/app/.next/server/app/api/usage/logs/route.js +1 -1
- package/app/.next/server/app/api/usage/providers/route.js +1 -1
- package/app/.next/server/app/api/usage/request-details/route.js +1 -1
- package/app/.next/server/app/api/usage/request-logs/route.js +1 -1
- package/app/.next/server/app/api/usage/stats/route.js +1 -1
- package/app/.next/server/app/api/usage/stream/route.js +1 -1
- package/app/.next/server/app/api/users/[id]/route.js +1 -1
- package/app/.next/server/app/api/users/route.js +1 -1
- package/app/.next/server/app/api/v1/api/chat/route.js +1 -1
- package/app/.next/server/app/api/v1/audio/speech/route.js +1 -1
- package/app/.next/server/app/api/v1/audio/transcriptions/route.js +1 -1
- package/app/.next/server/app/api/v1/audio/voices/route.js +1 -1
- package/app/.next/server/app/api/v1/chat/completions/route.js +1 -1
- package/app/.next/server/app/api/v1/embeddings/route.js +1 -1
- package/app/.next/server/app/api/v1/images/generations/route.js +1 -1
- package/app/.next/server/app/api/v1/messages/count_tokens/route.js +1 -1
- package/app/.next/server/app/api/v1/messages/route.js +1 -1
- package/app/.next/server/app/api/v1/models/[kind]/route.js +1 -1
- package/app/.next/server/app/api/v1/models/info/route.js +1 -1
- package/app/.next/server/app/api/v1/models/route.js +1 -1
- package/app/.next/server/app/api/v1/responses/compact/route.js +1 -1
- package/app/.next/server/app/api/v1/responses/route.js +1 -1
- package/app/.next/server/app/api/v1/route.js +1 -1
- package/app/.next/server/app/api/v1/search/route.js +1 -1
- package/app/.next/server/app/api/v1/web/fetch/route.js +1 -1
- package/app/.next/server/app/api/v1beta/models/[...path]/route.js +1 -1
- package/app/.next/server/app/api/v1beta/models/route.js +1 -1
- package/app/.next/server/app/api/version/route.js +1 -1
- package/app/.next/server/app/api/version/shutdown/route.js +1 -1
- package/app/.next/server/app/api/version/update/route.js +1 -1
- package/app/.next/server/app/callback/page.js +1 -1
- package/app/.next/server/app/callback/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/callback.html +1 -1
- package/app/.next/server/app/callback.rsc +3 -3
- package/app/.next/server/app/callback.segments/_full.segment.rsc +3 -3
- package/app/.next/server/app/callback.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/callback.segments/_index.segment.rsc +3 -3
- package/app/.next/server/app/callback.segments/_tree.segment.rsc +1 -1
- package/app/.next/server/app/callback.segments/callback/__PAGE__.segment.rsc +1 -1
- package/app/.next/server/app/callback.segments/callback.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/settings/pricing/page.js +1 -1
- package/app/.next/server/app/dashboard/settings/pricing/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/dashboard/settings/pricing.html +1 -1
- package/app/.next/server/app/dashboard/settings/pricing.rsc +3 -3
- package/app/.next/server/app/dashboard/settings/pricing.segments/_full.segment.rsc +3 -3
- package/app/.next/server/app/dashboard/settings/pricing.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/settings/pricing.segments/_index.segment.rsc +3 -3
- package/app/.next/server/app/dashboard/settings/pricing.segments/_tree.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing/__PAGE__.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/settings/pricing.segments/dashboard/settings.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/settings/pricing.segments/dashboard.segment.rsc +1 -1
- package/app/.next/server/app/favicon.ico/route.js +1 -1
- package/app/.next/server/app/index.html +1 -1
- package/app/.next/server/app/index.rsc +3 -3
- package/app/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/app/.next/server/app/index.segments/_full.segment.rsc +3 -3
- package/app/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/index.segments/_index.segment.rsc +3 -3
- package/app/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/app/.next/server/app/landing/page.js +1 -1
- package/app/.next/server/app/landing/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/landing.html +1 -1
- package/app/.next/server/app/landing.rsc +3 -3
- package/app/.next/server/app/landing.segments/_full.segment.rsc +3 -3
- package/app/.next/server/app/landing.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/landing.segments/_index.segment.rsc +3 -3
- package/app/.next/server/app/landing.segments/_tree.segment.rsc +1 -1
- package/app/.next/server/app/landing.segments/landing/__PAGE__.segment.rsc +1 -1
- package/app/.next/server/app/landing.segments/landing.segment.rsc +1 -1
- package/app/.next/server/app/login/page.js +1 -1
- package/app/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/login.html +1 -1
- package/app/.next/server/app/login.rsc +4 -4
- package/app/.next/server/app/login.segments/_full.segment.rsc +4 -4
- package/app/.next/server/app/login.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/login.segments/_index.segment.rsc +3 -3
- package/app/.next/server/app/login.segments/_tree.segment.rsc +1 -1
- package/app/.next/server/app/login.segments/login/__PAGE__.segment.rsc +2 -2
- package/app/.next/server/app/login.segments/login.segment.rsc +1 -1
- package/app/.next/server/app/manifest.webmanifest/route.js +1 -1
- package/app/.next/server/app/page.js +1 -1
- package/app/.next/server/app/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app-paths-manifest.json +2 -2
- package/app/.next/server/chunks/1350.js +1 -1
- package/app/.next/server/chunks/3110.js +1 -1
- package/app/.next/server/chunks/3493.js +1 -1
- package/app/.next/server/chunks/4922.js +1 -1
- package/app/.next/server/chunks/5627.js +6 -6
- package/app/.next/server/chunks/6182.js +3 -3
- package/app/.next/server/chunks/7595.js +1 -1
- package/app/.next/server/chunks/7774.js +2 -2
- package/app/.next/server/chunks/8866.js +1 -1
- package/app/.next/server/chunks/9718.js +1 -1
- package/app/.next/server/middleware-build-manifest.js +1 -1
- package/app/.next/server/middleware.js +1 -1
- package/app/.next/server/pages/404.html +1 -1
- package/app/.next/server/pages/500.html +1 -1
- package/app/.next/static/9qtW6KlzV_D2b828CZp1A/_buildManifest.js +1 -0
- package/app/.next/static/chunks/{1321-194580b028caec3a.js → 1321-634f2d25db77d618.js} +1 -1
- package/app/.next/static/chunks/5095-42d435b0583b2f98.js +2 -0
- package/app/.next/static/chunks/main-2237af167d2c1c35.js +5 -0
- package/app/package.json +1 -1
- package/app/src/mitm/config.js +1 -0
- package/app/src/mitm/dns/dnsConfig.js +20 -73
- package/app/src/mitm/handlers/base.js +19 -20
- package/app/src/mitm/manager.js +79 -45
- package/app/src/mitm/server.js +36 -36
- package/cli.js +0 -170
- package/hooks/postinstall.js +25 -26
- package/package.json +1 -1
- package/app/.next/static/XHWEINo8HqIhskxHTrvjk/_buildManifest.js +0 -1
- package/app/.next/static/chunks/5095-fea302b55a08f07b.js +0 -2
- package/app/.next/static/chunks/main-9b9267659a73e61e.js +0 -5
- /package/app/.next/static/{XHWEINo8HqIhskxHTrvjk → 9qtW6KlzV_D2b828CZp1A}/_ssgManifest.js +0 -0
|
@@ -2,9 +2,7 @@ const { exec, spawn, execSync } = require("child_process");
|
|
|
2
2
|
const fs = require("fs");
|
|
3
3
|
const path = require("path");
|
|
4
4
|
const os = require("os");
|
|
5
|
-
const dns = require("dns");
|
|
6
5
|
const { log, err } = require("../logger");
|
|
7
|
-
const { MITM_DIR } = require("../paths");
|
|
8
6
|
const { TOOL_HOSTS } = require("../../shared/constants/mitmToolHosts.js");
|
|
9
7
|
const { runElevatedPowerShell, isAdmin } = require("../winElevated.js");
|
|
10
8
|
|
|
@@ -39,22 +37,23 @@ const HOSTS_FILE = IS_WIN
|
|
|
39
37
|
? path.join(process.env.SystemRoot || "C:\\Windows", "System32", "drivers", "etc", "hosts")
|
|
40
38
|
: "/etc/hosts";
|
|
41
39
|
const MAC_PF_ANTIGRAVITY_ANCHOR = "com.apple/openrouterx-mitm-antigravity";
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
const MAC_ANTIGRAVITY_FALLBACK_IPS = [
|
|
41
|
+
"216.239.32.223",
|
|
42
|
+
"216.239.34.223",
|
|
43
|
+
"216.239.36.223",
|
|
44
|
+
"216.239.38.223",
|
|
45
|
+
];
|
|
45
46
|
const MAC_ANTIGRAVITY_LEGACY_SHARED_IP_PREFIXES = [
|
|
46
|
-
"64.233.",
|
|
47
|
-
"66.102.",
|
|
48
|
-
"74.125.",
|
|
49
47
|
"142.250.",
|
|
50
48
|
"142.251.",
|
|
51
49
|
"172.217.",
|
|
52
|
-
"172.253.",
|
|
53
|
-
"216.58.",
|
|
54
|
-
"216.239.",
|
|
55
50
|
];
|
|
56
51
|
const REQUIRED_HOST_LOOPBACKS = IS_WIN ? ["127.0.0.1"] : ["127.0.0.1", "::1"];
|
|
57
52
|
|
|
53
|
+
function isMacAntigravityPfRedirectEnabled(env = process.env) {
|
|
54
|
+
return String(env.OPENROUTERX_MITM_ANTIGRAVITY_PF || "").trim() === "1";
|
|
55
|
+
}
|
|
56
|
+
|
|
58
57
|
function lineHasHostEntry(line, address, host) {
|
|
59
58
|
const trimmed = String(line || "").trim();
|
|
60
59
|
if (!trimmed || trimmed.startsWith("#")) return false;
|
|
@@ -170,55 +169,8 @@ function getDefaultMacInterface() {
|
|
|
170
169
|
}
|
|
171
170
|
}
|
|
172
171
|
|
|
173
|
-
async function
|
|
174
|
-
|
|
175
|
-
resolver.setServers([server]);
|
|
176
|
-
try {
|
|
177
|
-
return await withTimeout(resolver.resolve4(host), MAC_ANTIGRAVITY_DNS_TIMEOUT_MS);
|
|
178
|
-
} catch {
|
|
179
|
-
return [];
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
function withTimeout(promise, timeoutMs) {
|
|
184
|
-
let timeout;
|
|
185
|
-
return Promise.race([
|
|
186
|
-
promise,
|
|
187
|
-
new Promise((_, reject) => {
|
|
188
|
-
timeout = setTimeout(() => reject(new Error("DNS query timed out")), timeoutMs);
|
|
189
|
-
}),
|
|
190
|
-
]).finally(() => clearTimeout(timeout));
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
async function getMacAntigravityRedirectIPs(hosts = TOOL_HOSTS.antigravity, servers = MAC_ANTIGRAVITY_DNS_SERVERS) {
|
|
194
|
-
if (!IS_MAC) return [];
|
|
195
|
-
const resolved = await Promise.all(
|
|
196
|
-
hosts.flatMap((host) => servers.map((server) => resolveIPv4WithServer(host, server)))
|
|
197
|
-
);
|
|
198
|
-
return [...new Set(resolved.flat())].filter((ip) => /^\d+\.\d+\.\d+\.\d+$/.test(ip));
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
function saveMacAntigravityRedirectIPs(ips) {
|
|
202
|
-
if (!IS_MAC) return;
|
|
203
|
-
try {
|
|
204
|
-
fs.mkdirSync(MITM_DIR, { recursive: true });
|
|
205
|
-
fs.writeFileSync(MAC_ANTIGRAVITY_REDIRECT_STATE_FILE, JSON.stringify({
|
|
206
|
-
ips: [...new Set(ips || [])],
|
|
207
|
-
updatedAt: new Date().toISOString(),
|
|
208
|
-
}, null, 2), "utf8");
|
|
209
|
-
} catch (e) {
|
|
210
|
-
err(`PF antigravity: failed to save redirect IP state — ${e.message}`);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
function readMacAntigravityRedirectIPs() {
|
|
215
|
-
if (!IS_MAC) return [];
|
|
216
|
-
try {
|
|
217
|
-
const parsed = JSON.parse(fs.readFileSync(MAC_ANTIGRAVITY_REDIRECT_STATE_FILE, "utf8"));
|
|
218
|
-
return Array.isArray(parsed.ips) ? parsed.ips.filter((ip) => /^\d+\.\d+\.\d+\.\d+$/.test(ip)) : [];
|
|
219
|
-
} catch {
|
|
220
|
-
return [];
|
|
221
|
-
}
|
|
172
|
+
async function getMacAntigravityRedirectIPs() {
|
|
173
|
+
return [...MAC_ANTIGRAVITY_FALLBACK_IPS];
|
|
222
174
|
}
|
|
223
175
|
|
|
224
176
|
function getMacLoopbackIPv4Aliases() {
|
|
@@ -239,13 +191,15 @@ function getMacLegacyAntigravityAliases() {
|
|
|
239
191
|
|
|
240
192
|
async function enableMacAntigravityRedirect(sudoPassword) {
|
|
241
193
|
if (!IS_MAC) return;
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
194
|
+
if (!isMacAntigravityPfRedirectEnabled()) {
|
|
195
|
+
await disableMacAntigravityRedirect(sudoPassword);
|
|
196
|
+
log("🌐 PF antigravity: skipped (hosts-only mode; set OPENROUTERX_MITM_ANTIGRAVITY_PF=1 to opt in)");
|
|
197
|
+
return;
|
|
245
198
|
}
|
|
199
|
+
const ips = await getMacAntigravityRedirectIPs();
|
|
200
|
+
if (ips.length === 0) return;
|
|
246
201
|
|
|
247
202
|
await enableMacAntigravityLoopbackAliases(sudoPassword, ips);
|
|
248
|
-
saveMacAntigravityRedirectIPs(ips);
|
|
249
203
|
|
|
250
204
|
const iface = getDefaultMacInterface();
|
|
251
205
|
const rules = [
|
|
@@ -265,13 +219,11 @@ async function enableMacAntigravityRedirect(sudoPassword) {
|
|
|
265
219
|
async function disableMacAntigravityRedirect(sudoPassword) {
|
|
266
220
|
if (!IS_MAC) return;
|
|
267
221
|
const ips = [...new Set([
|
|
268
|
-
...readMacAntigravityRedirectIPs(),
|
|
269
222
|
...await getMacAntigravityRedirectIPs(),
|
|
270
223
|
...getMacLegacyAntigravityAliases(),
|
|
271
224
|
])];
|
|
272
225
|
await execWithPassword(`pfctl -a ${shellQuoteSingle(MAC_PF_ANTIGRAVITY_ANCHOR)} -F all >/dev/null 2>&1 || true`, sudoPassword);
|
|
273
226
|
await disableMacAntigravityLoopbackAliases(sudoPassword, ips);
|
|
274
|
-
try { fs.unlinkSync(MAC_ANTIGRAVITY_REDIRECT_STATE_FILE); } catch { /* none */ }
|
|
275
227
|
log("🌐 PF antigravity: ✅ redirect removed");
|
|
276
228
|
}
|
|
277
229
|
|
|
@@ -426,13 +378,9 @@ function removeAllDNSEntriesSync() {
|
|
|
426
378
|
try {
|
|
427
379
|
if (IS_MAC) {
|
|
428
380
|
try { execSync(`pfctl -a ${MAC_PF_ANTIGRAVITY_ANCHOR} -F all >/dev/null 2>&1 || true`, { stdio: "ignore" }); } catch { /* ignore */ }
|
|
429
|
-
for (const ip of
|
|
430
|
-
...readMacAntigravityRedirectIPs(),
|
|
431
|
-
...getMacLegacyAntigravityAliases(),
|
|
432
|
-
])]) {
|
|
381
|
+
for (const ip of MAC_ANTIGRAVITY_FALLBACK_IPS) {
|
|
433
382
|
try { execSync(`ifconfig lo0 -alias ${ip} 2>/dev/null || true`, { stdio: "ignore" }); } catch { /* ignore */ }
|
|
434
383
|
}
|
|
435
|
-
try { fs.unlinkSync(MAC_ANTIGRAVITY_REDIRECT_STATE_FILE); } catch { /* ignore */ }
|
|
436
384
|
}
|
|
437
385
|
if (!fs.existsSync(HOSTS_FILE)) return;
|
|
438
386
|
const allHosts = Object.values(TOOL_HOSTS).flat();
|
|
@@ -466,6 +414,5 @@ module.exports = {
|
|
|
466
414
|
checkAllDNSStatus,
|
|
467
415
|
getMissingHostsEntries,
|
|
468
416
|
hostHasRequiredLoopbacks,
|
|
469
|
-
|
|
470
|
-
readMacAntigravityRedirectIPs,
|
|
417
|
+
isMacAntigravityPfRedirectEnabled,
|
|
471
418
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const { log, err } = require("../logger");
|
|
2
2
|
|
|
3
|
-
const DEFAULT_LOCAL_ROUTER = "http://
|
|
3
|
+
const DEFAULT_LOCAL_ROUTER = "http://localhost:20502";
|
|
4
4
|
const ROUTER_BASE = String(process.env.MITM_ROUTER_BASE || DEFAULT_LOCAL_ROUTER)
|
|
5
5
|
.trim()
|
|
6
6
|
.replace(/\/+$/, "") || DEFAULT_LOCAL_ROUTER;
|
|
@@ -12,34 +12,33 @@ const STRIP_HEADERS = new Set([
|
|
|
12
12
|
"content-type", "authorization"
|
|
13
13
|
]);
|
|
14
14
|
|
|
15
|
+
function normalizeRouterPath(path) {
|
|
16
|
+
const rawPath = String(path || "").trim() || "/v1/chat/completions";
|
|
17
|
+
if (rawPath === "/v1") return "/api/v1";
|
|
18
|
+
if (rawPath.startsWith("/v1/")) return `/api${rawPath}`;
|
|
19
|
+
return rawPath;
|
|
20
|
+
}
|
|
21
|
+
|
|
15
22
|
/**
|
|
16
23
|
* Send body to OpenrouterX at the given path and return the fetch Response object.
|
|
17
24
|
* Optionally forwards client headers (stripped of hop-by-hop / overridden keys).
|
|
18
25
|
*/
|
|
19
26
|
async function fetchRouter(openaiBody, path = "/v1/chat/completions", clientHeaders = {}) {
|
|
27
|
+
const routerPath = normalizeRouterPath(path);
|
|
20
28
|
const forwarded = {};
|
|
21
29
|
for (const [k, v] of Object.entries(clientHeaders)) {
|
|
22
30
|
if (!STRIP_HEADERS.has(k.toLowerCase())) forwarded[k] = v;
|
|
23
31
|
}
|
|
24
32
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
body: JSON.stringify(openaiBody)
|
|
35
|
-
});
|
|
36
|
-
} catch (error) {
|
|
37
|
-
const cause = error.cause;
|
|
38
|
-
const causeDetail = cause
|
|
39
|
-
? ` (cause: ${cause.code || cause.name || "unknown"}: ${cause.message || cause})`
|
|
40
|
-
: "";
|
|
41
|
-
throw new Error(`Router fetch failed for ${ROUTER_BASE}${path}: ${error.message}${causeDetail}`);
|
|
42
|
-
}
|
|
33
|
+
const response = await fetch(`${ROUTER_BASE}${routerPath}`, {
|
|
34
|
+
method: "POST",
|
|
35
|
+
headers: {
|
|
36
|
+
...forwarded,
|
|
37
|
+
"Content-Type": "application/json",
|
|
38
|
+
...(API_KEY && { "Authorization": `Bearer ${API_KEY}` })
|
|
39
|
+
},
|
|
40
|
+
body: JSON.stringify(openaiBody)
|
|
41
|
+
});
|
|
43
42
|
|
|
44
43
|
// Forward response as-is (status + body). pipeSSE will propagate status.
|
|
45
44
|
return response;
|
|
@@ -74,4 +73,4 @@ async function pipeSSE(routerRes, res, dumper) {
|
|
|
74
73
|
}
|
|
75
74
|
}
|
|
76
75
|
|
|
77
|
-
module.exports = { fetchRouter, pipeSSE };
|
|
76
|
+
module.exports = { fetchRouter, normalizeRouterPath, pipeSSE };
|
package/app/src/mitm/manager.js
CHANGED
|
@@ -16,31 +16,90 @@ const { isCertExpired } = require("./cert/rootCA");
|
|
|
16
16
|
const { DATA_DIR, MITM_DIR } = require("./paths");
|
|
17
17
|
const { log, err } = require("./logger");
|
|
18
18
|
|
|
19
|
-
const DEFAULT_MITM_ROUTER_BASE = "http://
|
|
20
|
-
const LEGACY_DEFAULT_MITM_ROUTER_BASES = new Set([
|
|
21
|
-
"http://localhost:20128",
|
|
22
|
-
"http://127.0.0.1:20128",
|
|
23
|
-
]);
|
|
19
|
+
const DEFAULT_MITM_ROUTER_BASE = "http://localhost:20502";
|
|
24
20
|
|
|
25
21
|
function shellQuoteSingle(str) {
|
|
26
22
|
if (str == null || str === "") return "''";
|
|
27
23
|
return `'${String(str).replace(/'/g, "'\\''")}'`;
|
|
28
24
|
}
|
|
29
25
|
|
|
26
|
+
function normalizeHttpBaseUrl(input) {
|
|
27
|
+
const raw = input == null ? "" : String(input).trim();
|
|
28
|
+
if (!raw) return "";
|
|
29
|
+
try {
|
|
30
|
+
const u = new URL(raw.replace(/\/+$/, ""));
|
|
31
|
+
if (u.protocol !== "http:" && u.protocol !== "https:") return "";
|
|
32
|
+
return u.toString().replace(/\/+$/, "");
|
|
33
|
+
} catch {
|
|
34
|
+
return "";
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function isLoopbackBaseUrl(baseUrl) {
|
|
39
|
+
try {
|
|
40
|
+
const host = new URL(baseUrl).hostname.toLowerCase();
|
|
41
|
+
return host === "localhost" || host === "127.0.0.1" || host === "::1";
|
|
42
|
+
} catch {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function readCurrentServerBaseUrl() {
|
|
48
|
+
try {
|
|
49
|
+
const file = path.join(DATA_DIR, "server.json");
|
|
50
|
+
if (!fs.existsSync(file)) return "";
|
|
51
|
+
const parsed = JSON.parse(fs.readFileSync(file, "utf8"));
|
|
52
|
+
return normalizeHttpBaseUrl(parsed && parsed.baseUrl);
|
|
53
|
+
} catch {
|
|
54
|
+
return "";
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function canConnectBaseUrl(baseUrl, timeoutMs = 350) {
|
|
59
|
+
return new Promise((resolve) => {
|
|
60
|
+
let u;
|
|
61
|
+
try {
|
|
62
|
+
u = new URL(baseUrl);
|
|
63
|
+
} catch {
|
|
64
|
+
resolve(false);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const port = Number(u.port || (u.protocol === "https:" ? 443 : 80));
|
|
69
|
+
const socket = net.connect({ host: u.hostname, port });
|
|
70
|
+
const done = (ok) => {
|
|
71
|
+
socket.removeAllListeners();
|
|
72
|
+
socket.destroy();
|
|
73
|
+
resolve(ok);
|
|
74
|
+
};
|
|
75
|
+
socket.setTimeout(timeoutMs, () => done(false));
|
|
76
|
+
socket.once("connect", () => done(true));
|
|
77
|
+
socket.once("error", () => done(false));
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
30
81
|
async function resolveMitmRouterBaseUrl() {
|
|
31
|
-
|
|
82
|
+
const currentServerBase = readCurrentServerBaseUrl();
|
|
83
|
+
if (!_getSettings) return currentServerBase || DEFAULT_MITM_ROUTER_BASE;
|
|
32
84
|
try {
|
|
33
85
|
const s = await _getSettings();
|
|
34
|
-
const
|
|
35
|
-
if (!
|
|
36
|
-
|
|
37
|
-
|
|
86
|
+
const configuredBase = normalizeHttpBaseUrl(s && s.mitmRouterBaseUrl);
|
|
87
|
+
if (!configuredBase) return currentServerBase || DEFAULT_MITM_ROUTER_BASE;
|
|
88
|
+
|
|
89
|
+
if (isLoopbackBaseUrl(configuredBase) && currentServerBase && configuredBase !== currentServerBase) {
|
|
90
|
+
const configuredAlive = await canConnectBaseUrl(configuredBase);
|
|
91
|
+
if (!configuredAlive && await canConnectBaseUrl(currentServerBase)) {
|
|
92
|
+
if (_updateSettings) {
|
|
93
|
+
_updateSettings({ mitmRouterBaseUrl: currentServerBase }).catch(() => { });
|
|
94
|
+
}
|
|
95
|
+
log(`🚀 MITM router base auto-corrected: ${configuredBase} → ${currentServerBase}`);
|
|
96
|
+
return currentServerBase;
|
|
97
|
+
}
|
|
38
98
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
return raw.replace(/\/+$/, "");
|
|
99
|
+
|
|
100
|
+
return configuredBase;
|
|
42
101
|
} catch {
|
|
43
|
-
return DEFAULT_MITM_ROUTER_BASE;
|
|
102
|
+
return currentServerBase || DEFAULT_MITM_ROUTER_BASE;
|
|
44
103
|
}
|
|
45
104
|
}
|
|
46
105
|
|
|
@@ -405,7 +464,7 @@ async function scheduleMitmRestart(apiKey) {
|
|
|
405
464
|
mitmIsRestarting = false;
|
|
406
465
|
return;
|
|
407
466
|
}
|
|
408
|
-
await startServer(apiKey, password
|
|
467
|
+
await startServer(apiKey, password);
|
|
409
468
|
log("🔄 Restarted successfully");
|
|
410
469
|
mitmRestartCount = 0;
|
|
411
470
|
mitmIsRestarting = false;
|
|
@@ -439,23 +498,7 @@ async function killPort443Owner(owner, sudoPassword) {
|
|
|
439
498
|
await new Promise(r => setTimeout(r, 800));
|
|
440
499
|
}
|
|
441
500
|
|
|
442
|
-
async function
|
|
443
|
-
const health = await pollMitmHealth(1000, MITM_PORT);
|
|
444
|
-
if (!health) return null;
|
|
445
|
-
|
|
446
|
-
const pid = health.pid || serverPid || (() => {
|
|
447
|
-
try { return parseInt(fs.readFileSync(PID_FILE, "utf-8").trim(), 10); } catch { return null; }
|
|
448
|
-
})();
|
|
449
|
-
if (pid) {
|
|
450
|
-
serverPid = pid;
|
|
451
|
-
try { fs.writeFileSync(PID_FILE, String(pid)); } catch { /* ignore */ }
|
|
452
|
-
}
|
|
453
|
-
await saveMitmSettings(true, sudoPassword);
|
|
454
|
-
return { running: true, pid: serverPid || pid };
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
async function startServer(apiKey, sudoPassword, forceKillPort443 = false, options = {}) {
|
|
458
|
-
const isRestart = options.restart === true;
|
|
501
|
+
async function startServer(apiKey, sudoPassword, forceKillPort443 = false) {
|
|
459
502
|
if (!serverProcess || serverProcess.killed) {
|
|
460
503
|
try {
|
|
461
504
|
if (fs.existsSync(PID_FILE)) {
|
|
@@ -474,13 +517,7 @@ async function startServer(apiKey, sudoPassword, forceKillPort443 = false, optio
|
|
|
474
517
|
}
|
|
475
518
|
|
|
476
519
|
if (serverProcess && !serverProcess.killed) {
|
|
477
|
-
|
|
478
|
-
if (healthy) return healthy;
|
|
479
|
-
if (isRestart) {
|
|
480
|
-
await killLeftoverMitm(sudoPassword);
|
|
481
|
-
} else {
|
|
482
|
-
throw new Error("MITM server is already running");
|
|
483
|
-
}
|
|
520
|
+
throw new Error("MITM server is already running");
|
|
484
521
|
}
|
|
485
522
|
|
|
486
523
|
await killLeftoverMitm(sudoPassword);
|
|
@@ -673,18 +710,12 @@ async function startServer(apiKey, sudoPassword, forceKillPort443 = false, optio
|
|
|
673
710
|
const health = await pollMitmHealth(8000, MITM_PORT);
|
|
674
711
|
if (!health) {
|
|
675
712
|
if (serverProcess && !serverProcess.killed) { try { serverProcess.kill(); } catch { /* ignore */ } serverProcess = null; }
|
|
676
|
-
serverPid = null;
|
|
677
713
|
const processUsing443 = getProcessUsingPort443();
|
|
678
714
|
const portInfo = processUsing443 ? ` Port 443 already in use by ${processUsing443}.` : "";
|
|
679
715
|
const reason = startError || `Check sudo password or port 443 access.${portInfo}`;
|
|
680
716
|
throw new Error(`MITM server failed to start. ${reason}`);
|
|
681
717
|
}
|
|
682
718
|
|
|
683
|
-
if (health.pid && health.pid !== serverPid) {
|
|
684
|
-
serverPid = health.pid;
|
|
685
|
-
try { fs.writeFileSync(PID_FILE, String(serverPid)); } catch { /* ignore */ }
|
|
686
|
-
}
|
|
687
|
-
|
|
688
719
|
if (_updateSettings) await _updateSettings({ mitmCertInstalled: true }).catch(() => { });
|
|
689
720
|
|
|
690
721
|
log(`✅ Server healthy (PID: ${serverPid || health.pid})`);
|
|
@@ -827,4 +858,7 @@ module.exports = {
|
|
|
827
858
|
restoreToolDNS,
|
|
828
859
|
hasDnsPrivilege,
|
|
829
860
|
removeAllDNSEntriesSync,
|
|
861
|
+
resolveMitmRouterBaseUrl,
|
|
862
|
+
normalizeHttpBaseUrl,
|
|
863
|
+
readCurrentServerBaseUrl,
|
|
830
864
|
};
|
package/app/src/mitm/server.js
CHANGED
|
@@ -344,47 +344,47 @@ async function passthrough(req, res, bodyBuffer, onResponse, transformResponse)
|
|
|
344
344
|
servername: targetHost,
|
|
345
345
|
rejectUnauthorized: false
|
|
346
346
|
}, (forwardRes) => {
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
347
|
+
// When transformResponse is provided, buffer the full response so we can
|
|
348
|
+
// modify it before sending to the client.
|
|
349
|
+
const shouldBuffer = transformResponse != null;
|
|
350
|
+
if (!shouldBuffer) res.writeHead(forwardRes.statusCode, forwardRes.headers);
|
|
351
351
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
352
|
+
if (!onResponse && !dumper && !shouldBuffer) {
|
|
353
|
+
forwardRes.pipe(res);
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
356
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
357
|
+
const chunks = [];
|
|
358
|
+
forwardRes.on("data", chunk => {
|
|
359
|
+
if (dumper) dumper.writeChunk(chunk);
|
|
360
|
+
if (onResponse || shouldBuffer) chunks.push(chunk);
|
|
361
|
+
if (!shouldBuffer) res.write(chunk);
|
|
362
|
+
});
|
|
363
|
+
forwardRes.on("end", () => {
|
|
364
|
+
const rawBuffer = Buffer.concat(chunks);
|
|
365
|
+
|
|
366
|
+
if (shouldBuffer) {
|
|
367
|
+
try {
|
|
368
|
+
const modified = transformResponse(rawBuffer, forwardRes.headers);
|
|
369
|
+
// Update Content-Length if present to match modified body
|
|
370
|
+
const headers = { ...forwardRes.headers };
|
|
371
|
+
if (headers["content-length"] != null) {
|
|
372
|
+
headers["content-length"] = String(Buffer.byteLength(modified));
|
|
373
|
+
}
|
|
374
|
+
res.writeHead(forwardRes.statusCode, headers);
|
|
375
|
+
res.end(modified);
|
|
376
|
+
} catch (e) {
|
|
377
|
+
err(`transformResponse error: ${e.message}`);
|
|
378
|
+
if (!res.headersSent) res.writeHead(502);
|
|
379
|
+
res.end("Bad Gateway");
|
|
373
380
|
}
|
|
374
|
-
|
|
375
|
-
res.end(
|
|
376
|
-
} catch (e) {
|
|
377
|
-
err(`transformResponse error: ${e.message}`);
|
|
378
|
-
if (!res.headersSent) res.writeHead(502);
|
|
379
|
-
res.end("Bad Gateway");
|
|
381
|
+
} else {
|
|
382
|
+
res.end();
|
|
380
383
|
}
|
|
381
|
-
} else {
|
|
382
|
-
res.end();
|
|
383
|
-
}
|
|
384
384
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
385
|
+
if (dumper) dumper.end();
|
|
386
|
+
if (onResponse) try { onResponse(rawBuffer, forwardRes.headers); } catch { /* ignore */ }
|
|
387
|
+
});
|
|
388
388
|
});
|
|
389
389
|
|
|
390
390
|
forwardReq.on("error", (e) => {
|