http: inherit request URL fragment across fragment-less redirect

Per RFC 7231 §7.1.2, when a 3xx response carries a Location header
without a fragment, the user agent must process the redirect as if
the value inherited the fragment of the request URL. URL.resolve
follows RFC 3986 §5.3 which drops the base fragment, so handleRedirect
now reattaches the original fragment when the resolved target has none.

Closes #2263
This commit is contained in:
Navid EMAD
2026-04-27 08:04:47 +02:00
parent 9fbade4573
commit 00c42dec4e
3 changed files with 93 additions and 1 deletions

View File

@@ -610,6 +610,32 @@ fn testHTTPHandler(req: *std.http.Server.Request) !void {
});
}
if (std.mem.eql(u8, path, "/redirect-no-fragment")) {
return req.respond("", .{
.status = .found,
.extra_headers = &.{
.{ .name = "Location", .value = "/redirect-target" },
},
});
}
if (std.mem.eql(u8, path, "/redirect-target")) {
return req.respond("<!DOCTYPE html><title>landed</title>", .{
.extra_headers = &.{
.{ .name = "Content-Type", .value = "text/html; charset=utf-8" },
},
});
}
if (std.mem.eql(u8, path, "/redirect-with-fragment")) {
return req.respond("", .{
.status = .found,
.extra_headers = &.{
.{ .name = "Location", .value = "/redirect-target#target_fragment" },
},
});
}
if (std.mem.eql(u8, path, "/xhr/404")) {
return req.respond("Not Found", .{
.status = .not_found,