mirror of
				https://github.com/lightpanda-io/browser.git
				synced 2025-10-30 07:31:47 +00:00 
			
		
		
		
	Merge pull request #768 from lightpanda-io/setExtraHTTPHeaders
	
		
			
	
		
	
	
		
	
		
			Some checks failed
		
		
	
	
		
			
				
	
				e2e-test / zig build release (push) Has been cancelled
				
			
		
			
				
	
				e2e-test / puppeteer-perf (push) Has been cancelled
				
			
		
			
				
	
				e2e-test / demo-scripts (push) Has been cancelled
				
			
		
			
				
	
				e2e-test / cdp-and-hyperfine-bench (push) Has been cancelled
				
			
		
			
				
	
				e2e-test / perf-fmt (push) Has been cancelled
				
			
		
			
				
	
				zig-test / zig build dev (push) Has been cancelled
				
			
		
			
				
	
				zig-test / browser fetch (push) Has been cancelled
				
			
		
			
				
	
				zig-test / zig test (push) Has been cancelled
				
			
		
			
				
	
				zig-test / perf-fmt (push) Has been cancelled
				
			
		
		
	
	
				
					
				
			
		
			Some checks failed
		
		
	
	e2e-test / zig build release (push) Has been cancelled
				
			e2e-test / puppeteer-perf (push) Has been cancelled
				
			e2e-test / demo-scripts (push) Has been cancelled
				
			e2e-test / cdp-and-hyperfine-bench (push) Has been cancelled
				
			e2e-test / perf-fmt (push) Has been cancelled
				
			zig-test / zig build dev (push) Has been cancelled
				
			zig-test / browser fetch (push) Has been cancelled
				
			zig-test / zig test (push) Has been cancelled
				
			zig-test / perf-fmt (push) Has been cancelled
				
			setExtraHTTPHeaders
