sliccy 6.211.0 → 6.212.0
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/dist/node-server/_shared/index.d.ts +1 -0
- package/dist/node-server/_shared/index.d.ts.map +1 -1
- package/dist/node-server/_shared/index.js +1 -0
- package/dist/node-server/_shared/index.js.map +1 -1
- package/dist/node-server/_shared/raw-fetch-protocol.d.ts +149 -0
- package/dist/node-server/_shared/raw-fetch-protocol.d.ts.map +1 -0
- package/dist/node-server/_shared/raw-fetch-protocol.js +296 -0
- package/dist/node-server/_shared/raw-fetch-protocol.js.map +1 -0
- package/dist/node-server/fetch-proxy-headers.d.ts +3 -1
- package/dist/node-server/fetch-proxy-headers.js +5 -1
- package/dist/node-server/index.js +14 -3
- package/dist/node-server/routes/fetch-proxy-raw.d.ts +43 -0
- package/dist/node-server/routes/fetch-proxy-raw.js +205 -0
- package/dist/node-server/routes/fetch-proxy.d.ts +23 -0
- package/dist/node-server/routes/fetch-proxy.js +4 -3
- package/dist/ui/.vite/manifest.json +182 -182
- package/dist/ui/assets/SKILL-CN4LOg1h.js +1 -0
- package/dist/ui/assets/{account-store-CwNcf5Wq.js → account-store-DdclMpWp.js} +1 -1
- package/dist/ui/assets/{account-store-nlKbTUhJ.js → account-store-DnIs5WZM.js} +1 -1
- package/dist/ui/assets/{adobe-DBVa9oOG.js → adobe-BNRJjQn6.js} +1 -1
- package/dist/ui/assets/{adobe-D7sqH2X_.js → adobe-w_RhhSWv.js} +1 -1
- package/dist/ui/assets/{agent-panels-B0VuA3mU.js → agent-panels-B-6e5X0F.js} +1 -1
- package/dist/ui/assets/{almost-bash-shell-headless-C0x2DyFh.js → almost-bash-shell-headless-D19kpvHY.js} +154 -149
- package/dist/ui/assets/{apply-layout-fciODM2t.js → apply-layout-oUk89jk1.js} +1 -1
- package/dist/ui/assets/{apps-RVxpwEfn.js → apps-oJ_nTgiK.js} +1 -1
- package/dist/ui/assets/{azure-openai-QS8TU-7m.js → azure-openai-BKBBD2Dq.js} +1 -1
- package/dist/ui/assets/{azure-openai-JxdRj-Iq.js → azure-openai-zqUyJv0c.js} +1 -1
- package/dist/ui/assets/{backend-hostfs-CITljQVo.js → backend-hostfs-BotdHD_S.js} +1 -1
- package/dist/ui/assets/{bsh-watchdog-BTB0exmo.js → bsh-watchdog-TYuawE-B.js} +1 -1
- package/dist/ui/assets/{cdp-Djm-AVXd.js → cdp-C0InCdRQ.js} +1 -1
- package/dist/ui/assets/{cerebras-DvIFsdoW.js → cerebras-ChWjfEi0.js} +1 -1
- package/dist/ui/assets/{cerebras-Czq0QoYg.js → cerebras-DL4U9Vjg.js} +1 -1
- package/dist/ui/assets/{client-CwxmlQM-.js → client-dISfU5Wf.js} +1 -1
- package/dist/ui/assets/{composer-speech-DgLXFFNQ.js → composer-speech-d-ejBNSK.js} +1 -1
- package/dist/ui/assets/{connect-surface-YjzKwUub.js → connect-surface-DNUrGg9g.js} +1 -1
- package/dist/ui/assets/{core-C7UGykIC.js → core-DZ0CleVD.js} +2 -2
- package/dist/ui/assets/{directed-approval-BMnSWjrJ.js → directed-approval-ol0Z6v9I.js} +1 -1
- package/dist/ui/assets/{emscripten-vfs-hook-CwbQLP-I.js → emscripten-vfs-hook-fCUbQRCb.js} +1 -1
- package/dist/ui/assets/{ensure-speech-assets-Bqf-swhU.js → ensure-speech-assets-S71yPbdv.js} +1 -1
- package/dist/ui/assets/{esbuild-wasm-DIcMVR3g.js → esbuild-wasm-llEEkCQu.js} +1 -1
- package/dist/ui/assets/{extension-ops-CF2mLDRW.js → extension-ops-CEprwZyb.js} +1 -1
- package/dist/ui/assets/{ffmpeg-wasm-B5jofhIa.js → ffmpeg-wasm-DGDKCZ27.js} +1 -1
- package/dist/ui/assets/{frozen-archive-writer-BV51qDTg.js → frozen-archive-writer-khicEqGd.js} +1 -1
- package/dist/ui/assets/{fs-ZnsLbva1.js → fs-CIR1p_m7.js} +1 -1
- package/dist/ui/assets/{fs-pBJBtnUm.js → fs-D6QJU-ZE.js} +2 -2
- package/dist/ui/assets/{gelatiere-store-B-PMFWOJ.js → gelatiere-store-CYdUzk1p.js} +1 -1
- package/dist/ui/assets/{gelatiere-unit-B7YUbTOe.js → gelatiere-unit-Dzkphhv5.js} +1 -1
- package/dist/ui/assets/{github-CRKKUq6c.js → github-8QTzsnR3.js} +1 -1
- package/dist/ui/assets/{github-q7aLpavT.js → github-BdQ6NNi6.js} +2 -2
- package/dist/ui/assets/{github-auth-DPBopdHy.js → github-auth-CgSRRmdA.js} +1 -1
- package/dist/ui/assets/{github-copilot-Cn5WeEVQ.js → github-copilot-Beq3TkEz.js} +1 -1
- package/dist/ui/assets/{github-copilot-BOqjn_pA.js → github-copilot-C6ZXCgIT.js} +1 -1
- package/dist/ui/assets/{github-install-Dlx1x9oP.js → github-install-BV6F_EyI.js} +1 -1
- package/dist/ui/assets/{github-zip-BKesEE7T.js → github-zip-nn7aW2E1.js} +1 -1
- package/dist/ui/assets/{guest-tool-gate-DbuM_BFG.js → guest-tool-gate-4cZHoDbf.js} +1 -1
- package/dist/ui/assets/{hear-BAlAHUln.js → hear-HND90jpV.js} +1 -1
- package/dist/ui/assets/{help-MPD6QjSi.js → help-Dgt88ySg.js} +1 -1
- package/dist/ui/assets/{installer-DR7izkMG.js → installer-BdG_mJUp.js} +1 -1
- package/dist/ui/assets/{interrupted-work-recovery-DKlfO3Dk.js → interrupted-work-recovery-niFgJlYA.js} +1 -1
- package/dist/ui/assets/{ipk-mamba-B7DsVAHB.js → ipk-mamba-DMPz0Na-.js} +1 -1
- package/dist/ui/assets/{js-realm-worker-Dj6E7cem.js → js-realm-worker-Dt6CkC-q.js} +2 -2
- package/dist/ui/assets/{jsh-executor-DOTwZy5W.js → jsh-executor-m_BRqJJW.js} +2 -2
- package/dist/ui/assets/{kernel-worker-C6evRbt8.js → kernel-worker-Bejt-Ojz.js} +10 -10
- package/dist/ui/assets/{lick-ws-bridge-DEO3vHuX.js → lick-ws-bridge-DoT1E5ir.js} +1 -1
- package/dist/ui/assets/{lick-ws-bridge-cpYoem5_.js → lick-ws-bridge-Nul1wz09.js} +1 -1
- package/dist/ui/assets/{live-session-curation-BM8tZX-r.js → live-session-curation-BKsScSRB.js} +1 -1
- package/dist/ui/assets/{live-session-snapshot-C2NMVRMF.js → live-session-snapshot-6V9mPUM5.js} +1 -1
- package/dist/ui/assets/{local-llm-Cfh9VuPq.js → local-llm-C0NdLczW.js} +1 -1
- package/dist/ui/assets/{local-llm-z-cBJlKf.js → local-llm-DoZ2LiSE.js} +1 -1
- package/dist/ui/assets/{magick-wasm-agWGi-e0.js → magick-wasm-BL5NYmcE.js} +1 -1
- package/dist/ui/assets/{main-tEtVPbXh.js → main-DmLxMDGT.js} +3 -3
- package/dist/ui/assets/{main-cherry-CbQUCau8.js → main-cherry-C3pK2VKW.js} +1 -1
- package/dist/ui/assets/{memory-curation-seam-CjBglHNa.js → memory-curation-seam-B_5OPYdP.js} +1 -1
- package/dist/ui/assets/{memory-health-CPzWzT1P.js → memory-health-CRH2Blzq.js} +1 -1
- package/dist/ui/assets/{memory-write-execute-DqWqBfwf.js → memory-write-execute-BfCExMYN.js} +1 -1
- package/dist/ui/assets/{merge-folded-cost-into-frozen-DCuPhNTk.js → merge-folded-cost-into-frozen-CoL4Bfzs.js} +1 -1
- package/dist/ui/assets/{mount-ydk0WHgG.js → mount-B3v77n4z.js} +3 -3
- package/dist/ui/assets/{mount-4dZRjkrQ.js → mount-TnWJttSG.js} +1 -1
- package/dist/ui/assets/{mount-bridge-client-Dz_UHbPE.js → mount-bridge-client-DkrmF1xh.js} +1 -1
- package/dist/ui/assets/{new-session-C5MEP_cK.js → new-session-C8MNLQeR.js} +2 -2
- package/dist/ui/assets/{oauth-bootstrap-BVUK3GEs.js → oauth-bootstrap-BW3jawLe.js} +2 -2
- package/dist/ui/assets/{oauth-service-DP3Rx6V_.js → oauth-service-B_A2Hp66.js} +1 -1
- package/dist/ui/assets/{onboarding-orchestrator-DftSEsKa.js → onboarding-orchestrator-Ca5D3wWS.js} +1 -1
- package/dist/ui/assets/{openai-codex-fJtQGV69.js → openai-codex-B-c0ZWNV.js} +1 -1
- package/dist/ui/assets/{openai-codex-Cwz1FT-z.js → openai-codex-CMsdDz1G.js} +1 -1
- package/dist/ui/assets/{openrouter-rcqoBXaw.js → openrouter-B7Sm8SVp.js} +1 -1
- package/dist/ui/assets/{openrouter-DmEz5WxK.js → openrouter-ChF-ckvt.js} +1 -1
- package/dist/ui/assets/{openrouter-free-C5O97xvy.js → openrouter-free-D6PoJTox.js} +1 -1
- package/dist/ui/assets/{openrouter-free-DRw-DHQn.js → openrouter-free-F9UehDw-.js} +1 -1
- package/dist/ui/assets/{openrouter-oauth-Csq32wt2.js → openrouter-oauth-CWDz3gd8.js} +1 -1
- package/dist/ui/assets/{openrouter-oauth-C4uIzDcA.js → openrouter-oauth-ClC2jnRu.js} +1 -1
- package/dist/ui/assets/{opfs-mount-C0Lus0Cz.js → opfs-mount-mkZhMkc1.js} +1 -1
- package/dist/ui/assets/{panel-rpc-handlers-B9LenTR0.js → panel-rpc-handlers-BGopQTZk.js} +2 -2
- package/dist/ui/assets/{panelize-shell-Dzogbbfc.js → panelize-shell-RRJ2rlAy.js} +1 -1
- package/dist/ui/assets/{pi-edit-execution-D9D4FDIQ.js → pi-edit-execution-Cn6P8kEd.js} +1 -1
- package/dist/ui/assets/{port-bridge-client-B-l7cQTC.js → port-bridge-client-DvO4atpq.js} +1 -1
- package/dist/ui/assets/{provider-CTPdODd7.js → provider-BkkOFpKq.js} +1 -1
- package/dist/ui/assets/{provider-Do-gc4OB.js → provider-CFbeLwlx.js} +2 -2
- package/dist/ui/assets/{provider-settings-DzDdkFMx.js → provider-settings-Df1UWum6.js} +1 -1
- package/dist/ui/assets/provider-store-access-440PUQnq.js +1 -0
- package/dist/ui/assets/provider-store-access-ioP6z6ei.js +1 -0
- package/dist/ui/assets/{providers-1_CCXdq3.js → providers-DelYSiJM.js} +2 -2
- package/dist/ui/assets/{providers-BdG-aC29.js → providers-narfgv33.js} +1 -1
- package/dist/ui/assets/proxied-fetch-Ba8A2Dlh.js +1 -0
- package/dist/ui/assets/proxied-fetch-raw-CzaxeyeU.js +1 -0
- package/dist/ui/assets/proxy-error-BVzVNPvv.js +1 -0
- package/dist/ui/assets/{quick-llm-B07QXQ0s.js → quick-llm-t5wZbj0G.js} +1 -1
- package/dist/ui/assets/{realm-inprocess-wC9VuVQf.js → realm-inprocess-DIZ0NkAs.js} +2 -2
- package/dist/ui/assets/{realm-unhandled-rejections-CEAHL08q.js → realm-unhandled-rejections-BIyM8soC.js} +1 -1
- package/dist/ui/assets/{realm-unhandled-rejections-CuAh-NpD.js → realm-unhandled-rejections-DzT6eKFi.js} +1 -1
- package/dist/ui/assets/{recovery-screen-mPjIBgPH.js → recovery-screen-DvZoe1eu.js} +1 -1
- package/dist/ui/assets/{redirect-uri-CBCnYKsl.js → redirect-uri-DvNqGm3U.js} +1 -1
- package/dist/ui/assets/{remote-terminal-view-DTmUlQlW.js → remote-terminal-view-BeYl7akD.js} +2 -2
- package/dist/ui/assets/{require-guards-CyhsDWYg.js → require-guards-Du4bUc9R.js} +1 -1
- package/dist/ui/assets/{resolver-BjX48SSL.js → resolver-Cuxoosmc.js} +4 -4
- package/dist/ui/assets/{rest-ops-CLliBy-9.js → rest-ops-B4SFZmC5.js} +1 -1
- package/dist/ui/assets/{restore-BSMRZD-l.js → restore-B7CtAq9P.js} +1 -1
- package/dist/ui/assets/{run-CyMKLTKU.js → run-BBYfg5ni.js} +1 -1
- package/dist/ui/assets/run-BUXpkB7_.js +14 -0
- package/dist/ui/assets/{run-CM8a7Cc3.js → run-BVpDhce0.js} +1 -1
- package/dist/ui/assets/{run-C8OfqJcF.js → run-BySbsyjF.js} +2 -2
- package/dist/ui/assets/{run-CJfA-Obt.js → run-C2YgBAHx.js} +1 -1
- package/dist/ui/assets/{run-DMO7-CuA.js → run-DVDUpupT.js} +1 -1
- package/dist/ui/assets/{run-BSt_FVlm.js → run-DkUy3OHx.js} +2 -2
- package/dist/ui/assets/{run-KLXVoIYy.js → run-DpwgbNbp.js} +1 -1
- package/dist/ui/assets/{run-BoxCVicT.js → run-NrNIVu5b.js} +3 -3
- package/dist/ui/assets/{run-CjBpwwpL.js → run-VCYF-r1b.js} +1 -1
- package/dist/ui/assets/{screencapture-run-C3Y7V44Z.js → screencapture-run-DUAmyetz.js} +1 -1
- package/dist/ui/assets/{secrets-bridge-client-BiJrSKN9.js → secrets-bridge-client-Cxg_UIbw.js} +1 -1
- package/dist/ui/assets/{session-command-memory-D9pTlYAY.js → session-command-memory-CwZxueuC.js} +2 -2
- package/dist/ui/assets/{session-jsonl-AoJrx9pb.js → session-jsonl-B0APtun9.js} +1 -1
- package/dist/ui/assets/{session-jsonl-CJzYIghQ.js → session-jsonl-Bf2fgFhg.js} +1 -1
- package/dist/ui/assets/{session-search-index-qOmoZUJy.js → session-search-index-Cj0yWWuZ.js} +1 -1
- package/dist/ui/assets/{setup-feature-flags-remote-BKACONdE.js → setup-feature-flags-remote-DobdVTx1.js} +1 -1
- package/dist/ui/assets/{setup-model-catalog-WWCUCy79.js → setup-model-catalog-D4LHaeXg.js} +1 -1
- package/dist/ui/assets/{shared-Crk4gYF8.js → shared-dvo4ZY2y.js} +1 -1
- package/dist/ui/assets/{signed-fetch-CwZ1-qSJ.js → signed-fetch-i5c9uHzg.js} +1 -1
- package/dist/ui/assets/{silent-renew-backoff-L4eA7UKO.js → silent-renew-backoff-BUgLOZtF.js} +1 -1
- package/dist/ui/assets/slicc-version-CyiNVflt.js +1 -0
- package/dist/ui/assets/{snapshot-D4DlVVCr.js → snapshot-CxBYeic7.js} +1 -1
- package/dist/ui/assets/{snapshot-features-Cp2XSvVD.js → snapshot-features-D9YdXtgT.js} +1 -1
- package/dist/ui/assets/{soundscape-CcHroDUu.js → soundscape-VpddA9af.js} +1 -1
- package/dist/ui/assets/{speak-5UMXEj6t.js → speak-DU6xYfaW.js} +1 -1
- package/dist/ui/assets/{sprinkle-manager-ByfWs52B.js → sprinkle-manager-B23UQfKW.js} +1 -1
- package/dist/ui/assets/{sprinkle-renderer-Dw0Oo-mB.js → sprinkle-renderer-D_eHK453.js} +1 -1
- package/dist/ui/assets/{ssh-ChyTtRdf.js → ssh-DYTFFLnN.js} +1 -1
- package/dist/ui/assets/{state-BPcLy39T.js → state-BEL8NQ3N.js} +1 -1
- package/dist/ui/assets/{store-BA5jRQLQ.js → store-C8pkV9xX.js} +1 -1
- package/dist/ui/assets/{store-BCOFBOmf.js → store-Ce8lHof4.js} +1 -1
- package/dist/ui/assets/{sudo-CZL3U0lj.js → sudo-Dz77pSRv.js} +1 -1
- package/dist/ui/assets/{supervisor-n5AQXVdz.js → supervisor-CODgsiun.js} +1 -1
- package/dist/ui/assets/{sync-dialog-CLv-AjS5.js → sync-dialog-DEd-6_ea.js} +1 -1
- package/dist/ui/assets/{transformers-env-DuP48CFD.js → transformers-env-DDxx-_yr.js} +1 -1
- package/dist/ui/assets/{tray-leader-oK24Tenu.js → tray-leader-PwhN5FVH.js} +1 -1
- package/dist/ui/assets/{tray-leave-runtime-BtmhGDJl.js → tray-leave-runtime-BLeKsvgA.js} +1 -1
- package/dist/ui/assets/{tray-runtime-config-CTm013-K.js → tray-runtime-config-CEuo4NwB.js} +1 -1
- package/dist/ui/assets/{tray-sidecar-x9PQcB2n.js → tray-sidecar-B5Rwvi0w.js} +1 -1
- package/dist/ui/assets/{turn-journal-CScxev4H.js → turn-journal-DgrDAXyz.js} +1 -1
- package/dist/ui/assets/{upgrade-detection-DS5evAII.js → upgrade-detection-DkrC9knp.js} +1 -1
- package/dist/ui/assets/{upskill-lick-skip-DsgHyVv5.js → upskill-lick-skip-x-HPkkoo.js} +1 -1
- package/dist/ui/assets/{voice-reply-ebSU1_qk.js → voice-reply-DN-og12Q.js} +1 -1
- package/dist/ui/assets/{wc-attach-525SvDTY.js → wc-attach-BxBMMvBD.js} +2 -2
- package/dist/ui/assets/{wc-browser-BWykEy-8.js → wc-browser-Bx_tyqby.js} +1 -1
- package/dist/ui/assets/{wc-computers-D3Avqz55.js → wc-computers--Hh_a1eS.js} +1 -1
- package/dist/ui/assets/{wc-detached-Cy1E6He4.js → wc-detached-Cfb7cdsS.js} +1 -1
- package/dist/ui/assets/{wc-extension-CVhWXV2w.js → wc-extension-DtmFrIBz.js} +2 -2
- package/dist/ui/assets/{wc-follower-C1kJ0lF_.js → wc-follower-CY8MJG2d.js} +3 -3
- package/dist/ui/assets/{wc-follower-oauth-qqfI5zJ5.js → wc-follower-oauth-Qp2Onk42.js} +1 -1
- package/dist/ui/assets/{wc-gelatiere-DFV5mBJW.js → wc-gelatiere-CIqpoRvp.js} +1 -1
- package/dist/ui/assets/{wc-live-Eu6ghZAo.js → wc-live-kIulpDGT.js} +5 -5
- package/dist/ui/assets/{wc-nav-BJ1Fg_hB.js → wc-nav-CKLAJB62.js} +2 -2
- package/dist/ui/assets/{wc-onboarding-D_k6jMGA.js → wc-onboarding-CCfbxIFk.js} +2 -2
- package/dist/ui/assets/{wc-permissions-CbwZeya-.js → wc-permissions-gkkaKIYQ.js} +2 -2
- package/dist/ui/assets/{wc-placeholder-DzHKpyEK.js → wc-placeholder-CPbGysCM.js} +3 -3
- package/dist/ui/assets/{wc-secret-request-bOcP6m9U.js → wc-secret-request-C-t_JIqx.js} +1 -1
- package/dist/ui/assets/{wc-settings-BNekAbpv.js → wc-settings-C3gOS2HO.js} +3 -3
- package/dist/ui/assets/{wc-shell-DdE40qZj.js → wc-shell-C5TUWPbD.js} +3 -3
- package/dist/ui/assets/{wc-shortcut-config-KdvTJp27.js → wc-shortcut-config-CxyrO44G.js} +1 -1
- package/dist/ui/assets/{wc-sprinkles-Bnnb88mU.js → wc-sprinkles-CdV_-XON.js} +2 -2
- package/dist/ui/assets/{wc-transcript-export-DWOEgP2-.js → wc-transcript-export-uviFziTO.js} +2 -2
- package/dist/ui/assets/{wc-tray-Dpx-EoMd.js → wc-tray-C_LlCq8n.js} +4 -4
- package/dist/ui/assets/welcome-detection-62JgQjpE.js +1 -0
- package/dist/ui/assets/{whisper-session-CB6rG-eD.js → whisper-session-DpmN2H-S.js} +2 -2
- package/dist/ui/assets/{xai-grok-CuIlQYpM.js → xai-grok-DqHHYruF.js} +1 -1
- package/dist/ui/assets/{xai-grok-BGPDFi9z.js → xai-grok-Qkm8D-bR.js} +1 -1
- package/dist/ui/index.html +3 -3
- package/dist/ui/packages/webapp/index.html +3 -3
- package/package.json +1 -1
- package/dist/ui/assets/SKILL-lcwLWMKp.js +0 -1
- package/dist/ui/assets/provider-store-access-BbvRUwZT.js +0 -1
- package/dist/ui/assets/provider-store-access-CrrW9eCi.js +0 -1
- package/dist/ui/assets/proxied-fetch-DXaTHROw.js +0 -1
- package/dist/ui/assets/run-Y1uUJvV7.js +0 -14
- package/dist/ui/assets/slicc-version-jRBuHQmT.js +0 -1
- package/dist/ui/assets/welcome-detection-BdEfH_d7.js +0 -1
|
@@ -21,6 +21,7 @@ export * from './loopback.js';
|
|
|
21
21
|
export * from './oauth-extra-domains-storage.js';
|
|
22
22
|
export * from './preview-url.js';
|
|
23
23
|
export * from './proxy-headers.js';
|
|
24
|
+
export * from './raw-fetch-protocol.js';
|
|
24
25
|
export * from './runtime-env.js';
|
|
25
26
|
export * from './secret-env-schema.js';
|
|
26
27
|
export * from './secret-masking.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAC5B,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,kCAAkC,CAAC;AACjD,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAC5B,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,kCAAkC,CAAC;AACjD,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC"}
|
|
@@ -22,6 +22,7 @@ export * from './loopback.js';
|
|
|
22
22
|
export * from './oauth-extra-domains-storage.js';
|
|
23
23
|
export * from './preview-url.js';
|
|
24
24
|
export * from './proxy-headers.js';
|
|
25
|
+
export * from './raw-fetch-protocol.js';
|
|
25
26
|
export * from './runtime-env.js';
|
|
26
27
|
export * from './secret-env-schema.js';
|
|
27
28
|
export * from './secret-masking.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iFAAiF;AAEjF,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAC5B,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,kCAAkC,CAAC;AACjD,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iFAAiF;AAEjF,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAC5B,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,kCAAkC,CAAC;AACjD,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Raw-mode fetch-proxy contract (#3571). The default proxied fetch behaves like
|
|
3
|
+
* a browser (follows redirects, folds Set-Cookie into an out-of-band header,
|
|
4
|
+
* buffers bodies). Raw mode behaves like an HTTP client, so the wasm realm's
|
|
5
|
+
* HTTP proxy can hand each response to curl or git as the origin sent it:
|
|
6
|
+
*
|
|
7
|
+
* - redirects are NOT followed; the 3xx, `Location` and `Set-Cookie` reach
|
|
8
|
+
* the caller;
|
|
9
|
+
* - headers travel as an ordered name/value list, so every `Set-Cookie`
|
|
10
|
+
* stays a separate entry;
|
|
11
|
+
* - the body is always delivered DECODED: `Content-Encoding` is removed
|
|
12
|
+
* whenever a coding was undone, and `Content-Length` survives only when
|
|
13
|
+
* it still counts the delivered bytes (see {@link rawResponseHeaders});
|
|
14
|
+
* - the body streams, and nothing is read from the float's hop until the
|
|
15
|
+
* caller asks. Chrome's own `fetch` still reads a response off the
|
|
16
|
+
* network ahead of the reader (measured on Chrome 146: 400 MiB drained
|
|
17
|
+
* while a page held one chunk), so the upstream itself is not throttled.
|
|
18
|
+
*
|
|
19
|
+
* Every float speaks this contract; each one frames it for its own hop. The
|
|
20
|
+
* CLI/cloud node-server route reads the request head from
|
|
21
|
+
* {@link RAW_FETCH_REQUEST_HEADER} and answers `200` with
|
|
22
|
+
* {@link RAW_FETCH_CONTENT_TYPE}, whose body is one response-head frame
|
|
23
|
+
* ({@link encodeRawResponseFrame}) followed by the upstream body bytes.
|
|
24
|
+
*/
|
|
25
|
+
/** Ordered header list. Names keep their case; repeats stay separate. */
|
|
26
|
+
export type RawHeaderList = Array<[string, string]>;
|
|
27
|
+
/** What the caller wants sent upstream. */
|
|
28
|
+
export interface RawFetchRequestHead {
|
|
29
|
+
url: string;
|
|
30
|
+
method: string;
|
|
31
|
+
headers: RawHeaderList;
|
|
32
|
+
}
|
|
33
|
+
/** What the upstream answered, before the body. */
|
|
34
|
+
export interface RawFetchResponseHead {
|
|
35
|
+
status: number;
|
|
36
|
+
statusText: string;
|
|
37
|
+
headers: RawHeaderList;
|
|
38
|
+
/** The URL that answered; with manual redirects always the request URL. */
|
|
39
|
+
url: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Request header carrying the JSON {@link RawFetchRequestHead} on the
|
|
43
|
+
* node-server hop. The hop itself is always `POST` so neither the method nor
|
|
44
|
+
* the caller's headers are subject to the browser's forbidden-name filter.
|
|
45
|
+
* Its presence (instead of `X-Target-URL`) is what selects raw mode, so a
|
|
46
|
+
* bridge that predates raw mode answers 400 rather than sending the request
|
|
47
|
+
* the default way.
|
|
48
|
+
*/
|
|
49
|
+
export declare const RAW_FETCH_REQUEST_HEADER = "X-Slicc-Raw-Request";
|
|
50
|
+
/**
|
|
51
|
+
* Capability probe on the node-server hop: a `POST /api/fetch-proxy` carrying
|
|
52
|
+
* only this header (no `X-Target-URL`, no request head). A bridge with raw
|
|
53
|
+
* mode answers `200` JSON {@link RawFetchProbeReply}; one without it answers
|
|
54
|
+
* 400 (node-server before raw mode, swift-server) or 404 (no bridge at all),
|
|
55
|
+
* and nothing is fetched upstream either way.
|
|
56
|
+
*/
|
|
57
|
+
export declare const RAW_FETCH_PROBE_HEADER = "X-Slicc-Raw-Probe";
|
|
58
|
+
/** Raw-mode protocol revision a bridge reports in its probe reply. */
|
|
59
|
+
export declare const RAW_FETCH_PROTOCOL_VERSION = 1;
|
|
60
|
+
/** What a raw-capable bridge reports about itself. */
|
|
61
|
+
export interface RawFetchProbeReply {
|
|
62
|
+
rawFetch: number;
|
|
63
|
+
requestBodyStreaming: boolean;
|
|
64
|
+
maxRequestBodyBytes: number;
|
|
65
|
+
}
|
|
66
|
+
/** Validate a probe reply; `null` when it is not one. */
|
|
67
|
+
export declare function parseRawFetchProbeReply(value: unknown): RawFetchProbeReply | null;
|
|
68
|
+
/** Content type of a raw-mode answer on the node-server hop. */
|
|
69
|
+
export declare const RAW_FETCH_CONTENT_TYPE = "application/vnd.slicc.raw-fetch";
|
|
70
|
+
/**
|
|
71
|
+
* Request-body ceiling on the node-server hop (CLI and cloud). This hop
|
|
72
|
+
* buffers the upload on both ends for now; past this size the bridge answers
|
|
73
|
+
* 413 and the webapp refuses before sending.
|
|
74
|
+
*/
|
|
75
|
+
export declare const RAW_FETCH_BRIDGE_REQUEST_BODY_CAP: number;
|
|
76
|
+
/** Upper bound on one encoded response-head frame. */
|
|
77
|
+
export declare const RAW_FETCH_MAX_HEAD_BYTES: number;
|
|
78
|
+
/** `Accept-Encoding` a float sends upstream: exactly the codings it decodes. */
|
|
79
|
+
export declare const RAW_FETCH_ACCEPT_ENCODING = "gzip, deflate, br";
|
|
80
|
+
/**
|
|
81
|
+
* The `Accept-Encoding` a float sets for a request with these (folded,
|
|
82
|
+
* lowercase) headers, or `undefined` to set none. A ranged request (`Range`,
|
|
83
|
+
* `If-Range`) must not offer a compressed coding: a 206 over a compressed
|
|
84
|
+
* representation carries `Content-Range` offsets into the compressed bytes,
|
|
85
|
+
* which no longer describe the body once the float decodes it, so a resumed
|
|
86
|
+
* or ranged download would assemble corrupt data. With no `Accept-Encoding`
|
|
87
|
+
* set, `fetch` itself sends `identity` for a request carrying `Range` (Fetch
|
|
88
|
+
* standard, HTTP-network-or-cache fetch), in Node and in Chrome alike.
|
|
89
|
+
*/
|
|
90
|
+
export declare function rawAcceptEncoding(headers: Record<string, string>): string | undefined;
|
|
91
|
+
/**
|
|
92
|
+
* Whether a partial response came back with a coding the float undid
|
|
93
|
+
* (an origin that ignored `Accept-Encoding: identity`). Its `Content-Range`
|
|
94
|
+
* counts encoded bytes the caller never sees, so the float must refuse it
|
|
95
|
+
* rather than deliver it.
|
|
96
|
+
*/
|
|
97
|
+
export declare function isDecodedPartialResponse(input: {
|
|
98
|
+
status: number;
|
|
99
|
+
headers: RawHeaderList;
|
|
100
|
+
}): boolean;
|
|
101
|
+
/** Drop hop-by-hop and float-owned request headers, keeping order. */
|
|
102
|
+
export declare function stripRawRequestHeaders(headers: RawHeaderList): RawHeaderList;
|
|
103
|
+
/**
|
|
104
|
+
* Fold a raw list into the name → value record `fetch` sends. Repeats join
|
|
105
|
+
* with `, ` (RFC 9110 §5.3), except `Cookie`, which joins with `; `. No float
|
|
106
|
+
* can put two lines with one name on the wire: `fetch` folds them the same way.
|
|
107
|
+
*/
|
|
108
|
+
export declare function foldRawRequestHeaders(headers: RawHeaderList): Record<string, string>;
|
|
109
|
+
export interface RawResponseHeaderInput {
|
|
110
|
+
method: string;
|
|
111
|
+
status: number;
|
|
112
|
+
headers: RawHeaderList;
|
|
113
|
+
/**
|
|
114
|
+
* The float may rewrite the body (secret scrub, gunzip sniff), so the
|
|
115
|
+
* upstream `Content-Length` would no longer count the delivered bytes.
|
|
116
|
+
*/
|
|
117
|
+
bodyRewritten: boolean;
|
|
118
|
+
}
|
|
119
|
+
/** Whether a response to `method` with `status` carries a body at all. */
|
|
120
|
+
export declare function rawResponseHasBody(method: string, status: number): boolean;
|
|
121
|
+
/**
|
|
122
|
+
* The head a raw caller sees. Hop-by-hop headers go, and so do the fields
|
|
123
|
+
* the response's `Connection` header names (RFC 9110 §7.6.1). A bodiless response
|
|
124
|
+
* (HEAD, 1xx/204/205/304) keeps `Content-Encoding` and `Content-Length` as
|
|
125
|
+
* sent, since they describe the representation, not bytes on this hop.
|
|
126
|
+
* Otherwise a decoded coding drops both headers, and `Content-Length` also
|
|
127
|
+
* goes when the float rewrote the body. An unknown coding stays with its
|
|
128
|
+
* encoded bytes.
|
|
129
|
+
*/
|
|
130
|
+
export declare function rawResponseHeaders(input: RawResponseHeaderInput): RawHeaderList;
|
|
131
|
+
/**
|
|
132
|
+
* JSON for {@link RAW_FETCH_REQUEST_HEADER}. Non-ASCII is `\u`-escaped so the
|
|
133
|
+
* value is a valid header ByteString whatever the caller's headers hold.
|
|
134
|
+
*/
|
|
135
|
+
export declare function encodeRawRequestHead(head: RawFetchRequestHead): string;
|
|
136
|
+
/** Parse a {@link RAW_FETCH_REQUEST_HEADER} value; `null` when malformed. */
|
|
137
|
+
export declare function decodeRawRequestHead(value: string): RawFetchRequestHead | null;
|
|
138
|
+
/** One response-head frame: a big-endian u32 length, then UTF-8 JSON. */
|
|
139
|
+
export declare function encodeRawResponseFrame(head: RawFetchResponseHead): Uint8Array;
|
|
140
|
+
/**
|
|
141
|
+
* Split a response-head frame off the front of `buffer`. Returns `null` while
|
|
142
|
+
* the frame is still incomplete, and throws when it is malformed or larger
|
|
143
|
+
* than {@link RAW_FETCH_MAX_HEAD_BYTES}.
|
|
144
|
+
*/
|
|
145
|
+
export declare function decodeRawResponseFrame(buffer: Uint8Array): {
|
|
146
|
+
head: RawFetchResponseHead;
|
|
147
|
+
rest: Uint8Array;
|
|
148
|
+
} | null;
|
|
149
|
+
//# sourceMappingURL=raw-fetch-protocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"raw-fetch-protocol.d.ts","sourceRoot":"","sources":["../src/raw-fetch-protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,yEAAyE;AACzE,MAAM,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAEpD,2CAA2C;AAC3C,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,aAAa,CAAC;CACxB;AAED,mDAAmD;AACnD,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,aAAa,CAAC;IACvB,2EAA2E;IAC3E,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB,wBAAwB,CAAC;AAE9D;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,sBAAsB,CAAC;AAE1D,sEAAsE;AACtE,eAAO,MAAM,0BAA0B,IAAI,CAAC;AAE5C,sDAAsD;AACtD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,yDAAyD;AACzD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,kBAAkB,GAAG,IAAI,CAWjF;AAED,gEAAgE;AAChE,eAAO,MAAM,sBAAsB,oCAAoC,CAAC;AAExE;;;;GAIG;AACH,eAAO,MAAM,iCAAiC,QAAoB,CAAC;AAEnE,sDAAsD;AACtD,eAAO,MAAM,wBAAwB,QAAc,CAAC;AAoCpD,gFAAgF;AAChF,eAAO,MAAM,yBAAyB,sBAAsB,CAAC;AAE7D;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,GAAG,SAAS,CAIrF;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,aAAa,CAAC;CACxB,GAAG,OAAO,CAOV;AA2BD,sEAAsE;AACtE,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,aAAa,GAAG,aAAa,CAM5E;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CASpF;AAWD,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,aAAa,CAAC;IACvB;;;OAGG;IACH,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,0EAA0E;AAC1E,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAE1E;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,sBAAsB,GAAG,aAAa,CAoB/E;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,mBAAmB,GAAG,MAAM,CAKtE;AAED,6EAA6E;AAC7E,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI,CAkB9E;AAED,yEAAyE;AACzE,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,oBAAoB,GAAG,UAAU,CAM7E;AAcD;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,UAAU,GACjB;IAAE,IAAI,EAAE,oBAAoB,CAAC;IAAC,IAAI,EAAE,UAAU,CAAA;CAAE,GAAG,IAAI,CAezD"}
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Raw-mode fetch-proxy contract (#3571). The default proxied fetch behaves like
|
|
3
|
+
* a browser (follows redirects, folds Set-Cookie into an out-of-band header,
|
|
4
|
+
* buffers bodies). Raw mode behaves like an HTTP client, so the wasm realm's
|
|
5
|
+
* HTTP proxy can hand each response to curl or git as the origin sent it:
|
|
6
|
+
*
|
|
7
|
+
* - redirects are NOT followed; the 3xx, `Location` and `Set-Cookie` reach
|
|
8
|
+
* the caller;
|
|
9
|
+
* - headers travel as an ordered name/value list, so every `Set-Cookie`
|
|
10
|
+
* stays a separate entry;
|
|
11
|
+
* - the body is always delivered DECODED: `Content-Encoding` is removed
|
|
12
|
+
* whenever a coding was undone, and `Content-Length` survives only when
|
|
13
|
+
* it still counts the delivered bytes (see {@link rawResponseHeaders});
|
|
14
|
+
* - the body streams, and nothing is read from the float's hop until the
|
|
15
|
+
* caller asks. Chrome's own `fetch` still reads a response off the
|
|
16
|
+
* network ahead of the reader (measured on Chrome 146: 400 MiB drained
|
|
17
|
+
* while a page held one chunk), so the upstream itself is not throttled.
|
|
18
|
+
*
|
|
19
|
+
* Every float speaks this contract; each one frames it for its own hop. The
|
|
20
|
+
* CLI/cloud node-server route reads the request head from
|
|
21
|
+
* {@link RAW_FETCH_REQUEST_HEADER} and answers `200` with
|
|
22
|
+
* {@link RAW_FETCH_CONTENT_TYPE}, whose body is one response-head frame
|
|
23
|
+
* ({@link encodeRawResponseFrame}) followed by the upstream body bytes.
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* Request header carrying the JSON {@link RawFetchRequestHead} on the
|
|
27
|
+
* node-server hop. The hop itself is always `POST` so neither the method nor
|
|
28
|
+
* the caller's headers are subject to the browser's forbidden-name filter.
|
|
29
|
+
* Its presence (instead of `X-Target-URL`) is what selects raw mode, so a
|
|
30
|
+
* bridge that predates raw mode answers 400 rather than sending the request
|
|
31
|
+
* the default way.
|
|
32
|
+
*/
|
|
33
|
+
export const RAW_FETCH_REQUEST_HEADER = 'X-Slicc-Raw-Request';
|
|
34
|
+
/**
|
|
35
|
+
* Capability probe on the node-server hop: a `POST /api/fetch-proxy` carrying
|
|
36
|
+
* only this header (no `X-Target-URL`, no request head). A bridge with raw
|
|
37
|
+
* mode answers `200` JSON {@link RawFetchProbeReply}; one without it answers
|
|
38
|
+
* 400 (node-server before raw mode, swift-server) or 404 (no bridge at all),
|
|
39
|
+
* and nothing is fetched upstream either way.
|
|
40
|
+
*/
|
|
41
|
+
export const RAW_FETCH_PROBE_HEADER = 'X-Slicc-Raw-Probe';
|
|
42
|
+
/** Raw-mode protocol revision a bridge reports in its probe reply. */
|
|
43
|
+
export const RAW_FETCH_PROTOCOL_VERSION = 1;
|
|
44
|
+
/** Validate a probe reply; `null` when it is not one. */
|
|
45
|
+
export function parseRawFetchProbeReply(value) {
|
|
46
|
+
if (!value || typeof value !== 'object')
|
|
47
|
+
return null;
|
|
48
|
+
const reply = value;
|
|
49
|
+
if (typeof reply.rawFetch !== 'number' || reply.rawFetch < 1)
|
|
50
|
+
return null;
|
|
51
|
+
if (typeof reply.requestBodyStreaming !== 'boolean')
|
|
52
|
+
return null;
|
|
53
|
+
if (typeof reply.maxRequestBodyBytes !== 'number')
|
|
54
|
+
return null;
|
|
55
|
+
return {
|
|
56
|
+
rawFetch: reply.rawFetch,
|
|
57
|
+
requestBodyStreaming: reply.requestBodyStreaming,
|
|
58
|
+
maxRequestBodyBytes: reply.maxRequestBodyBytes,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/** Content type of a raw-mode answer on the node-server hop. */
|
|
62
|
+
export const RAW_FETCH_CONTENT_TYPE = 'application/vnd.slicc.raw-fetch';
|
|
63
|
+
/**
|
|
64
|
+
* Request-body ceiling on the node-server hop (CLI and cloud). This hop
|
|
65
|
+
* buffers the upload on both ends for now; past this size the bridge answers
|
|
66
|
+
* 413 and the webapp refuses before sending.
|
|
67
|
+
*/
|
|
68
|
+
export const RAW_FETCH_BRIDGE_REQUEST_BODY_CAP = 256 * 1024 * 1024;
|
|
69
|
+
/** Upper bound on one encoded response-head frame. */
|
|
70
|
+
export const RAW_FETCH_MAX_HEAD_BYTES = 1024 * 1024;
|
|
71
|
+
/**
|
|
72
|
+
* Hop-by-hop request headers (RFC 9110 §7.6.1) plus the ones the forwarding
|
|
73
|
+
* fetch owns: `host` and `content-length` are derived from the URL and body,
|
|
74
|
+
* `accept-encoding` is chosen by the float so it can decode what it asked for,
|
|
75
|
+
* and `expect` is answered by the realm proxy, not the origin.
|
|
76
|
+
*/
|
|
77
|
+
const RAW_REQUEST_SKIP_HEADERS = new Set([
|
|
78
|
+
'connection',
|
|
79
|
+
'keep-alive',
|
|
80
|
+
'proxy-connection',
|
|
81
|
+
'te',
|
|
82
|
+
'trailer',
|
|
83
|
+
'transfer-encoding',
|
|
84
|
+
'upgrade',
|
|
85
|
+
'host',
|
|
86
|
+
'content-length',
|
|
87
|
+
'accept-encoding',
|
|
88
|
+
'expect',
|
|
89
|
+
]);
|
|
90
|
+
/** Hop-by-hop response headers; never part of the delivered head. */
|
|
91
|
+
const RAW_RESPONSE_SKIP_HEADERS = new Set([
|
|
92
|
+
'connection',
|
|
93
|
+
'keep-alive',
|
|
94
|
+
'proxy-connection',
|
|
95
|
+
'te',
|
|
96
|
+
'trailer',
|
|
97
|
+
'transfer-encoding',
|
|
98
|
+
'upgrade',
|
|
99
|
+
]);
|
|
100
|
+
/** Content codings every float's fetch decodes on its own. */
|
|
101
|
+
const DECODED_CODINGS = new Set(['gzip', 'x-gzip', 'deflate', 'br']);
|
|
102
|
+
/** `Accept-Encoding` a float sends upstream: exactly the codings it decodes. */
|
|
103
|
+
export const RAW_FETCH_ACCEPT_ENCODING = 'gzip, deflate, br';
|
|
104
|
+
/**
|
|
105
|
+
* The `Accept-Encoding` a float sets for a request with these (folded,
|
|
106
|
+
* lowercase) headers, or `undefined` to set none. A ranged request (`Range`,
|
|
107
|
+
* `If-Range`) must not offer a compressed coding: a 206 over a compressed
|
|
108
|
+
* representation carries `Content-Range` offsets into the compressed bytes,
|
|
109
|
+
* which no longer describe the body once the float decodes it, so a resumed
|
|
110
|
+
* or ranged download would assemble corrupt data. With no `Accept-Encoding`
|
|
111
|
+
* set, `fetch` itself sends `identity` for a request carrying `Range` (Fetch
|
|
112
|
+
* standard, HTTP-network-or-cache fetch), in Node and in Chrome alike.
|
|
113
|
+
*/
|
|
114
|
+
export function rawAcceptEncoding(headers) {
|
|
115
|
+
return headers.range !== undefined || headers['if-range'] !== undefined
|
|
116
|
+
? undefined
|
|
117
|
+
: RAW_FETCH_ACCEPT_ENCODING;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Whether a partial response came back with a coding the float undid
|
|
121
|
+
* (an origin that ignored `Accept-Encoding: identity`). Its `Content-Range`
|
|
122
|
+
* counts encoded bytes the caller never sees, so the float must refuse it
|
|
123
|
+
* rather than deliver it.
|
|
124
|
+
*/
|
|
125
|
+
export function isDecodedPartialResponse(input) {
|
|
126
|
+
if (input.status !== 206)
|
|
127
|
+
return false;
|
|
128
|
+
const encoding = input.headers
|
|
129
|
+
.filter(([name]) => name.toLowerCase() === 'content-encoding')
|
|
130
|
+
.map(([, value]) => value)
|
|
131
|
+
.join(',');
|
|
132
|
+
return codingsWereDecoded(encoding);
|
|
133
|
+
}
|
|
134
|
+
/** Statuses whose responses never carry a body. */
|
|
135
|
+
const NULL_BODY_STATUSES = new Set([101, 103, 204, 205, 304]);
|
|
136
|
+
function isHeaderPair(value) {
|
|
137
|
+
return (Array.isArray(value) &&
|
|
138
|
+
value.length === 2 &&
|
|
139
|
+
typeof value[0] === 'string' &&
|
|
140
|
+
typeof value[1] === 'string');
|
|
141
|
+
}
|
|
142
|
+
/** Tokens a `Connection` header names, lowercased. */
|
|
143
|
+
function connectionTokens(headers) {
|
|
144
|
+
const tokens = new Set();
|
|
145
|
+
for (const [name, value] of headers) {
|
|
146
|
+
if (name.toLowerCase() !== 'connection')
|
|
147
|
+
continue;
|
|
148
|
+
for (const token of value.split(',')) {
|
|
149
|
+
const trimmed = token.trim().toLowerCase();
|
|
150
|
+
if (trimmed)
|
|
151
|
+
tokens.add(trimmed);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return tokens;
|
|
155
|
+
}
|
|
156
|
+
/** Drop hop-by-hop and float-owned request headers, keeping order. */
|
|
157
|
+
export function stripRawRequestHeaders(headers) {
|
|
158
|
+
const named = connectionTokens(headers);
|
|
159
|
+
return headers.filter(([name]) => {
|
|
160
|
+
const lower = name.toLowerCase();
|
|
161
|
+
return !RAW_REQUEST_SKIP_HEADERS.has(lower) && !named.has(lower);
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Fold a raw list into the name → value record `fetch` sends. Repeats join
|
|
166
|
+
* with `, ` (RFC 9110 §5.3), except `Cookie`, which joins with `; `. No float
|
|
167
|
+
* can put two lines with one name on the wire: `fetch` folds them the same way.
|
|
168
|
+
*/
|
|
169
|
+
export function foldRawRequestHeaders(headers) {
|
|
170
|
+
const out = {};
|
|
171
|
+
for (const [name, value] of headers) {
|
|
172
|
+
const lower = name.toLowerCase();
|
|
173
|
+
const prior = out[lower];
|
|
174
|
+
if (prior === undefined)
|
|
175
|
+
out[lower] = value;
|
|
176
|
+
else
|
|
177
|
+
out[lower] = `${prior}${lower === 'cookie' ? '; ' : ', '}${value}`;
|
|
178
|
+
}
|
|
179
|
+
return out;
|
|
180
|
+
}
|
|
181
|
+
/** True when every listed coding is one the float's fetch undid. */
|
|
182
|
+
function codingsWereDecoded(contentEncoding) {
|
|
183
|
+
const codings = contentEncoding
|
|
184
|
+
.split(',')
|
|
185
|
+
.map((c) => c.trim().toLowerCase())
|
|
186
|
+
.filter((c) => c !== '' && c !== 'identity');
|
|
187
|
+
return codings.length > 0 && codings.every((c) => DECODED_CODINGS.has(c));
|
|
188
|
+
}
|
|
189
|
+
/** Whether a response to `method` with `status` carries a body at all. */
|
|
190
|
+
export function rawResponseHasBody(method, status) {
|
|
191
|
+
return method.toUpperCase() !== 'HEAD' && !NULL_BODY_STATUSES.has(status);
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* The head a raw caller sees. Hop-by-hop headers go, and so do the fields
|
|
195
|
+
* the response's `Connection` header names (RFC 9110 §7.6.1). A bodiless response
|
|
196
|
+
* (HEAD, 1xx/204/205/304) keeps `Content-Encoding` and `Content-Length` as
|
|
197
|
+
* sent, since they describe the representation, not bytes on this hop.
|
|
198
|
+
* Otherwise a decoded coding drops both headers, and `Content-Length` also
|
|
199
|
+
* goes when the float rewrote the body. An unknown coding stays with its
|
|
200
|
+
* encoded bytes.
|
|
201
|
+
*/
|
|
202
|
+
export function rawResponseHeaders(input) {
|
|
203
|
+
const named = connectionTokens(input.headers);
|
|
204
|
+
const withoutHop = input.headers.filter(([name]) => {
|
|
205
|
+
const lower = name.toLowerCase();
|
|
206
|
+
return !RAW_RESPONSE_SKIP_HEADERS.has(lower) && !named.has(lower);
|
|
207
|
+
});
|
|
208
|
+
if (!rawResponseHasBody(input.method, input.status))
|
|
209
|
+
return withoutHop;
|
|
210
|
+
const encoding = withoutHop
|
|
211
|
+
.filter(([name]) => name.toLowerCase() === 'content-encoding')
|
|
212
|
+
.map(([, value]) => value)
|
|
213
|
+
.join(',');
|
|
214
|
+
const decoded = codingsWereDecoded(encoding);
|
|
215
|
+
const dropLength = decoded || input.bodyRewritten;
|
|
216
|
+
return withoutHop.filter(([name]) => {
|
|
217
|
+
const lower = name.toLowerCase();
|
|
218
|
+
if (lower === 'content-length')
|
|
219
|
+
return !dropLength;
|
|
220
|
+
if (lower === 'content-encoding')
|
|
221
|
+
return !decoded && encoding.trim().toLowerCase() !== 'identity';
|
|
222
|
+
return true;
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* JSON for {@link RAW_FETCH_REQUEST_HEADER}. Non-ASCII is `\u`-escaped so the
|
|
227
|
+
* value is a valid header ByteString whatever the caller's headers hold.
|
|
228
|
+
*/
|
|
229
|
+
export function encodeRawRequestHead(head) {
|
|
230
|
+
return JSON.stringify(head).replace(/[\u007f-]/g, (c) => `\\u${c.charCodeAt(0).toString(16).padStart(4, '0')}`);
|
|
231
|
+
}
|
|
232
|
+
/** Parse a {@link RAW_FETCH_REQUEST_HEADER} value; `null` when malformed. */
|
|
233
|
+
export function decodeRawRequestHead(value) {
|
|
234
|
+
let parsed;
|
|
235
|
+
try {
|
|
236
|
+
parsed = JSON.parse(value);
|
|
237
|
+
}
|
|
238
|
+
catch {
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
241
|
+
if (!parsed || typeof parsed !== 'object')
|
|
242
|
+
return null;
|
|
243
|
+
const { url, method, headers } = parsed;
|
|
244
|
+
if (typeof url !== 'string' ||
|
|
245
|
+
typeof method !== 'string' ||
|
|
246
|
+
!/^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/.test(method)) {
|
|
247
|
+
return null;
|
|
248
|
+
}
|
|
249
|
+
if (!Array.isArray(headers) || !headers.every(isHeaderPair))
|
|
250
|
+
return null;
|
|
251
|
+
return { url, method, headers };
|
|
252
|
+
}
|
|
253
|
+
/** One response-head frame: a big-endian u32 length, then UTF-8 JSON. */
|
|
254
|
+
export function encodeRawResponseFrame(head) {
|
|
255
|
+
const json = new TextEncoder().encode(JSON.stringify(head));
|
|
256
|
+
const frame = new Uint8Array(4 + json.byteLength);
|
|
257
|
+
new DataView(frame.buffer).setUint32(0, json.byteLength);
|
|
258
|
+
frame.set(json, 4);
|
|
259
|
+
return frame;
|
|
260
|
+
}
|
|
261
|
+
function isRawResponseHead(value) {
|
|
262
|
+
if (!value || typeof value !== 'object')
|
|
263
|
+
return false;
|
|
264
|
+
const head = value;
|
|
265
|
+
return (typeof head.status === 'number' &&
|
|
266
|
+
typeof head.statusText === 'string' &&
|
|
267
|
+
typeof head.url === 'string' &&
|
|
268
|
+
Array.isArray(head.headers) &&
|
|
269
|
+
head.headers.every(isHeaderPair));
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Split a response-head frame off the front of `buffer`. Returns `null` while
|
|
273
|
+
* the frame is still incomplete, and throws when it is malformed or larger
|
|
274
|
+
* than {@link RAW_FETCH_MAX_HEAD_BYTES}.
|
|
275
|
+
*/
|
|
276
|
+
export function decodeRawResponseFrame(buffer) {
|
|
277
|
+
if (buffer.byteLength < 4)
|
|
278
|
+
return null;
|
|
279
|
+
const length = new DataView(buffer.buffer, buffer.byteOffset, 4).getUint32(0);
|
|
280
|
+
if (length > RAW_FETCH_MAX_HEAD_BYTES) {
|
|
281
|
+
throw new Error(`raw fetch: response head of ${length} bytes exceeds the limit`);
|
|
282
|
+
}
|
|
283
|
+
if (buffer.byteLength < 4 + length)
|
|
284
|
+
return null;
|
|
285
|
+
let head;
|
|
286
|
+
try {
|
|
287
|
+
head = JSON.parse(new TextDecoder().decode(buffer.subarray(4, 4 + length)));
|
|
288
|
+
}
|
|
289
|
+
catch {
|
|
290
|
+
throw new Error('raw fetch: malformed response head');
|
|
291
|
+
}
|
|
292
|
+
if (!isRawResponseHead(head))
|
|
293
|
+
throw new Error('raw fetch: malformed response head');
|
|
294
|
+
return { head, rest: buffer.subarray(4 + length) };
|
|
295
|
+
}
|
|
296
|
+
//# sourceMappingURL=raw-fetch-protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"raw-fetch-protocol.js","sourceRoot":"","sources":["../src/raw-fetch-protocol.ts"],"names":[],"mappings":"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"}
|
|
@@ -68,11 +68,13 @@ export declare const FETCH_PROXY_BASE_EXPOSE_HEADERS: readonly string[];
|
|
|
68
68
|
*/
|
|
69
69
|
export declare function buildFetchProxyExposeHeaders(forwardedHeaderNames: Iterable<string>): string;
|
|
70
70
|
/**
|
|
71
|
-
* Which requests the global `express.json()` consumes.
|
|
71
|
+
* Which requests the global `express.json()` consumes. Three exclusions:
|
|
72
72
|
*
|
|
73
73
|
* - `X-Slicc-Raw-Body: 1` — SigV4-signed bodies must reach the
|
|
74
74
|
* /api/fetch-proxy handler byte-for-byte (the parser would re-serialize
|
|
75
75
|
* them via JSON.stringify and break the signature);
|
|
76
|
+
* - `X-Slicc-Raw-Request` — raw-mode fetch-proxy uploads, read as a
|
|
77
|
+
* bounded byte stream by `routes/fetch-proxy-raw.ts`;
|
|
76
78
|
* - the stable hostfs dispatcher — it owns a bounded 1 MiB parser and an
|
|
77
79
|
* errno error adapter, and this parser is mounted ahead of
|
|
78
80
|
* `registerHostFsRoutes`, so without the exclusion it would consume the
|
|
@@ -121,11 +121,13 @@ export function buildFetchProxyExposeHeaders(forwardedHeaderNames) {
|
|
|
121
121
|
return out.join(', ');
|
|
122
122
|
}
|
|
123
123
|
/**
|
|
124
|
-
* Which requests the global `express.json()` consumes.
|
|
124
|
+
* Which requests the global `express.json()` consumes. Three exclusions:
|
|
125
125
|
*
|
|
126
126
|
* - `X-Slicc-Raw-Body: 1` — SigV4-signed bodies must reach the
|
|
127
127
|
* /api/fetch-proxy handler byte-for-byte (the parser would re-serialize
|
|
128
128
|
* them via JSON.stringify and break the signature);
|
|
129
|
+
* - `X-Slicc-Raw-Request` — raw-mode fetch-proxy uploads, read as a
|
|
130
|
+
* bounded byte stream by `routes/fetch-proxy-raw.ts`;
|
|
129
131
|
* - the stable hostfs dispatcher — it owns a bounded 1 MiB parser and an
|
|
130
132
|
* errno error adapter, and this parser is mounted ahead of
|
|
131
133
|
* `registerHostFsRoutes`, so without the exclusion it would consume the
|
|
@@ -134,6 +136,8 @@ export function buildFetchProxyExposeHeaders(forwardedHeaderNames) {
|
|
|
134
136
|
export function shouldParseGlobalJson(req) {
|
|
135
137
|
if (req.headers['x-slicc-raw-body'] === '1')
|
|
136
138
|
return false;
|
|
139
|
+
if (req.headers['x-slicc-raw-request'] !== undefined)
|
|
140
|
+
return false;
|
|
137
141
|
if (isHostFsStableBodyRequest(req))
|
|
138
142
|
return false;
|
|
139
143
|
return (req.headers['content-type'] ?? '').includes('application/json');
|
|
@@ -42,7 +42,9 @@ import { runInstallCli } from './install-cli.js';
|
|
|
42
42
|
import { resolveCliBrowserLaunchUrl } from './launch-url.js';
|
|
43
43
|
import { createHttpCdp, registerLeaderRestartEndpoint } from './leader-restart.js';
|
|
44
44
|
import { buildLocalApiDescriptor, sliccLinksMiddleware } from './links-middleware.js';
|
|
45
|
+
import { AgentActivityTracker } from './routes/agent-activity.js';
|
|
45
46
|
import { registerFetchProxyRoute } from './routes/fetch-proxy.js';
|
|
47
|
+
import { registerRawFetchProxyRoute } from './routes/fetch-proxy-raw.js';
|
|
46
48
|
import { registerHandoffRoute } from './routes/handoff.js';
|
|
47
49
|
import { registerLickApiRoutes } from './routes/lick-api.js';
|
|
48
50
|
import { createLickBridge } from './routes/lick-bridge.js';
|
|
@@ -1194,6 +1196,17 @@ function createCdpWebSocketServer(bridgeToken) {
|
|
|
1194
1196
|
},
|
|
1195
1197
|
});
|
|
1196
1198
|
}
|
|
1199
|
+
/**
|
|
1200
|
+
* Fetch proxy — forwards cross-origin requests from the browser to bypass CORS,
|
|
1201
|
+
* injecting/unmasking secrets and streaming the response with a UTF-8-safe
|
|
1202
|
+
* scrub. Raw mode (#3571) is mounted first and falls through for default
|
|
1203
|
+
* requests; both share one agent-activity window.
|
|
1204
|
+
*/
|
|
1205
|
+
function mountFetchProxy(app, secretProxy) {
|
|
1206
|
+
const activityTracker = new AgentActivityTracker();
|
|
1207
|
+
registerRawFetchProxyRoute(app, { secretProxy, activityTracker });
|
|
1208
|
+
registerFetchProxyRoute(app, { secretProxy, activityTracker });
|
|
1209
|
+
}
|
|
1197
1210
|
async function main() {
|
|
1198
1211
|
// Resolve ports first; `launchBrowser` is deferred until AFTER
|
|
1199
1212
|
// `server.listen()` so the /cdp bridge is accepting connections before
|
|
@@ -1297,9 +1310,7 @@ async function main() {
|
|
|
1297
1310
|
const computerDemo = RUNTIME_FLAGS.computerDemo ? new ComputerDemoState() : null;
|
|
1298
1311
|
if (computerDemo)
|
|
1299
1312
|
registerComputerDemoRoutes(app, computerDemo);
|
|
1300
|
-
|
|
1301
|
-
// injecting/unmasking secrets and streaming the response with a UTF-8-safe scrub.
|
|
1302
|
-
registerFetchProxyRoute(app, { secretProxy });
|
|
1313
|
+
mountFetchProxy(app, secretProxy);
|
|
1303
1314
|
// node-server serves no UI in any mode: it is a pure /cdp bridge + /api
|
|
1304
1315
|
// surface. Chrome opens the sliccy.ai-hosted leader which talks to /cdp +
|
|
1305
1316
|
// /api cross-origin. Create the HTTP server so we can attach the /cdp WS
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Raw mode of `/api/fetch-proxy` (#3571): the HTTP-client flavor the wasm
|
|
3
|
+
* realm's proxy forwards curl and git through. The wire contract lives in
|
|
4
|
+
* `@slicc/shared-ts` `raw-fetch-protocol.ts`; this module is the CLI/cloud
|
|
5
|
+
* float's side of it. Differences from the default route:
|
|
6
|
+
*
|
|
7
|
+
* - the request head (URL, method, ordered headers) arrives as JSON in
|
|
8
|
+
* `X-Slicc-Raw-Request`, so the browser's forbidden-header filter and the
|
|
9
|
+
* page's own headers (User-Agent, Sec-Fetch-*) never reach upstream;
|
|
10
|
+
* - redirects are manual: the 3xx, `Location` and every `Set-Cookie` go
|
|
11
|
+
* back to the caller in an ordered header list;
|
|
12
|
+
* - the answer is always `200` + `application/vnd.slicc.raw-fetch`: one
|
|
13
|
+
* response-head frame, then the body streamed through (Node `pipe`
|
|
14
|
+
* pauses upstream whenever the browser stops reading, though Chrome's
|
|
15
|
+
* `fetch` reads ahead of its JS reader, so in practice it rarely does).
|
|
16
|
+
*
|
|
17
|
+
* Secret handling is the default route's: masked values in headers, URL
|
|
18
|
+
* credentials and text bodies are unmasked for allowed domains only (403
|
|
19
|
+
* otherwise), `x-slicc-hmac-sign` is honored, and response header values and
|
|
20
|
+
* text bodies are scrubbed, including `Location`.
|
|
21
|
+
*/
|
|
22
|
+
import type { Express, Request, Response } from 'express';
|
|
23
|
+
import type { SecretProxyManager } from '../secrets/proxy-manager.js';
|
|
24
|
+
import type { AgentActivityTracker } from './agent-activity.js';
|
|
25
|
+
export interface RawFetchProxyDeps {
|
|
26
|
+
secretProxy: SecretProxyManager;
|
|
27
|
+
activityTracker: AgentActivityTracker;
|
|
28
|
+
logger?: Pick<Console, 'log' | 'warn' | 'error'>;
|
|
29
|
+
/** Request-body ceiling; tests shrink it. */
|
|
30
|
+
maxRequestBodyBytes?: number;
|
|
31
|
+
}
|
|
32
|
+
/** Whether this `/api/fetch-proxy` request selected raw mode. */
|
|
33
|
+
export declare function isRawFetchProxyRequest(req: Request): boolean;
|
|
34
|
+
/** Whether this `/api/fetch-proxy` request asks what raw mode can do. */
|
|
35
|
+
export declare function isRawFetchProbe(req: Request): boolean;
|
|
36
|
+
/** Answer the capability probe; nothing is fetched upstream. */
|
|
37
|
+
export declare function answerRawFetchProbe(res: Response, maxRequestBodyBytes: number): void;
|
|
38
|
+
export declare function handleRawFetchProxy(req: Request, res: Response, deps: RawFetchProxyDeps): Promise<void>;
|
|
39
|
+
/**
|
|
40
|
+
* Mount raw mode ahead of the default `/api/fetch-proxy` handler; requests
|
|
41
|
+
* without `X-Slicc-Raw-Request` fall through to it untouched.
|
|
42
|
+
*/
|
|
43
|
+
export declare function registerRawFetchProxyRoute(app: Express, deps: RawFetchProxyDeps): void;
|