mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-07-30 09:16:07 -04:00
feat(cdp): implement Network.setBlockedURLs via urlPatterns
Reimplement request blocking on the non-deprecated urlPatterns shape: each pattern carries an explicit block/allow flag (first match wins), UrlBlocklist owns the compiled patterns plus their block flags, and the legacy setBlockedUrls path stays for back-compat. Tests updated.
This commit is contained in:
committed by
Pierre Tachoire
parent
311ab3aaae
commit
dee40075a0
@@ -103,11 +103,11 @@ fn setCacheDisabled(cmd: *CDP.Command) !void {
|
||||
|
||||
fn setBlockedURLs(cmd: *CDP.Command) !void {
|
||||
const params = (try cmd.params(struct {
|
||||
urls: []const []const u8,
|
||||
urlPatterns: []const HttpClient.BlockPattern,
|
||||
})) orelse return error.InvalidParams;
|
||||
|
||||
const bc = cmd.browser_context orelse return error.BrowserContextNotLoaded;
|
||||
try bc.cdp.browser.http_client.setBlockedUrls(params.urls);
|
||||
try bc.cdp.browser.http_client.setBlockedUrlPatterns(params.urlPatterns);
|
||||
return cmd.sendResult(null, .{});
|
||||
}
|
||||
|
||||
@@ -1018,7 +1018,9 @@ test "cdp.Network: setBlockedURLs blocks requests with inspector reason" {
|
||||
try ctx.processMessage(.{
|
||||
.id = 2,
|
||||
.method = "Network.setBlockedURLs",
|
||||
.params = .{ .urls = &[_][]const u8{"*://blocked.test/*"} },
|
||||
.params = .{ .urlPatterns = &[_]HttpClient.BlockPattern{
|
||||
.{ .urlPattern = "*://blocked.test/*", .block = true },
|
||||
} },
|
||||
});
|
||||
try ctx.expectSentResult(null, .{ .id = 2 });
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ const Network = @import("Network.zig");
|
||||
const Cache = @import("cache/Cache.zig");
|
||||
const RobotsGate = @import("RobotsGate.zig");
|
||||
const UrlBlocklist = @import("UrlBlocklist.zig");
|
||||
pub const BlockPattern = UrlBlocklist.Pattern;
|
||||
|
||||
const log = lp.log;
|
||||
const Allocator = std.mem.Allocator;
|
||||
@@ -366,6 +367,16 @@ pub fn setBlockedUrls(self: *Client, patterns: []const []const u8) !void {
|
||||
self.url_blocklist = replacement;
|
||||
}
|
||||
|
||||
pub fn setBlockedUrlPatterns(self: *Client, patterns: []const BlockPattern) !void {
|
||||
const replacement: ?UrlBlocklist = if (patterns.len == 0)
|
||||
null
|
||||
else
|
||||
try UrlBlocklist.initPatterns(self.allocator, patterns);
|
||||
|
||||
self.clearUrlBlocklist();
|
||||
self.url_blocklist = replacement;
|
||||
}
|
||||
|
||||
fn clearUrlBlocklist(self: *Client) void {
|
||||
if (self.url_blocklist) |*blocklist| {
|
||||
blocklist.deinit();
|
||||
|
||||
@@ -19,6 +19,12 @@ const UrlBlocklist = @This();
|
||||
|
||||
allocator: std.mem.Allocator,
|
||||
patterns: []const []const u8,
|
||||
blocks: ?[]const bool = null,
|
||||
|
||||
pub const Pattern = struct {
|
||||
urlPattern: []const u8,
|
||||
block: bool,
|
||||
};
|
||||
|
||||
/// Compile and own a set of URL wildcard patterns. Patterns are normalized to
|
||||
/// lowercase once so request matching remains allocation-free.
|
||||
@@ -45,14 +51,28 @@ pub fn init(allocator: std.mem.Allocator, patterns: []const []const u8) !UrlBloc
|
||||
};
|
||||
}
|
||||
|
||||
pub fn initPatterns(allocator: std.mem.Allocator, patterns: []const Pattern) !UrlBlocklist {
|
||||
const urls = try allocator.alloc([]const u8, patterns.len);
|
||||
defer allocator.free(urls);
|
||||
for (patterns, urls) |pattern, *url| url.* = pattern.urlPattern;
|
||||
|
||||
var blocklist = try init(allocator, urls);
|
||||
errdefer blocklist.deinit();
|
||||
const blocks = try allocator.alloc(bool, patterns.len);
|
||||
for (patterns, blocks) |pattern, *block| block.* = pattern.block;
|
||||
blocklist.blocks = blocks;
|
||||
return blocklist;
|
||||
}
|
||||
|
||||
pub fn deinit(self: *UrlBlocklist) void {
|
||||
for (self.patterns) |pattern| self.allocator.free(pattern);
|
||||
self.allocator.free(self.patterns);
|
||||
if (self.blocks) |blocks| self.allocator.free(blocks);
|
||||
}
|
||||
|
||||
pub fn isBlocked(self: *const UrlBlocklist, url: []const u8) bool {
|
||||
for (self.patterns) |pattern| {
|
||||
if (wildcardMatch(pattern, url)) return true;
|
||||
for (self.patterns, 0..) |pattern, index| {
|
||||
if (wildcardMatch(pattern, url)) return if (self.blocks) |blocks| blocks[index] else true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -133,9 +153,9 @@ test "UrlBlocklist: wildcard matching backtracks and handles empty patterns" {
|
||||
|
||||
test "UrlBlocklist: owns compiled patterns" {
|
||||
var pattern = [_]u8{ '*', 'a', 'd', 's', '*' };
|
||||
var blocklist = try UrlBlocklist.init(std.testing.allocator, &.{&pattern});
|
||||
var blocklist = try UrlBlocklist.initPatterns(std.testing.allocator, &.{ .{ .urlPattern = &pattern, .block = false }, .{ .urlPattern = "*", .block = true } });
|
||||
defer blocklist.deinit();
|
||||
|
||||
@memset(&pattern, 'x');
|
||||
try std.testing.expect(blocklist.isBlocked("https://example.com/ads/script.js"));
|
||||
try std.testing.expect(!blocklist.isBlocked("https://example.com/ads/script.js"));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user