Merge pull request #2990 from staylor/scott/http-cache-interception

Add per-CDP control for Network.setCacheDisabled
This commit is contained in:
Pierre Tachoire
2026-07-21 10:06:54 +02:00
committed by GitHub
4 changed files with 88 additions and 20 deletions

View File

@@ -82,6 +82,7 @@ browser_context_id_gen: BrowserContextIdGen = .{},
browser_session_id: ?[]const u8 = null,
browser_context: ?BrowserContext,
disable_set_cache_disabled: bool = false,
// Re-used arena for processing a message. We're assuming that we're getting
// 1 message at a time.

View File

@@ -44,6 +44,7 @@ pub fn processMessage(cmd: *CDP.Command) !void {
scrollNode,
waitForSelector,
handleJavaScriptDialog,
configureCDP,
configureLoading,
version,
}, cmd.input.action) orelse return error.UnknownMethod;
@@ -61,6 +62,7 @@ pub fn processMessage(cmd: *CDP.Command) !void {
.scrollNode => return scrollNode(cmd),
.waitForSelector => return waitForSelector(cmd),
.handleJavaScriptDialog => return handleJavaScriptDialog(cmd),
.configureCDP => return configureCDP(cmd),
.configureLoading => return configureLoading(cmd),
.version => return version(cmd),
}
@@ -72,6 +74,17 @@ fn version(cmd: *CDP.Command) !void {
}, .{});
}
fn configureCDP(cmd: *CDP.Command) !void {
const params = (try cmd.params(struct {
disableSetCacheDisabled: ?bool = null,
})) orelse return error.InvalidParams;
if (params.disableSetCacheDisabled) |value| {
cmd.cdp.disable_set_cache_disabled = value;
}
return cmd.sendResult(null, .{});
}
fn configureLoading(cmd: *CDP.Command) !void {
// Each field is optional so callers can flip one without resetting
// the other to its default. Backwards-compatible: existing callers
@@ -407,6 +420,34 @@ test "cdp.lp: version" {
try testing.expectEqualSlices(u8, lp.build_config.version, result.get("version").?.string);
}
test "cdp.lp: configureCDP toggles setCacheDisabled handling" {
var ctx = try testing.context();
defer ctx.deinit();
try testing.expectEqual(false, ctx.cdp().disable_set_cache_disabled);
try ctx.processMessage(.{ .id = 1, .method = "Target.attachToBrowserTarget" });
try ctx.expectSentResult(.{ .sessionId = "BSID-1" }, .{ .id = 1 });
try ctx.processMessage(.{
.id = 2,
.method = "LP.configureCDP",
.sessionId = "BSID-1",
.params = .{ .disableSetCacheDisabled = true },
});
try ctx.expectSentResult(null, .{ .id = 2, .session_id = "BSID-1" });
try testing.expectEqual(true, ctx.cdp().disable_set_cache_disabled);
try ctx.processMessage(.{
.id = 3,
.method = "LP.configureCDP",
.sessionId = "BSID-1",
.params = .{ .disableSetCacheDisabled = false },
});
try ctx.expectSentResult(null, .{ .id = 3, .session_id = "BSID-1" });
try testing.expectEqual(false, ctx.cdp().disable_set_cache_disabled);
}
test "cdp.lp: getMarkdown" {
var ctx = try testing.context();
defer ctx.deinit();

View File

@@ -28,6 +28,7 @@ const Mime = @import("../../browser/Mime.zig");
const Notification = @import("../../Notification.zig");
const timestamp = @import("../../datetime.zig").timestamp;
const Cache = @import("../../network/cache/Cache.zig");
const Headers = @import("../../network/HttpClient.zig").Headers;
const Transfer = @import("../../network/HttpClient.zig").Transfer;
@@ -91,7 +92,9 @@ fn setCacheDisabled(cmd: *CDP.Command) !void {
const bc = cmd.browser_context orelse return error.BrowserContextNotLoaded;
const client = &bc.cdp.browser.http_client;
client.disableCache(params.cacheDisabled);
if (!bc.cdp.disable_set_cache_disabled) {
client.disableCache(params.cacheDisabled);
}
return cmd.sendResult(null, .{});
}
@@ -940,10 +943,41 @@ test "cdp.Network: setCacheDisabled" {
defer ctx.deinit();
_ = try ctx.loadBrowserContext(.{ .id = "BID-CD1" });
var cache: Cache = undefined;
const client = &ctx.cdp().browser.http_client;
client.cache = &cache;
try ctx.processMessage(.{
.id = 1,
.method = "Network.setCacheDisabled",
.params = .{ .cacheDisabled = true },
});
try ctx.expectSentResult(null, .{ .id = 1 });
try testing.expect(client.cache == null);
}
test "cdp.Network: configured CDP ignores setCacheDisabled" {
var ctx = try testing.context();
defer ctx.deinit();
_ = try ctx.loadBrowserContext(.{ .id = "BID-CD2" });
var cache: Cache = undefined;
const client = &ctx.cdp().browser.http_client;
client.cache = &cache;
defer client.cache = null;
try ctx.processMessage(.{
.id = 1,
.method = "LP.configureCDP",
.params = .{ .disableSetCacheDisabled = true },
});
try ctx.expectSentResult(null, .{ .id = 1 });
try ctx.processMessage(.{
.id = 2,
.method = "Network.setCacheDisabled",
.params = .{ .cacheDisabled = true },
});
try ctx.expectSentResult(null, .{ .id = 2 });
try testing.expect(client.cache == &cache);
}

View File

@@ -252,19 +252,15 @@ fn attachToTarget(cmd: *CDP.Command) !void {
}
fn attachToBrowserTarget(cmd: *CDP.Command) !void {
const bc = cmd.browser_context orelse return error.BrowserContextNotLoaded;
const cdp = cmd.cdp;
// This session targets the browser, not the page. It must not touch
// bc.session_id: a non-null bc.session_id means "attached to the page
// target", and a browser-only attachment would break that invariant
// (e.g. the createTarget assert).
// Browser-target sessions are independent from page-target sessions and
// can be created before a browser context exists.
const session_id = cdp.browser_session_id orelse cdp.browser_session_id_gen.next();
try cmd.sendEvent("Target.attachedToTarget", AttachToTarget{
.sessionId = session_id,
.targetInfo = TargetInfo{
.targetId = bc.id, // We use the browser context is as browser's target id.
.targetId = "browser",
.title = "",
.url = "",
.type = "browser",
@@ -667,21 +663,17 @@ test "cdp.target: attachToBrowserTarget then createTarget" {
var ctx = try testing.context();
defer ctx.deinit();
try ctx.processMessage(.{ .id = 1, .method = "Target.createBrowserContext" });
try ctx.processMessage(.{ .id = 1, .method = "Target.attachToBrowserTarget" });
try ctx.expectSentEvent("Target.attachedToTarget", .{ .sessionId = "BSID-1", .targetInfo = .{ .targetId = "browser", .title = "", .url = "", .attached = true, .type = "browser", .canAccessOpener = false } }, .{});
try ctx.expectSentResult(.{ .sessionId = "BSID-1" }, .{ .id = 1 });
try testing.expectEqual(null, ctx.cdp().browser_context);
try ctx.processMessage(.{ .id = 2, .method = "Target.createBrowserContext" });
const bc = &ctx.cdp().browser_context.?;
try ctx.expectSentResult(.{ .browserContextId = bc.id }, .{ .id = 1 });
try ctx.expectSentResult(.{ .browserContextId = bc.id }, .{ .id = 2 });
try testing.expectEqual(null, bc.session_id);
{
try ctx.processMessage(.{ .id = 2, .method = "Target.attachToBrowserTarget" });
try ctx.expectSentEvent("Target.attachedToTarget", .{ .sessionId = "BSID-1", .targetInfo = .{ .targetId = bc.id, .title = "", .url = "", .attached = true, .type = "browser", .canAccessOpener = false } }, .{});
try ctx.expectSentResult(.{ .sessionId = "BSID-1" }, .{ .id = 2 });
// the browser session must not occupy the page session slot
try testing.expectEqual(null, bc.session_id);
}
{
// this used to fail the "not null session_id" assertion
try ctx.processMessage(.{ .id = 3, .method = "Target.createTarget", .params = .{ .url = "about:blank" } });
try ctx.expectSentResult(.{ .targetId = bc.target_id.? }, .{ .id = 3 });
}