mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-09-22 12:35:22 -04:00
add basic CorsGate scaffold
This commit is contained in:
3 files changed
+158
-4
No files matched your search
@@ -35,6 +35,7 @@ const http = @import("http.zig");
|
||||
const Network = @import("Network.zig");
|
||||
const Cache = @import("cache/Cache.zig");
|
||||
const RobotsGate = @import("RobotsGate.zig");
|
||||
const CorsGate = @import("CorsGate.zig");
|
||||
const UrlBlocklist = @import("UrlBlocklist.zig");
|
||||
|
||||
pub const BlockPattern = UrlBlocklist.Pattern;
|
||||
@@ -187,6 +188,7 @@ obey_robots: bool,
|
||||
http_version: lp.Config.HttpVersion,
|
||||
|
||||
robots: RobotsGate,
|
||||
cors: CorsGate,
|
||||
url_blocklist: ?UrlBlocklist,
|
||||
|
||||
pub fn init(self: *Client, app: *lp.App) !void {
|
||||
@@ -233,6 +235,10 @@ pub fn init(self: *Client, app: *lp.App) !void {
|
||||
.network = network,
|
||||
.single_flight = .init(allocator),
|
||||
},
|
||||
.cors = .{
|
||||
.network = network,
|
||||
.single_flight = .init(allocator),
|
||||
},
|
||||
.url_blocklist = url_blocklist,
|
||||
.arena_pool = &app.arena_pool,
|
||||
};
|
||||
@@ -264,6 +270,7 @@ pub fn deinit(self: *Client) void {
|
||||
|
||||
self.clearUrlBlocklist();
|
||||
self.robots.deinit();
|
||||
self.cors.deinit();
|
||||
self.blocking_requests.deinit(self.allocator);
|
||||
self.transfers.deinit(self.allocator);
|
||||
self.cache.maintenance(lp.datetime.timestamp(.real));
|
||||
@@ -461,6 +468,7 @@ pub fn abort(self: *Client) void {
|
||||
// - self.robots.pending : each robots fetch's shutdown_callback
|
||||
// drops its entry; parked waiters unlink in their own deinit.
|
||||
std.debug.assert(self.robots.single_flight.count() == 0);
|
||||
std.debug.assert(self.cors.single_flight.count() == 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -962,6 +970,7 @@ const SubmitFrom = enum {
|
||||
start, // Transfer.submit — a brand new request.
|
||||
redirect, // Followed 3xx. Same as .start, but a distinct name (e.g. for CDP)
|
||||
after_intercept, // Released by CDP
|
||||
after_cors, // cors allowed the request.
|
||||
throttle, // the robots gate allowed the request.
|
||||
network, // released by throttle
|
||||
};
|
||||
@@ -1015,9 +1024,18 @@ fn pipeline(self: *Client, transfer: *Transfer, from: SubmitFrom) !void {
|
||||
return transfer.failAsync(error.UrlBlocked);
|
||||
}
|
||||
if (try self.cacheLookup(transfer)) {
|
||||
// response came from the cache, we're done
|
||||
return;
|
||||
}
|
||||
if (!transfer.req.internal) {
|
||||
switch (try self.cors.check(transfer)) {
|
||||
.allowed => {},
|
||||
.blocked => return transfer.failAsync(error.CorsBlocked),
|
||||
.pending => return,
|
||||
}
|
||||
}
|
||||
continue :sw SubmitFrom.after_cors;
|
||||
},
|
||||
.after_cors => {
|
||||
if (self.obey_robots and !transfer.req.internal) {
|
||||
switch (try self.robots.check(transfer)) {
|
||||
.allowed => {
|
||||
@@ -1059,6 +1077,12 @@ pub fn resumeAfterRobots(self: *Client, transfer: *Transfer) !void {
|
||||
return self.pipeline(transfer, .throttle);
|
||||
}
|
||||
|
||||
// CorsGate resumption after a preflight resolves as allowed. Re-enters
|
||||
// right after the CORS step (not .after_intercept)
|
||||
pub fn resumeAfterCors(self: *Client, transfer: *Transfer) !void {
|
||||
return self.pipeline(transfer, .after_cors);
|
||||
}
|
||||
|
||||
fn findHeader(headers: []const http.Header, name: []const u8) ?[]const u8 {
|
||||
for (headers) |hdr| {
|
||||
if (std.ascii.eqlIgnoreCase(hdr.name, name)) {
|
||||
@@ -2162,6 +2186,8 @@ pub const Transfer = struct {
|
||||
// everything and sits on client.graveyard
|
||||
_retired: bool = false,
|
||||
|
||||
_cors_cross_origin: bool = false,
|
||||
|
||||
pub const State = union(enum) {
|
||||
// Pre-commit. Only valid inside the request flow (Client.request
|
||||
// or a re-entry like continueTransfer / unpark) before any commit
|
||||
@@ -2214,6 +2240,9 @@ pub const Transfer = struct {
|
||||
|
||||
// RobotsGate holds the transfer pending a robots.txt fetch.
|
||||
robots,
|
||||
|
||||
// CorsGate holds the tranfer pending a CORS preflight.
|
||||
cors,
|
||||
};
|
||||
|
||||
pub const HeaderResult = enum {
|
||||
@@ -2249,7 +2278,7 @@ pub const Transfer = struct {
|
||||
return;
|
||||
}
|
||||
switch (self.state.parked) {
|
||||
.robots => {},
|
||||
.robots, .cors => {},
|
||||
.intercept_request, .intercept_auth => {
|
||||
lp.assert(self.client.intercepted > 0, "Transfer.leaveIntercept", .{ .value = self.client.intercepted });
|
||||
self.client.intercepted -= 1;
|
||||
@@ -2388,8 +2417,12 @@ pub const Transfer = struct {
|
||||
|
||||
// And for the robots gate: RobotsGate.pending holds a raw *Transfer
|
||||
// while we're parked.
|
||||
if (self.state == .parked and self.state.parked == .robots) {
|
||||
self.client.robots.remove(self);
|
||||
if (self.state == .parked) {
|
||||
switch (self.state.parked) {
|
||||
.cors => self.client.cors.remove(self),
|
||||
.robots => self.client.robots.remove(self),
|
||||
.intercept_auth, .intercept_request => {},
|
||||
}
|
||||
}
|
||||
|
||||
// A pending revalidation entry owns cache resources (possibly an
|
||||
|
||||
Reference in new issue
Block a user