webapi: correct error on wrong method, guard headers

Return TypeError on an invalid method and guard against invalid headers. This
2nd change just uses the guards added in https://github.com/lightpanda-io/browser/pull/3460
from XHR.

Fixes a handful of cases, e.g. /fetch/api/request/forbidden-method.any.html
This commit is contained in:
Karl Seguin committed 2026-09-19 10:02:28 +08:00
1 parent ae928a91b1
commit 7b6bb7b269
4 files changed
+20 -4

No files matched your search

+7
View File
@@ -453,3 +453,10 @@
testing.expectEqual(1024, requests.length);
testing.expectEqual('https://example.com/1023', requests[1023].url);
</script>
<script id=method_errors>
// Forbidden methods and invalid tokens throw a TypeError.
for (const method of ['CONNECT', 'trace', 'TRACK', 'IN VALID']) {
testing.expectError('TypeError', () => new Request('https://example.com/api', { method }));
}
</script>
+9
View File
@@ -575,6 +575,11 @@
req.setRequestHeader('X-Multi', 'b');
req.setRequestHeader('User-Agent', 'Mozilla/5.0 (X11; Linux x86_64)');
req.setRequestHeader('Sec-Ch-Ua', '"Chromium";v="140"');
// forbidden request headers are silently ignored
req.setRequestHeader('Cookie', 'injected=1');
req.setRequestHeader('Proxy-Test', '1');
req.setRequestHeader('Sec-Test', '1');
req.setRequestHeader('X-HTTP-Method-Override', 'TRACE');
req.send();
await state.done(() => {
@@ -589,6 +594,10 @@
testing.expectEqual(false, got['user-agent'].includes('Mozilla'));
testing.expectEqual(true, got['sec-ch-ua'].includes('Lightpanda'));
testing.expectEqual(false, got['sec-ch-ua'].includes('Chromium'));
testing.expectEqual(false, (got['cookie'] ?? '').includes('injected'));
testing.expectEqual(undefined, got['proxy-test']);
testing.expectEqual(undefined, got['sec-test']);
testing.expectEqual(undefined, got['x-http-method-override']);
});
}
</script>
+2 -2
View File
@@ -240,7 +240,7 @@ pub fn acquireRef(self: *Request) void {
fn parseMethod(method: []const u8, exec: *const Execution) !http.Method {
if (method.len > "propfind".len) {
return error.InvalidMethod;
return error.TypeError;
}
const lower = std.ascii.lowerString(exec.buf, method);
@@ -255,7 +255,7 @@ fn parseMethod(method: []const u8, exec: *const Execution) !http.Method {
.{ "options", .OPTIONS },
.{ "propfind", .PROPFIND },
});
return method_lookup.get(lower) orelse return error.InvalidMethod;
return method_lookup.get(lower) orelse return error.TypeError;
}
pub fn getUrl(self: *const Request) []const u8 {
+2 -2
View File
@@ -120,7 +120,7 @@ pub fn init(exec: *const Execution) !*XMLHttpRequest {
._exec = exec,
._arena = arena,
._proto = undefined,
._request_headers = try Headers.init(null, exec),
._request_headers = try Headers.initGuarded(null, .request, exec),
});
return self;
}
@@ -861,7 +861,7 @@ test "parseMethod: accepts known methods case-insensitively" {
}
test "WebApi: XHR" {
testing.expectLog(&.{ .http, .http, .http });
testing.expectLog(&.{ .http, .http });
try testing.htmlRunner("net/xhr.html", .{});
}