@@ -24,7 +24,6 @@ const Allocator = std.mem.Allocator;
2424const Types = @import ("root" ).Types ;
2525
2626const parser = @import ("netsurf" );
27- const Loader = @import ("loader.zig" ).Loader ;
2827const Dump = @import ("dump.zig" );
2928const Mime = @import ("mime.zig" ).Mime ;
3029
@@ -44,10 +43,8 @@ const Location = @import("../html/location.zig").Location;
4443
4544const storage = @import ("../storage/storage.zig" );
4645
47- const FetchResult = @import ("../http/Client.zig" ).Client .FetchResult ;
48-
46+ const http = @import ("../http/client.zig" );
4947const UserContext = @import ("../user_context.zig" ).UserContext ;
50- const HttpClient = @import ("asyncio" ).Client ;
5148
5249const polyfill = @import ("../polyfill/polyfill.zig" );
5350
@@ -63,20 +60,20 @@ pub const Browser = struct {
6360 app : * App ,
6461 session : ? * Session ,
6562 allocator : Allocator ,
66- http_client : HttpClient ,
63+ http_client : http.Client ,
6764 session_pool : SessionPool ,
6865 page_arena : std.heap.ArenaAllocator ,
6966
7067 const SessionPool = std .heap .MemoryPool (Session );
7168
72- pub fn init (app : * App ) Browser {
69+ pub fn init (app : * App ) ! Browser {
7370 const allocator = app .allocator ;
7471 return .{
7572 .app = app ,
7673 .session = null ,
7774 .allocator = allocator ,
78- .http_client = .{ .allocator = allocator },
7975 .session_pool = SessionPool .init (allocator ),
76+ .http_client = try http .Client .init (allocator , 5 ),
8077 .page_arena = std .heap .ArenaAllocator .init (allocator ),
8178 };
8279 }
@@ -122,9 +119,6 @@ pub const Session = struct {
122119 // all others Session deps use directly self.alloc and not the arena.
123120 arena : std.heap.ArenaAllocator ,
124121
125- // TODO handle proxy
126- loader : Loader ,
127-
128122 env : Env ,
129123 inspector : jsruntime.Inspector ,
130124
@@ -133,6 +127,7 @@ pub const Session = struct {
133127 // TODO move the shed to the browser?
134128 storage_shed : storage.Shed ,
135129 page : ? Page = null ,
130+ http_client : * http.Client ,
136131
137132 jstypes : [Types .len ]usize = undefined ,
138133
@@ -144,7 +139,7 @@ pub const Session = struct {
144139 .env = undefined ,
145140 .browser = browser ,
146141 .inspector = undefined ,
147- .loader = Loader . init ( allocator ) ,
142+ .http_client = & browser . http_client ,
148143 .storage_shed = storage .Shed .init (allocator ),
149144 .arena = std .heap .ArenaAllocator .init (allocator ),
150145 .window = Window .create (null , .{ .agent = user_agent }),
@@ -182,7 +177,6 @@ pub const Session = struct {
182177 }
183178 self .env .deinit ();
184179 self .arena .deinit ();
185- self .loader .deinit ();
186180 self .storage_shed .deinit ();
187181 }
188182
@@ -371,32 +365,14 @@ pub const Page = struct {
371365 } });
372366
373367 // load the data
374- var resp = try self .session .loader .get (arena , self .uri );
375- defer resp .deinit ();
368+ var request = try self .session .http_client .request (.GET , self .uri );
369+ defer request .deinit ();
370+ var response = try request .sendSync (.{});
376371
377- const req = resp .req ;
372+ const header = response .header ;
373+ log .info ("GET {any} {d}" , .{ self .uri , header .status });
378374
379- log .info ("GET {any} {d}" , .{ self .uri , @intFromEnum (req .response .status ) });
380-
381- // TODO handle redirection
382- log .debug ("{?} {d} {s}" , .{
383- req .response .version ,
384- @intFromEnum (req .response .status ),
385- req .response .reason ,
386- // TODO log headers
387- });
388-
389- // TODO handle charset
390- // https://html.spec.whatwg.org/#content-type
391- var it = req .response .iterateHeaders ();
392- var ct_ : ? []const u8 = null ;
393- while (true ) {
394- const h = it .next () orelse break ;
395- if (std .ascii .eqlIgnoreCase (h .name , "Content-Type" )) {
396- ct_ = try arena .dupe (u8 , h .value );
397- }
398- }
399- const ct = ct_ orelse {
375+ const ct = response .header .get ("content-type" ) orelse {
400376 // no content type in HTTP headers.
401377 // TODO try to sniff mime type from the body.
402378 log .info ("no content-type HTTP header" , .{});
@@ -405,14 +381,18 @@ pub const Page = struct {
405381
406382 log .debug ("header content-type: {s}" , .{ct });
407383 var mime = try Mime .parse (arena , ct );
384+ defer mime .deinit ();
408385
409386 if (mime .isHTML ()) {
410- try self .loadHTMLDoc (req . reader () , mime .charset orelse "utf-8" , aux_data );
387+ try self .loadHTMLDoc (& response , mime .charset orelse "utf-8" , aux_data );
411388 } else {
412389 log .info ("non-HTML document: {s}" , .{ct });
413-
390+ var arr : std .ArrayListUnmanaged (u8 ) = .{};
391+ while (try response .next ()) | data | {
392+ try arr .appendSlice (arena , try arena .dupe (u8 , data ));
393+ }
414394 // save the body into the page.
415- self .raw_data = try req . reader (). readAllAlloc ( arena , 16 * 1024 * 1024 ) ;
395+ self .raw_data = arr . items ;
416396 }
417397 }
418398
@@ -454,7 +434,7 @@ pub const Page = struct {
454434 // replace the user context document with the new one.
455435 try session .env .setUserContext (.{
456436 .document = html_doc ,
457- .httpClient = & self .session .browser . http_client ,
437+ .http_client = @ptrCast ( & self .session .http_client ) ,
458438 });
459439
460440 // browse the DOM tree to retrieve scripts
@@ -629,30 +609,32 @@ pub const Page = struct {
629609
630610 const u = try std .Uri .resolve_inplace (self .uri , res_src , & b );
631611
632- var fetchres = try self .session .loader .get (arena , u );
633- defer fetchres .deinit ();
634-
635- const resp = fetchres .req .response ;
612+ var request = try self .session .http_client .request (.GET , u );
613+ defer request .deinit ();
614+ var response = try request .sendSync (.{});
636615
637- log .info ("fetch {any}: {d}" , .{ u , resp .status });
616+ log .info ("fetch {any}: {d}" , .{ u , response . header .status });
638617
639- if (resp . status != .ok ) {
618+ if (response . header . status != 200 ) {
640619 return FetchError .BadStatusCode ;
641620 }
642621
622+ var arr : std .ArrayListUnmanaged (u8 ) = .{};
623+ while (try response .next ()) | data | {
624+ try arr .appendSlice (arena , try arena .dupe (u8 , data ));
625+ }
626+
643627 // TODO check content-type
644- const body = try fetchres .req .reader ().readAllAlloc (arena , 16 * 1024 * 1024 );
645628
646629 // check no body
647- if (body .len == 0 ) {
630+ if (arr . items .len == 0 ) {
648631 return FetchError .NoBody ;
649632 }
650633
651- return body ;
634+ return arr . items ;
652635 }
653636
654- // fetchScript senf a GET request to the src and execute the script
655- // received.
637+
656638 fn fetchScript (self : * const Page , s : * const Script ) ! void {
657639 const arena = self .arena ;
658640 const body = try self .fetchData (arena , s .src , null );
0 commit comments