@@ -344,6 +344,15 @@ pub fn BrowserContext(comptime CDP_T: type) type {
344344
345345 intercept_state : InterceptState ,
346346
347+ // When network is enabled, we'll capture the transfer.id -> body
348+ // This is awfully memory intensive, but our underlying http client and
349+ // its users (script manager and page) correctly do not hold the body
350+ // memory longer than they have to. In fact, the main request is only
351+ // ever streamed. So if CDP is the only thing that needs bodies in
352+ // memory for an arbitrary amount of time, then that's where we're going
353+ // to store the,
354+ captured_responses : std .AutoHashMapUnmanaged (usize , std .ArrayListUnmanaged (u8 )),
355+
347356 const Self = @This ();
348357
349358 fn init (self : * Self , id : []const u8 , cdp : * CDP_T ) ! void {
@@ -374,6 +383,7 @@ pub fn BrowserContext(comptime CDP_T: type) type {
374383 .inspector = inspector ,
375384 .notification_arena = cdp .notification_arena .allocator (),
376385 .intercept_state = try InterceptState .init (allocator ),
386+ .captured_responses = .empty ,
377387 };
378388 self .node_search_list = Node .Search .List .init (allocator , & self .node_registry );
379389 errdefer self .deinit ();
@@ -454,15 +464,17 @@ pub fn BrowserContext(comptime CDP_T: type) type {
454464 pub fn networkEnable (self : * Self ) ! void {
455465 try self .cdp .browser .notification .register (.http_request_fail , self , onHttpRequestFail );
456466 try self .cdp .browser .notification .register (.http_request_start , self , onHttpRequestStart );
457- try self .cdp .browser .notification .register (.http_headers_done , self , onHttpHeadersDone );
458467 try self .cdp .browser .notification .register (.http_request_done , self , onHttpRequestDone );
468+ try self .cdp .browser .notification .register (.http_response_data , self , onHttpResponseData );
469+ try self .cdp .browser .notification .register (.http_response_header_done , self , onHttpResponseHeadersDone );
459470 }
460471
461472 pub fn networkDisable (self : * Self ) void {
462473 self .cdp .browser .notification .unregister (.http_request_fail , self );
463474 self .cdp .browser .notification .unregister (.http_request_start , self );
464- self .cdp .browser .notification .unregister (.http_headers_done , self );
465475 self .cdp .browser .notification .unregister (.http_request_done , self );
476+ self .cdp .browser .notification .unregister (.http_response_data , self );
477+ self .cdp .browser .notification .unregister (.http_response_header_done , self );
466478 }
467479
468480 pub fn fetchEnable (self : * Self ) ! void {
@@ -483,45 +495,57 @@ pub fn BrowserContext(comptime CDP_T: type) type {
483495 return @import ("domains/page.zig" ).pageCreated (self , page );
484496 }
485497
486- pub fn onPageNavigate (ctx : * anyopaque , data : * const Notification.PageNavigate ) ! void {
498+ pub fn onPageNavigate (ctx : * anyopaque , msg : * const Notification.PageNavigate ) ! void {
487499 const self : * Self = @alignCast (@ptrCast (ctx ));
488500 defer self .resetNotificationArena ();
489- return @import ("domains/page.zig" ).pageNavigate (self .notification_arena , self , data );
501+ return @import ("domains/page.zig" ).pageNavigate (self .notification_arena , self , msg );
490502 }
491503
492- pub fn onPageNavigated (ctx : * anyopaque , data : * const Notification.PageNavigated ) ! void {
504+ pub fn onPageNavigated (ctx : * anyopaque , msg : * const Notification.PageNavigated ) ! void {
493505 const self : * Self = @alignCast (@ptrCast (ctx ));
494- return @import ("domains/page.zig" ).pageNavigated (self , data );
506+ return @import ("domains/page.zig" ).pageNavigated (self , msg );
495507 }
496508
497- pub fn onHttpRequestStart (ctx : * anyopaque , data : * const Notification.RequestStart ) ! void {
509+ pub fn onHttpRequestStart (ctx : * anyopaque , msg : * const Notification.RequestStart ) ! void {
498510 const self : * Self = @alignCast (@ptrCast (ctx ));
499511 defer self .resetNotificationArena ();
500- try @import ("domains/network.zig" ).httpRequestStart (self .notification_arena , self , data );
512+ try @import ("domains/network.zig" ).httpRequestStart (self .notification_arena , self , msg );
501513 }
502514
503- pub fn onHttpRequestIntercept (ctx : * anyopaque , data : * const Notification.RequestIntercept ) ! void {
515+ pub fn onHttpRequestIntercept (ctx : * anyopaque , msg : * const Notification.RequestIntercept ) ! void {
504516 const self : * Self = @alignCast (@ptrCast (ctx ));
505517 defer self .resetNotificationArena ();
506- try @import ("domains/fetch.zig" ).requestIntercept (self .notification_arena , self , data );
518+ try @import ("domains/fetch.zig" ).requestIntercept (self .notification_arena , self , msg );
507519 }
508520
509- pub fn onHttpRequestFail (ctx : * anyopaque , data : * const Notification.RequestFail ) ! void {
521+ pub fn onHttpRequestFail (ctx : * anyopaque , msg : * const Notification.RequestFail ) ! void {
510522 const self : * Self = @alignCast (@ptrCast (ctx ));
511523 defer self .resetNotificationArena ();
512- return @import ("domains/network.zig" ).httpRequestFail (self .notification_arena , self , data );
524+ return @import ("domains/network.zig" ).httpRequestFail (self .notification_arena , self , msg );
513525 }
514526
515- pub fn onHttpHeadersDone (ctx : * anyopaque , data : * const Notification.ResponseHeadersDone ) ! void {
527+ pub fn onHttpResponseHeadersDone (ctx : * anyopaque , msg : * const Notification.ResponseHeaderDone ) ! void {
516528 const self : * Self = @alignCast (@ptrCast (ctx ));
517529 defer self .resetNotificationArena ();
518- return @import ("domains/network.zig" ).httpHeadersDone (self .notification_arena , self , data );
530+ return @import ("domains/network.zig" ).httpResponseHeaderDone (self .notification_arena , self , msg );
519531 }
520532
521- pub fn onHttpRequestDone (ctx : * anyopaque , data : * const Notification.RequestDone ) ! void {
533+ pub fn onHttpRequestDone (ctx : * anyopaque , msg : * const Notification.RequestDone ) ! void {
522534 const self : * Self = @alignCast (@ptrCast (ctx ));
523535 defer self .resetNotificationArena ();
524- return @import ("domains/network.zig" ).httpRequestDone (self .notification_arena , self , data );
536+ return @import ("domains/network.zig" ).httpRequestDone (self .notification_arena , self , msg );
537+ }
538+
539+ pub fn onHttpResponseData (ctx : * anyopaque , msg : * const Notification.ResponseData ) ! void {
540+ const self : * Self = @alignCast (@ptrCast (ctx ));
541+ const arena = self .arena ;
542+
543+ const id = msg .transfer .id ;
544+ const gop = try self .captured_responses .getOrPut (arena , id );
545+ if (! gop .found_existing ) {
546+ gop .value_ptr .* = .{};
547+ }
548+ try gop .value_ptr .appendSlice (arena , try arena .dupe (u8 , msg .data ));
525549 }
526550
527551 fn resetNotificationArena (self : * Self ) void {
0 commit comments