@@ -241,6 +241,11 @@ async def _actual_headers(self) -> "RawHeaders":
241
241
self ._all_headers_future .set_result (RawHeaders (headers ))
242
242
return await self ._all_headers_future
243
243
244
+ def _target_closed_future (self ) -> asyncio .Future :
245
+ if not hasattr (self .frame , "_page" ):
246
+ return asyncio .Future ()
247
+ return self .frame ._page ._closed_or_crashed_future
248
+
244
249
245
250
class Route (ChannelOwner ):
246
251
def __init__ (
@@ -348,10 +353,11 @@ async def fetch(
348
353
method : str = None ,
349
354
headers : Dict [str , str ] = None ,
350
355
postData : Union [Any , str , bytes ] = None ,
356
+ maxRedirects : int = None ,
351
357
) -> "APIResponse" :
352
358
page = self .request .frame ._page
353
359
return await page .context .request ._inner_fetch (
354
- self .request , url , method , headers , postData
360
+ self .request , url , method , headers , postData , maxRedirects = maxRedirects
355
361
)
356
362
357
363
async def fallback (
@@ -419,30 +425,22 @@ async def _redirected_navigation_request(self, url: str) -> None:
419
425
self ._report_handled (True )
420
426
421
427
async def _race_with_page_close (self , future : Coroutine ) -> None :
422
- if hasattr (self .request .frame , "_page" ):
423
- page = self .request .frame ._page
424
- # When page closes or crashes, we catch any potential rejects from this Route.
425
- # Note that page could be missing when routing popup's initial request that
426
- # does not have a Page initialized just yet.
427
- fut = asyncio .create_task (future )
428
- # Rewrite the user's stack to the new task which runs in the background.
429
- setattr (
430
- fut ,
431
- "__pw_stack__" ,
432
- getattr (
433
- asyncio .current_task (self ._loop ), "__pw_stack__" , inspect .stack ()
434
- ),
435
- )
436
- await asyncio .wait (
437
- [fut , page ._closed_or_crashed_future ],
438
- return_when = asyncio .FIRST_COMPLETED ,
439
- )
440
- if fut .done () and fut .exception ():
441
- raise cast (BaseException , fut .exception ())
442
- if page ._closed_or_crashed_future .done ():
443
- await asyncio .gather (fut , return_exceptions = True )
444
- else :
445
- await future
428
+ fut = asyncio .create_task (future )
429
+ # Rewrite the user's stack to the new task which runs in the background.
430
+ setattr (
431
+ fut ,
432
+ "__pw_stack__" ,
433
+ getattr (asyncio .current_task (self ._loop ), "__pw_stack__" , inspect .stack ()),
434
+ )
435
+ target_closed_future = self .request ._target_closed_future ()
436
+ await asyncio .wait (
437
+ [fut , target_closed_future ],
438
+ return_when = asyncio .FIRST_COMPLETED ,
439
+ )
440
+ if fut .done () and fut .exception ():
441
+ raise cast (BaseException , fut .exception ())
442
+ if target_closed_future .done ():
443
+ await asyncio .gather (fut , return_exceptions = True )
446
444
447
445
448
446
class Response (ChannelOwner ):
@@ -522,7 +520,20 @@ async def security_details(self) -> Optional[SecurityDetails]:
522
520
return await self ._channel .send ("securityDetails" )
523
521
524
522
async def finished (self ) -> None :
525
- await self ._finished_future
523
+ async def on_finished () -> None :
524
+ await self ._request ._target_closed_future ()
525
+ raise Error ("Target closed" )
526
+
527
+ on_finished_task = asyncio .create_task (on_finished ())
528
+ await asyncio .wait (
529
+ cast (
530
+ List [Union [asyncio .Task , asyncio .Future ]],
531
+ [self ._finished_future , on_finished_task ],
532
+ ),
533
+ return_when = asyncio .FIRST_COMPLETED ,
534
+ )
535
+ if on_finished_task .done ():
536
+ await on_finished_task
526
537
527
538
async def body (self ) -> bytes :
528
539
binary = await self ._channel .send ("body" )
0 commit comments