Skip to content

Commit f4c247b

Browse files
committed
fix: normalize browser route cache session IDs
Store browser routes under a normalized session ID so cache lookups and deletes stay consistent when route data includes surrounding whitespace. Add a regression test to lock in the normalization behavior. Made-with: Cursor
1 parent 0647d5c commit f4c247b

2 files changed

Lines changed: 35 additions & 5 deletions

File tree

src/kernel/lib/browser_routing/routing.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,17 +43,18 @@ def __init__(self) -> None:
4343
self._routes: dict[str, BrowserRoute] = {}
4444

4545
def get(self, session_id: str) -> BrowserRoute | None:
46-
return self._routes.get(session_id)
46+
return self._routes.get(_normalize_session_id(session_id))
4747

4848
def set(self, route: BrowserRoute) -> None:
49-
self._routes[route.session_id] = BrowserRoute(
50-
session_id=route.session_id.strip(),
49+
normalized_session_id = _normalize_session_id(route.session_id)
50+
self._routes[normalized_session_id] = BrowserRoute(
51+
session_id=normalized_session_id,
5152
base_url=route.base_url.strip().rstrip("/") + "/",
5253
jwt=route.jwt.strip(),
5354
)
5455

5556
def delete(self, session_id: str) -> None:
56-
self._routes.pop(session_id, None)
57+
self._routes.pop(_normalize_session_id(session_id), None)
5758

5859
def values(self) -> list[BrowserRoute]:
5960
return list(self._routes.values())
@@ -80,6 +81,10 @@ def browser_route_from_browser(browser: Any) -> BrowserRoute | None:
8081
return BrowserRoute(session_id=session_id, base_url=base_url, jwt=jwt)
8182

8283

84+
def _normalize_session_id(session_id: str) -> str:
85+
return session_id.strip()
86+
87+
8388
def rewrite_direct_vm_options(
8489
options: FinalRequestOptions,
8590
*,

tests/test_browser_routing.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@
99

1010
from kernel import Kernel
1111
from kernel.lib.browser_routing.util import jwt_from_cdp_ws_url
12-
from kernel.lib.browser_routing.routing import browser_route_from_browser, browser_routing_config_from_env
12+
from kernel.lib.browser_routing.routing import (
13+
BrowserRoute,
14+
BrowserRouteCache,
15+
browser_route_from_browser,
16+
browser_routing_config_from_env,
17+
)
1318

1419
base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
1520
api_key = "sk-123"
@@ -120,6 +125,26 @@ def test_browser_request_requires_cached_route() -> None:
120125
client.browsers.request("sess-1", "GET", "https://example.com")
121126

122127

128+
def test_browser_route_cache_normalizes_session_id_keys() -> None:
129+
cache = BrowserRouteCache()
130+
cache.set(
131+
BrowserRoute(
132+
session_id=" sess-1 ",
133+
base_url=" http://browser-session.test/browser/kernel/ ",
134+
jwt=" token-abc ",
135+
)
136+
)
137+
138+
route = cache.get("sess-1")
139+
assert route is not None
140+
assert route.session_id == "sess-1"
141+
assert route.base_url == "http://browser-session.test/browser/kernel/"
142+
assert route.jwt == "token-abc"
143+
144+
cache.delete("sess-1")
145+
assert cache.get("sess-1") is None
146+
147+
123148
def test_browser_route_from_browser_requires_base_url_and_jwt() -> None:
124149
assert browser_route_from_browser({**_fake_browser(), "base_url": None}) is None
125150
assert browser_route_from_browser({**_fake_browser(), "cdp_ws_url": None}) is None

0 commit comments

Comments
 (0)