Skip to content

E2B Dev Sidecar 源码级讲解

源码路径:CubeSandbox/examples/e2b-dev-sidecar/

概述

dev-sidecar 解决一个真实痛点:开发阶段不方便配泛解析 DNS,但 E2B SDK 需要通过域名路由到 CubeProxy

它在本地启动一个 HTTP 代理,自动改写 Host 头,让 SDK 的数据面流量正确到达 CubeProxy。

核心问题

解决方案架构

源码解析:dev_sidecar.py 核心逻辑

1. Sidecar 服务启动

python
async def _start_sidecar(config: dict) -> None:
    app = web.Application()
    app[CONFIG_KEY] = config
    app[SESSION_KEY] = session

    # 匹配所有 /sandboxes/router/{id}/{port} 路径
    app.router.add_route("*", "/sandboxes/router/{sandbox_id}/{port}/{tail:.*}",
                         _handle_router)
    runner = web.AppRunner(app)
    await runner.setup()
    site = web.TCPSite(runner, "127.0.0.1", port)
    await site.start()

2. 请求转发与 Host 改写

python
async def _handle_router(request):
    sandbox_id = request.match_info["sandbox_id"]
    port = request.match_info["port"]
    tail = request.match_info["tail"]

    # 构造目标 Host: <port>-<sandbox_id>.<domain>
    host = f"{port}-{sandbox_id}.{proxy_domain}"

    # 转发请求到 CubeProxy
    target_url = f"{remote_proxy_base}/{tail}"
    headers = _copy_headers(request.headers, host=host)

    if _is_websocket_request(request):
        return await _stream_ws_proxy(request, session, target_url, host=host)
    else:
        return await _stream_http_proxy(request, session, target_url, host=host)

3. Monkey Patch SDK 方法

python
def setup_dev_sidecar():
    # 替换 SDK 中的 URL 构造方法
    # 原始:直接访问 <port>-<id>.<domain>
    # 修改后:访问 127.0.0.1:<sidecar_port>/sandboxes/router/<id>/<port>

    _ORIGINAL_SANDBOX_BASE_GET_HOST = SandboxBase.get_host
    SandboxBase.get_host = _patched_get_host

    _ORIGINAL_SANDBOX_BASE_FILE_URL = SandboxBase.file_url
    SandboxBase.file_url = _patched_file_url

请求生命周期

WebSocket 支持

阅读建议

  1. _handle_router() — 核心转发逻辑
  2. _stream_http_proxy() — HTTP 流式转发
  3. _pump_websocket_to_upstream() — WebSocket 双向泵
  4. setup_dev_sidecar() — SDK monkey patch

源码参考:dev_sidecar.py