mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-29 07:03:29 +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.
|
// Used for processing notifications within a browser context.
|
||||||
notification_arena: std.heap.ArenaAllocator,
|
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();
|
const Self = @This();
|
||||||
|
|
||||||
pub fn init(app: *App, client: TypeProvider.Client) !Self {
|
pub fn init(app: *App, client: TypeProvider.Client) !Self {
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const Notification = @import("../../notification.zig").Notification;
|
const Notification = @import("../../notification.zig").Notification;
|
||||||
|
const log = @import("../../log.zig");
|
||||||
|
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
|
|
||||||
@@ -26,12 +27,14 @@ pub fn processMessage(cmd: anytype) !void {
|
|||||||
enable,
|
enable,
|
||||||
disable,
|
disable,
|
||||||
setCacheDisabled,
|
setCacheDisabled,
|
||||||
|
setExtraHTTPHeaders,
|
||||||
}, cmd.input.action) orelse return error.UnknownMethod;
|
}, cmd.input.action) orelse return error.UnknownMethod;
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
.enable => return enable(cmd),
|
.enable => return enable(cmd),
|
||||||
.disable => return disable(cmd),
|
.disable => return disable(cmd),
|
||||||
.setCacheDisabled => return cmd.sendResult(null, .{}),
|
.setCacheDisabled => return cmd.sendResult(null, .{}),
|
||||||
|
.setExtraHTTPHeaders => return setExtraHTTPHeaders(cmd),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,6 +50,40 @@ fn disable(cmd: anytype) !void {
|
|||||||
return cmd.sendResult(null, .{});
|
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 {
|
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
|
// Isn't possible to do a network request within a Browser (which our
|
||||||
// notification is tied to), without a page.
|
// 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 target_id = bc.target_id orelse unreachable;
|
||||||
const page = bc.session.currentPage() 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, .{
|
const document_url = try urlToString(arena, &page.url.uri, .{
|
||||||
.scheme = true,
|
.scheme = true,
|
||||||
.authentication = true,
|
.authentication = true,
|
||||||
@@ -80,8 +124,8 @@ pub fn httpRequestStart(arena: Allocator, bc: anytype, request: *const Notificat
|
|||||||
});
|
});
|
||||||
|
|
||||||
var headers: std.StringArrayHashMapUnmanaged([]const u8) = .empty;
|
var headers: std.StringArrayHashMapUnmanaged([]const u8) = .empty;
|
||||||
try headers.ensureTotalCapacity(arena, request.headers.len);
|
try headers.ensureTotalCapacity(arena, request.headers.items.len);
|
||||||
for (request.headers) |header| {
|
for (request.headers.items) |header| {
|
||||||
headers.putAssumeCapacity(header.name, header.value);
|
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
|
// We're missing a bunch of fields, but, for now, this seems like enough
|
||||||
try cdp.sendEvent("Network.responseReceived", .{
|
try cdp.sendEvent("Network.responseReceived", .{
|
||||||
.requestId = try std.fmt.allocPrint(arena, "REQ-{d}", .{request.id}),
|
.requestId = try std.fmt.allocPrint(arena, "REQ-{d}", .{request.id}),
|
||||||
.frameId = target_id,
|
|
||||||
.loaderId = bc.loader_id,
|
.loaderId = bc.loader_id,
|
||||||
.response = .{
|
.response = .{
|
||||||
.url = url,
|
.url = url,
|
||||||
.status = request.status,
|
.status = request.status,
|
||||||
.headers = std.json.ArrayHashMap([]const u8){ .map = headers },
|
.headers = std.json.ArrayHashMap([]const u8){ .map = headers },
|
||||||
},
|
},
|
||||||
|
.frameId = target_id,
|
||||||
}, .{ .session_id = session_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));
|
try url.writeToStream(opts, buf.writer(arena));
|
||||||
return buf.items;
|
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);
|
std.debug.assert(bc.session_id == null);
|
||||||
const session_id = cmd.cdp.session_id_gen.next();
|
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{
|
try cmd.sendEvent("Target.attachedToTarget", AttachToTarget{
|
||||||
.sessionId = session_id,
|
.sessionId = session_id,
|
||||||
.targetInfo = TargetInfo{
|
.targetInfo = TargetInfo{
|
||||||
|
|||||||
@@ -838,10 +838,11 @@ pub const Request = struct {
|
|||||||
}
|
}
|
||||||
self._notified_start = true;
|
self._notified_start = true;
|
||||||
notification.dispatch(.http_request_start, &.{
|
notification.dispatch(.http_request_start, &.{
|
||||||
|
.arena = self.arena,
|
||||||
.id = self.id,
|
.id = self.id,
|
||||||
.url = self.request_uri,
|
.url = self.request_uri,
|
||||||
.method = self.method,
|
.method = self.method,
|
||||||
.headers = self.headers.items,
|
.headers = &self.headers,
|
||||||
.has_body = self.body != null,
|
.has_body = self.body != null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,10 +89,11 @@ pub const Notification = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const RequestStart = struct {
|
pub const RequestStart = struct {
|
||||||
|
arena: Allocator,
|
||||||
id: usize,
|
id: usize,
|
||||||
url: *const std.Uri,
|
url: *const std.Uri,
|
||||||
method: http_client.Request.Method,
|
method: http_client.Request.Method,
|
||||||
headers: []std.http.Header,
|
headers: *std.ArrayListUnmanaged(std.http.Header),
|
||||||
has_body: bool,
|
has_body: bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user