mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-09-18 01:34:44 -04:00
fix more WPT test edge cases for preflight cache
This commit is contained in:
2 files changed
+26
-27
No files matched your search
+19
-20
@@ -217,19 +217,17 @@ pub fn check(self: *CorsGate, transfer: *Transfer) !Result {
|
||||
return .allowed;
|
||||
}
|
||||
|
||||
if (try URL.getOrigin(transfer.arena.allocator(), req.url)) |target| {
|
||||
if (self.network.cors_store.get(.{ .origin = origin, .target = target })) |cached| {
|
||||
const authored = try collectAuthoredHeaders(transfer, transfer.arena.allocator());
|
||||
if (CorsStore.covers(cached, req.method, req.credentials_mode == .include, authored.items)) {
|
||||
log.debug(.cors, "cross origin", .{
|
||||
.url = req.url,
|
||||
.origin = origin,
|
||||
.preflight = false,
|
||||
.cached = true,
|
||||
});
|
||||
lp.metrics.cors_check.incr(.cached);
|
||||
return .allowed;
|
||||
}
|
||||
if (self.network.cors_store.get(.{ .origin = origin, .target = req.url })) |cached| {
|
||||
const authored = try collectAuthoredHeaders(transfer, transfer.arena.allocator());
|
||||
if (CorsStore.covers(cached, req.method, req.credentials_mode == .include, authored.items)) {
|
||||
log.debug(.cors, "cross origin", .{
|
||||
.url = req.url,
|
||||
.origin = origin,
|
||||
.preflight = false,
|
||||
.cached = true,
|
||||
});
|
||||
lp.metrics.cors_check.incr(.cached);
|
||||
return .allowed;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -295,7 +293,6 @@ const CorsPreflightContext = struct {
|
||||
key: []const u8,
|
||||
url: [:0]const u8,
|
||||
origin: []const u8,
|
||||
target: []const u8,
|
||||
method: http.Method,
|
||||
request_headers: []const []const u8,
|
||||
wants_credentials: bool,
|
||||
@@ -393,9 +390,13 @@ const CorsPreflightContext = struct {
|
||||
}
|
||||
|
||||
fn cacheGrant(self: *CorsPreflightContext, acam: ?[]const u8, acah: ?[]const u8, acma: ?[]const u8) !void {
|
||||
if (self.target.len == 0) return;
|
||||
if (self.url.len == 0) return;
|
||||
|
||||
const max_age_s: u64 = if (acma) |v| std.fmt.parseUnsigned(u64, v, 10) catch return else return;
|
||||
const max_age_s: u64 = blk: {
|
||||
const v = acma orelse break :blk 5;
|
||||
if (v.len == 0) break :blk 5;
|
||||
break :blk std.fmt.parseUnsigned(u64, v, 10) catch return;
|
||||
};
|
||||
if (max_age_s == 0) return;
|
||||
|
||||
const capped_s: u64 = @min(max_age_s, 7200);
|
||||
@@ -426,14 +427,14 @@ const CorsPreflightContext = struct {
|
||||
}
|
||||
|
||||
try self.gate.network.cors_store.put(
|
||||
.{ .origin = self.origin, .target = self.target },
|
||||
.{ .origin = self.origin, .target = self.url },
|
||||
.{
|
||||
.credentials = self.wants_credentials,
|
||||
.methods_wildcard = methods_wildcard,
|
||||
.methods = methods,
|
||||
.headers_wildcard = headers_wildcard,
|
||||
.headers = owned_headers,
|
||||
.expires_at = lp.datetime.timestamp(.real) + capped_ms,
|
||||
.expires_at = lp.datetime.milliTimestamp(.real) + capped_ms,
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -576,7 +577,6 @@ fn fetchThenResume(self: *CorsGate, transfer: *Transfer) !void {
|
||||
const owned_url = try arena.dupeZ(u8, transfer.req.url);
|
||||
const owned_key = try arena.dupe(u8, key);
|
||||
const owned_origin = try arena.dupe(u8, origin);
|
||||
const owned_target = try URL.getOrigin(arena.allocator(), transfer.req.url) orelse "";
|
||||
|
||||
const owned_header_names = try arena.alloc([]const u8, header_names.items.len);
|
||||
for (header_names.items, 0..) |name, i| {
|
||||
@@ -591,7 +591,6 @@ fn fetchThenResume(self: *CorsGate, transfer: *Transfer) !void {
|
||||
.key = owned_key,
|
||||
.url = owned_url,
|
||||
.origin = owned_origin,
|
||||
.target = owned_target,
|
||||
.method = transfer.req.method,
|
||||
.request_headers = owned_header_names,
|
||||
.wants_credentials = transfer.req.credentials_mode == .include,
|
||||
|
||||
@@ -159,7 +159,7 @@ pub fn get(self: *CorsStore, key: Key) ?Entry {
|
||||
|
||||
const entry = self.map.get(key) orelse return null;
|
||||
|
||||
if (entry.expires_at <= lp.datetime.timestamp(.real)) {
|
||||
if (entry.expires_at <= lp.datetime.milliTimestamp(.real)) {
|
||||
const kv = self.map.fetchRemove(key).?;
|
||||
kv.key.deinit(self.allocator);
|
||||
kv.value.deinit(self.allocator);
|
||||
@@ -250,7 +250,7 @@ test "CorsStore: put then get, miss on different origin/target" {
|
||||
.methods = std.EnumSet(http.Method).initOne(.POST),
|
||||
.headers_wildcard = false,
|
||||
.headers = headers,
|
||||
.expires_at = lp.datetime.timestamp(.real) + 60_000,
|
||||
.expires_at = lp.datetime.milliTimestamp(.real) + 60_000,
|
||||
});
|
||||
|
||||
// store.get returns the store's own copy — not caller-owned, don't free it.
|
||||
@@ -273,7 +273,7 @@ test "CorsStore: expired entries are evicted on get" {
|
||||
.methods = .initEmpty(),
|
||||
.headers_wildcard = true,
|
||||
.headers = &.{}, // empty slice, nothing to free
|
||||
.expires_at = lp.datetime.timestamp(.real) - 1,
|
||||
.expires_at = lp.datetime.milliTimestamp(.real) - 1,
|
||||
});
|
||||
|
||||
try testing.expectEqual(null, store.get(.{ .origin = "https://a.example", .target = "https://api.example" }));
|
||||
@@ -295,7 +295,7 @@ test "CorsStore: put merges into existing entry rather than clobbering" {
|
||||
.methods = std.EnumSet(http.Method).initOne(.POST),
|
||||
.headers_wildcard = false,
|
||||
.headers = h1,
|
||||
.expires_at = lp.datetime.timestamp(.real) + 60_000,
|
||||
.expires_at = lp.datetime.milliTimestamp(.real) + 60_000,
|
||||
});
|
||||
freeHeaders(allocator, h1);
|
||||
|
||||
@@ -307,7 +307,7 @@ test "CorsStore: put merges into existing entry rather than clobbering" {
|
||||
.methods = std.EnumSet(http.Method).initOne(.PUT),
|
||||
.headers_wildcard = false,
|
||||
.headers = h2,
|
||||
.expires_at = lp.datetime.timestamp(.real) + 60_000,
|
||||
.expires_at = lp.datetime.milliTimestamp(.real) + 60_000,
|
||||
});
|
||||
freeHeaders(allocator, h2);
|
||||
|
||||
@@ -328,7 +328,7 @@ test "CorsStore: covers rejects credentialed request against uncredentialed wild
|
||||
.methods = .initEmpty(),
|
||||
.headers_wildcard = true,
|
||||
.headers = &.{},
|
||||
.expires_at = std.math.maxInt(i64),
|
||||
.expires_at = std.math.maxInt(u64),
|
||||
};
|
||||
try testing.expect(!CorsStore.covers(entry, .GET, true, &.{}));
|
||||
try testing.expect(CorsStore.covers(entry, .GET, false, &.{}));
|
||||
@@ -341,7 +341,7 @@ test "CorsStore: covers never lets a wildcard cover Authorization" {
|
||||
.methods = .initEmpty(),
|
||||
.headers_wildcard = true,
|
||||
.headers = &.{},
|
||||
.expires_at = std.math.maxInt(i64),
|
||||
.expires_at = std.math.maxInt(u64),
|
||||
};
|
||||
try testing.expect(!CorsStore.covers(entry, .GET, false, &.{"authorization"}));
|
||||
try testing.expect(CorsStore.covers(entry, .GET, false, &.{"x-anything"}));
|
||||
|
||||
Reference in new issue
Block a user