Skip to content

Commit 728330d

Browse files
committed
Retry stale direct-VM auth without needing the cache
A metro 401/403 with a jwt query param is enough to fall back to the control plane, so concurrent requests still retry after the first eviction.
1 parent 3580671 commit 728330d

3 files changed

Lines changed: 22 additions & 5 deletions

File tree

src/kernel/_client.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ def _prepare_request(self, request: httpx.Request) -> None:
356356

357357
@override
358358
def _should_retry(self, response: httpx.Response) -> bool:
359-
if should_retry_stale_direct_vm_auth(response, cache=self.browser_route_cache):
359+
if should_retry_stale_direct_vm_auth(response):
360360
maybe_evict_browser_route_from_response(response, cache=self.browser_route_cache)
361361
return True
362362
return super()._should_retry(response)
@@ -732,7 +732,7 @@ async def _prepare_request(self, request: httpx.Request) -> None:
732732

733733
@override
734734
def _should_retry(self, response: httpx.Response) -> bool:
735-
if should_retry_stale_direct_vm_auth(response, cache=self.browser_route_cache):
735+
if should_retry_stale_direct_vm_auth(response):
736736
maybe_evict_browser_route_from_response(response, cache=self.browser_route_cache)
737737
return True
738738
return super()._should_retry(response)

src/kernel/lib/browser_routing/routing.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ def maybe_evict_browser_route_from_response(response: httpx.Response, *, cache:
116116
cache.delete(session_id)
117117
return
118118

119-
if response.status_code not in {401, 403}:
119+
if not is_stale_direct_vm_auth_response(response):
120120
return
121121

122122
session_id = _session_id_from_direct_vm_response(response, cache=cache)
@@ -173,10 +173,14 @@ def _session_id_from_direct_vm_response(response: httpx.Response, *, cache: Brow
173173
return None
174174

175175

176-
def should_retry_stale_direct_vm_auth(response: httpx.Response, *, cache: BrowserRouteCache) -> bool:
176+
def is_stale_direct_vm_auth_response(response: httpx.Response) -> bool:
177177
if response.status_code not in {401, 403}:
178178
return False
179-
return _session_id_from_direct_vm_response(response, cache=cache) is not None
179+
return bool(response.request.url.params.get("jwt"))
180+
181+
182+
def should_retry_stale_direct_vm_auth(response: httpx.Response) -> bool:
183+
return is_stale_direct_vm_auth_response(response)
180184

181185

182186
def _session_id_from_browser_delete_path(path: str) -> str | None:

tests/test_browser_routing.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,3 +546,16 @@ def _skip_retry_sleep(_self: object, **_kwargs: object) -> None:
546546
assert api.called
547547
api_req = cast(httpx.Request, cast(Any, api.calls[0]).request)
548548
assert api_req.headers.get("Authorization") == f"Bearer {api_key}"
549+
550+
551+
def test_stale_direct_vm_auth_retry_does_not_require_cached_route() -> None:
552+
from kernel.lib.browser_routing.routing import should_retry_stale_direct_vm_auth
553+
554+
request = httpx.Request(
555+
"POST",
556+
"http://browser-session.test/browser/kernel/computer/screenshot?jwt=token-abc",
557+
)
558+
response = httpx.Response(401, text="Invalid JWT", request=request)
559+
empty = BrowserRouteCache()
560+
assert should_retry_stale_direct_vm_auth(response) is True
561+
assert empty.get("sess-1") is None

0 commit comments

Comments
 (0)