This commit is contained in:
		| @@ -71,6 +71,9 @@ pub fn CDPT(comptime TypeProvider: type) type { | ||||
|         // Used for processing notifications within a browser context. | ||||
|         notification_arena: std.heap.ArenaAllocator, | ||||
|  | ||||
|         // Extra headers to add to all requests. TBD under which conditions this should be reset. | ||||
|         extra_headers: std.ArrayListUnmanaged(std.http.Header) = .empty, | ||||
|  | ||||
|         const Self = @This(); | ||||
|  | ||||
|         pub fn init(app: *App, client: TypeProvider.Client) !Self { | ||||
|   | ||||
| @@ -18,6 +18,7 @@ | ||||
|  | ||||
| const std = @import("std"); | ||||
| const Notification = @import("../../notification.zig").Notification; | ||||
| const log = @import("../../log.zig"); | ||||
|  | ||||
| const Allocator = std.mem.Allocator; | ||||
|  | ||||
| @@ -26,12 +27,14 @@ pub fn processMessage(cmd: anytype) !void { | ||||
|         enable, | ||||
|         disable, | ||||
|         setCacheDisabled, | ||||
|         setExtraHTTPHeaders, | ||||
|     }, cmd.input.action) orelse return error.UnknownMethod; | ||||
|  | ||||
|     switch (action) { | ||||
|         .enable => return enable(cmd), | ||||
|         .disable => return disable(cmd), | ||||
|         .setCacheDisabled => return cmd.sendResult(null, .{}), | ||||
|         .setExtraHTTPHeaders => return setExtraHTTPHeaders(cmd), | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -47,6 +50,40 @@ fn disable(cmd: anytype) !void { | ||||
|     return cmd.sendResult(null, .{}); | ||||
| } | ||||
|  | ||||
| fn setExtraHTTPHeaders(cmd: anytype) !void { | ||||
|     const params = (try cmd.params(struct { | ||||
|         headers: std.json.ArrayHashMap([]const u8), | ||||
|     })) orelse return error.InvalidParams; | ||||
|  | ||||
|     const bc = cmd.browser_context orelse return error.BrowserContextNotLoaded; | ||||
|  | ||||
|     // Copy the headers onto the browser context arena | ||||
|     const arena = bc.arena; | ||||
|     const extra_headers = &bc.cdp.extra_headers; | ||||
|  | ||||
|     extra_headers.clearRetainingCapacity(); | ||||
|     try extra_headers.ensureTotalCapacity(arena, params.headers.map.count()); | ||||
|     var it = params.headers.map.iterator(); | ||||
|     while (it.next()) |header| { | ||||
|         extra_headers.appendAssumeCapacity(.{ .name = try arena.dupe(u8, header.key_ptr.*), .value = try arena.dupe(u8, header.value_ptr.*) }); | ||||
|     } | ||||
|  | ||||
|     return cmd.sendResult(null, .{}); | ||||
| } | ||||
|  | ||||
| // Upsert a header into the headers array. | ||||
| // returns true if the header was added, false if it was updated | ||||
| fn putAssumeCapacity(headers: *std.ArrayListUnmanaged(std.http.Header), extra: std.http.Header) bool { | ||||
|     for (headers.items) |*header| { | ||||
|         if (std.mem.eql(u8, header.name, extra.name)) { | ||||
|             header.value = extra.value; | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
|     headers.appendAssumeCapacity(extra); | ||||
|     return true; | ||||
| } | ||||
|  | ||||
| pub fn httpRequestStart(arena: Allocator, bc: anytype, request: *const Notification.RequestStart) !void { | ||||
|     // Isn't possible to do a network request within a Browser (which our | ||||
|     // notification is tied to), without a page. | ||||
| @@ -59,6 +96,13 @@ pub fn httpRequestStart(arena: Allocator, bc: anytype, request: *const Notificat | ||||
|     const target_id = bc.target_id orelse unreachable; | ||||
|     const page = bc.session.currentPage() orelse unreachable; | ||||
|  | ||||
|     // Modify request with extra CDP headers | ||||
|     try request.headers.ensureTotalCapacity(request.arena, request.headers.items.len + cdp.extra_headers.items.len); | ||||
|     for (cdp.extra_headers.items) |extra| { | ||||
|         const new = putAssumeCapacity(request.headers, extra); | ||||
|         if (!new) log.debug(.cdp, "request header overwritten", .{ .name = extra.name }); | ||||
|     } | ||||
|  | ||||
|     const document_url = try urlToString(arena, &page.url.uri, .{ | ||||
|         .scheme = true, | ||||
|         .authentication = true, | ||||
| @@ -80,8 +124,8 @@ pub fn httpRequestStart(arena: Allocator, bc: anytype, request: *const Notificat | ||||
|     }); | ||||
|  | ||||
|     var headers: std.StringArrayHashMapUnmanaged([]const u8) = .empty; | ||||
|     try headers.ensureTotalCapacity(arena, request.headers.len); | ||||
|     for (request.headers) |header| { | ||||
|     try headers.ensureTotalCapacity(arena, request.headers.items.len); | ||||
|     for (request.headers.items) |header| { | ||||
|         headers.putAssumeCapacity(header.name, header.value); | ||||
|     } | ||||
|  | ||||
| @@ -129,13 +173,13 @@ pub fn httpRequestComplete(arena: Allocator, bc: anytype, request: *const Notifi | ||||
|     // We're missing a bunch of fields, but, for now, this seems like enough | ||||
|     try cdp.sendEvent("Network.responseReceived", .{ | ||||
|         .requestId = try std.fmt.allocPrint(arena, "REQ-{d}", .{request.id}), | ||||
|         .frameId = target_id, | ||||
|         .loaderId = bc.loader_id, | ||||
|         .response = .{ | ||||
|             .url = url, | ||||
|             .status = request.status, | ||||
|             .headers = std.json.ArrayHashMap([]const u8){ .map = headers }, | ||||
|         }, | ||||
|         .frameId = target_id, | ||||
|     }, .{ .session_id = session_id }); | ||||
| } | ||||
|  | ||||
| @@ -144,3 +188,30 @@ fn urlToString(arena: Allocator, url: *const std.Uri, opts: std.Uri.WriteToStrea | ||||
|     try url.writeToStream(opts, buf.writer(arena)); | ||||
|     return buf.items; | ||||
| } | ||||
|  | ||||
| const testing = @import("../testing.zig"); | ||||
| test "cdp.network setExtraHTTPHeaders" { | ||||
|     var ctx = testing.context(); | ||||
|     defer ctx.deinit(); | ||||
|  | ||||
|     // _ = try ctx.loadBrowserContext(.{ .id = "NID-A", .session_id = "NESI-A" }); | ||||
|     try ctx.processMessage(.{ .id = 10, .method = "Target.createTarget", .params = .{ .url = "about/blank" } }); | ||||
|  | ||||
|     try ctx.processMessage(.{ | ||||
|         .id = 3, | ||||
|         .method = "Network.setExtraHTTPHeaders", | ||||
|         .params = .{ .headers = .{ .foo = "bar" } }, | ||||
|     }); | ||||
|  | ||||
|     try ctx.processMessage(.{ | ||||
|         .id = 4, | ||||
|         .method = "Network.setExtraHTTPHeaders", | ||||
|         .params = .{ .headers = .{ .food = "bars" } }, | ||||
|     }); | ||||
|  | ||||
|     const bc = ctx.cdp().browser_context.?; | ||||
|     try testing.expectEqual(bc.cdp.extra_headers.items.len, 1); | ||||
|  | ||||
|     try ctx.processMessage(.{ .id = 5, .method = "Target.attachToTarget", .params = .{ .targetId = bc.target_id.? } }); | ||||
|     try testing.expectEqual(bc.cdp.extra_headers.items.len, 0); | ||||
| } | ||||
|   | ||||
| @@ -389,6 +389,9 @@ fn doAttachtoTarget(cmd: anytype, target_id: []const u8) !void { | ||||
|     std.debug.assert(bc.session_id == null); | ||||
|     const session_id = cmd.cdp.session_id_gen.next(); | ||||
|  | ||||
|     // extra_headers should not be kept on a new page or tab, currently we have only 1 page, we clear it just in case | ||||
|     bc.cdp.extra_headers.clearRetainingCapacity(); | ||||
|  | ||||
|     try cmd.sendEvent("Target.attachedToTarget", AttachToTarget{ | ||||
|         .sessionId = session_id, | ||||
|         .targetInfo = TargetInfo{ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Karl Seguin
					Karl Seguin