@@ -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
@@ -43,10 +42,8 @@ const Location = @import("../html/location.zig").Location;
4342
4443const storage = @import ("../storage/storage.zig" );
4544
46- const FetchResult = @import ("../http/Client.zig" ).Client .FetchResult ;
47-
45+ const http = @import ("../http/client.zig" );
4846const UserContext = @import ("../user_context.zig" ).UserContext ;
49- const HttpClient = @import ("asyncio" ).Client ;
5047
5148const polyfill = @import ("../polyfill/polyfill.zig" );
5249
@@ -62,19 +59,19 @@ pub const Browser = struct {
6259 loop : * Loop ,
6360 session : ? * Session ,
6461 allocator : Allocator ,
65- http_client : HttpClient ,
62+ http_client : http.Client ,
6663 session_pool : SessionPool ,
6764 page_arena : std.heap.ArenaAllocator ,
6865
6966 const SessionPool = std .heap .MemoryPool (Session );
7067
71- pub fn init (allocator : Allocator , loop : * Loop ) Browser {
68+ pub fn init (allocator : Allocator , loop : * Loop ) ! Browser {
7269 return .{
7370 .loop = loop ,
7471 .session = null ,
7572 .allocator = allocator ,
76- .http_client = .{ .allocator = allocator },
7773 .session_pool = SessionPool .init (allocator ),
74+ .http_client = try http .Client .init (allocator , 5 ),
7875 .page_arena = std .heap .ArenaAllocator .init (allocator ),
7976 };
8077 }
@@ -118,9 +115,6 @@ pub const Session = struct {
118115 // all others Session deps use directly self.alloc and not the arena.
119116 arena : std.heap.ArenaAllocator ,
120117
121- // TODO handle proxy
122- loader : Loader ,
123-
124118 env : Env ,
125119 inspector : jsruntime.Inspector ,
126120
@@ -129,6 +123,7 @@ pub const Session = struct {
129123 // TODO move the shed to the browser?
130124 storage_shed : storage.Shed ,
131125 page : ? Page = null ,
126+ http_client : * http.Client ,
132127
133128 jstypes : [Types .len ]usize = undefined ,
134129
@@ -138,7 +133,7 @@ pub const Session = struct {
138133 .env = undefined ,
139134 .browser = browser ,
140135 .inspector = undefined ,
141- .loader = Loader . init ( allocator ) ,
136+ .http_client = & browser . http_client ,
142137 .storage_shed = storage .Shed .init (allocator ),
143138 .arena = std .heap .ArenaAllocator .init (allocator ),
144139 .window = Window .create (null , .{ .agent = user_agent }),
@@ -176,7 +171,6 @@ pub const Session = struct {
176171 }
177172 self .env .deinit ();
178173 self .arena .deinit ();
179- self .loader .deinit ();
180174 self .storage_shed .deinit ();
181175 }
182176
@@ -360,32 +354,14 @@ pub const Page = struct {
360354 // TODO handle fragment in url.
361355
362356 // load the data
363- var resp = try self .session .loader .get (arena , self .uri );
364- defer resp .deinit ();
357+ var request = try self .session .http_client .request (.GET , self .uri );
358+ defer request .deinit ();
359+ var response = try request .sendSync (.{});
365360
366- const req = resp .req ;
361+ const header = response .header ;
362+ log .info ("GET {any} {d}" , .{ self .uri , header .status });
367363
368- log .info ("GET {any} {d}" , .{ self .uri , @intFromEnum (req .response .status ) });
369-
370- // TODO handle redirection
371- log .debug ("{?} {d} {s}" , .{
372- req .response .version ,
373- @intFromEnum (req .response .status ),
374- req .response .reason ,
375- // TODO log headers
376- });
377-
378- // TODO handle charset
379- // https://html.spec.whatwg.org/#content-type
380- var it = req .response .iterateHeaders ();
381- var ct_ : ? []const u8 = null ;
382- while (true ) {
383- const h = it .next () orelse break ;
384- if (std .ascii .eqlIgnoreCase (h .name , "Content-Type" )) {
385- ct_ = try arena .dupe (u8 , h .value );
386- }
387- }
388- const ct = ct_ orelse {
364+ const ct = response .header .get ("content-type" ) orelse {
389365 // no content type in HTTP headers.
390366 // TODO try to sniff mime type from the body.
391367 log .info ("no content-type HTTP header" , .{});
@@ -394,14 +370,18 @@ pub const Page = struct {
394370
395371 log .debug ("header content-type: {s}" , .{ct });
396372 var mime = try Mime .parse (arena , ct );
373+ defer mime .deinit ();
397374
398375 if (mime .isHTML ()) {
399- try self .loadHTMLDoc (req . reader () , mime .charset orelse "utf-8" , aux_data );
376+ try self .loadHTMLDoc (& response , mime .charset orelse "utf-8" , aux_data );
400377 } else {
401378 log .info ("non-HTML document: {s}" , .{ct });
402-
379+ var arr : std .ArrayListUnmanaged (u8 ) = .{};
380+ while (try response .next ()) | data | {
381+ try arr .appendSlice (arena , try arena .dupe (u8 , data ));
382+ }
403383 // save the body into the page.
404- self .raw_data = try req . reader (). readAllAlloc ( arena , 16 * 1024 * 1024 ) ;
384+ self .raw_data = arr . items ;
405385 }
406386 }
407387
@@ -443,7 +423,7 @@ pub const Page = struct {
443423 // replace the user context document with the new one.
444424 try session .env .setUserContext (.{
445425 .document = html_doc ,
446- .httpClient = & self .session .browser . http_client ,
426+ .http_client = @ptrCast ( & self .session .http_client ) ,
447427 });
448428
449429 // browse the DOM tree to retrieve scripts
@@ -620,30 +600,32 @@ pub const Page = struct {
620600
621601 const u = try std .Uri .resolve_inplace (self .uri , res_src , & b );
622602
623- var fetchres = try self .session .loader .get (arena , u );
624- defer fetchres .deinit ();
625-
626- const resp = fetchres .req .response ;
603+ var request = try self .session .http_client .request (.GET , u );
604+ defer request .deinit ();
605+ var response = try request .sendSync (.{});
627606
628- log .info ("fetch {any}: {d}" , .{ u , resp .status });
607+ log .info ("fetch {any}: {d}" , .{ u , response . header .status });
629608
630- if (resp . status != .ok ) {
609+ if (response . header . status != 200 ) {
631610 return FetchError .BadStatusCode ;
632611 }
633612
613+ var arr : std .ArrayListUnmanaged (u8 ) = .{};
614+ while (try response .next ()) | data | {
615+ try arr .appendSlice (arena , try arena .dupe (u8 , data ));
616+ }
617+
634618 // TODO check content-type
635- const body = try fetchres .req .reader ().readAllAlloc (arena , 16 * 1024 * 1024 );
636619
637620 // check no body
638- if (body .len == 0 ) {
621+ if (arr . items .len == 0 ) {
639622 return FetchError .NoBody ;
640623 }
641624
642- return body ;
625+ return arr . items ;
643626 }
644627
645- // fetchScript senf a GET request to the src and execute the script
646- // received.
628+
647629 fn fetchScript (self : * const Page , s : * const Script ) ! void {
648630 const arena = self .arena ;
649631
0 commit comments