fix(#671): proxy WebSocket upgrades to External Apps#672
Merged
Conversation
`src/lib/ws-server.ts` の upgrade ハンドラに `/proxy/<prefix>/...` 分岐を追加し、
対応する external_apps レコードが enabled かつ websocket_enabled の場合は
upstream へ raw TCP で WebSocket をパススルーするようにした。これにより
Streamlit/Shiny 等 WebSocket を使う External App が CommandMate プロキシ越しでも
完全に起動できるようになる。
主な変更:
- src/lib/ws-server.ts: handleProxyUpgrade() を DI 構成で実装し、`/proxy/<prefix>` を
upstream 解決→TCP 接続→双方向パイプ
- SSRF 防御: PROXY_ALLOWED_HOSTS = {'localhost', '127.0.0.1'} allow-list
- src/lib/proxy/handler.ts: 旧 proxyWebSocket() を @deprecated 化 (実際には
Route Handler に upgrade は到達しないため dead code)
- src/app/proxy/[...path]/route.ts: HEAD メソッドを追加 (ヘルスチェック向け)
- next.config.js: skipTrailingSlashRedirect: true を設定し
`/proxy/<prefix>/` の 308 を抑止
- tests/unit/ws-server-proxy-upgrade.test.ts (11 ケース) と
tests/unit/proxy/route.test.ts (HEAD ケース) を追加
品質: lint / tsc / 6342 unit / 179 regression すべて pass。
新規コードパスのカバレッジ ~92%。
Closes #671
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
src/lib/ws-server.tsの upgrade ハンドラに/proxy/<prefix>/...分岐を追加し、external_appsレコードがenabled=1&websocket_enabled=1の場合は upstream へ raw TCP で WebSocket をパススルー (handleProxyUpgrade()を DI 構成で実装)PROXY_ALLOWED_HOSTS = {'localhost', '127.0.0.1'}allow-listproxyWebSocket()を@deprecated化、/proxy/[...path]/route.tsにHEAD追加、next.config.jsにskipTrailingSlashRedirect: trueこれにより Streamlit / Shiny 等 WebSocket を必要とする External App が CommandMate プロキシ越しでも完全にインタラクティブに起動するようになる。
Closes #671
Test plan
npm run lintPassnpx tsc --noEmitPassnpm run test:unitPass (337 files / 6342 passed / 7 skipped)npm run buildPasstests/unit/ws-server-proxy-upgrade.test.ts11 ケース passtests/integration/websocket.test.tsリグレッション無し/proxy/photon/で開いて完全にインタラクティブに動作することを手動確認 (developマージ後)受け入れ基準 (Issue #671)
/proxy/<prefix>/_stcore/streamへの WS Upgrade が upstream Streamlit に到達 (再現コマンドで上流フレームが流れる)enabled=0またはwebsocket_enabled=0の External App への WS Upgrade は 4xx で拒否tests/integration/websocket.test.tspass🤖 Generated with Claude Code