@@ -194,6 +194,65 @@ def test_browser_request_uses_curl_raw() -> None:
194194 assert request .headers .get ("x-kernel-direct-vm-request" ) is None
195195
196196
197+ def test_browser_stream_evicts_stale_route () -> None :
198+ requests : list [httpx .Request ] = []
199+
200+ def handle_request (request : httpx .Request ) -> httpx .Response :
201+ requests .append (request )
202+ if request .url .host == "browser-session.test" :
203+ return httpx .Response (401 )
204+ return httpx .Response (201 )
205+
206+ http_client = httpx .Client (transport = httpx .MockTransport (handle_request ))
207+ with Kernel (
208+ base_url = base_url ,
209+ api_key = api_key ,
210+ http_client = http_client ,
211+ _strict_response_validation = True ,
212+ ) as client :
213+ _cache_browser (client )
214+ with client .browsers .stream ("sess-1" , "POST" , "https://example.com" , content = [b"payload" ]) as response :
215+ assert response .status_code == 401
216+ assert client .browser_route_cache .get ("sess-1" ) is None
217+ client .browsers .fs .write_file ("sess-1" , b"next" , path = "/tmp/x" )
218+
219+ assert requests [0 ].url .host == "browser-session.test"
220+ assert requests [0 ].headers .get ("Authorization" ) is None
221+ assert requests [1 ].url == httpx .URL (f"{ base_url } /browsers/sess-1/fs/write_file?path=%2Ftmp%2Fx" )
222+ assert requests [1 ].headers .get ("Authorization" ) == f"Bearer { api_key } "
223+
224+
225+ @pytest .mark .asyncio
226+ async def test_async_browser_stream_evicts_stale_route () -> None :
227+ requests : list [httpx .Request ] = []
228+
229+ async def handle_request (request : httpx .Request ) -> httpx .Response :
230+ requests .append (request )
231+ if request .url .host == "browser-session.test" :
232+ return httpx .Response (403 )
233+ return httpx .Response (201 )
234+
235+ http_client = httpx .AsyncClient (transport = httpx .MockTransport (handle_request ))
236+ async with AsyncKernel (
237+ base_url = base_url ,
238+ api_key = api_key ,
239+ http_client = http_client ,
240+ _strict_response_validation = True ,
241+ ) as client :
242+ route = browser_route_from_browser (_fake_browser ())
243+ assert route is not None
244+ client .browser_route_cache .set (route )
245+ async with client .browsers .stream ("sess-1" , "POST" , "https://example.com" , content = b"payload" ) as response :
246+ assert response .status_code == 403
247+ assert client .browser_route_cache .get ("sess-1" ) is None
248+ await client .browsers .fs .write_file ("sess-1" , b"next" , path = "/tmp/x" )
249+
250+ assert requests [0 ].url .host == "browser-session.test"
251+ assert requests [0 ].headers .get ("Authorization" ) is None
252+ assert requests [1 ].url == httpx .URL (f"{ base_url } /browsers/sess-1/fs/write_file?path=%2Ftmp%2Fx" )
253+ assert requests [1 ].headers .get ("Authorization" ) == f"Bearer { api_key } "
254+
255+
197256@respx .mock
198257def test_telemetry_stream_routes_directly_to_vm (monkeypatch : pytest .MonkeyPatch ) -> None :
199258 monkeypatch .setenv ("KERNEL_BROWSER_ROUTING_SUBRESOURCES" , "telemetry/stream" )
0 commit comments