mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-06-11 09:35:59 -04:00
Merge pull request #2583 from jschaf/codex/fix-relative-url-fragment
browser/URL: ignore query and fragment slashes in URL resolve
This commit is contained in:
@@ -121,7 +121,8 @@ pub fn resolve(allocator: Allocator, base: [:0]const u8, source_path: anytype, o
|
||||
|
||||
const scheme_end = std.mem.indexOf(u8, base, "://");
|
||||
const authority_start = if (scheme_end) |end| end + 3 else 0;
|
||||
const path_start = std.mem.indexOfScalarPos(u8, base, authority_start, '/') orelse base.len;
|
||||
const path_start = std.mem.indexOfAnyPos(u8, base, authority_start, "/?#") orelse base.len;
|
||||
const path_end = std.mem.indexOfAnyPos(u8, base, path_start, "?#") orelse base.len;
|
||||
|
||||
if (path[0] == '/') {
|
||||
const result = try std.mem.joinZ(allocator, "", &.{ base[0..path_start], path });
|
||||
@@ -129,8 +130,8 @@ pub fn resolve(allocator: Allocator, base: [:0]const u8, source_path: anytype, o
|
||||
}
|
||||
|
||||
var normalized_base: []const u8 = base[0..path_start];
|
||||
if (path_start < base.len) {
|
||||
if (std.mem.lastIndexOfScalar(u8, base[path_start + 1 ..], '/')) |pos| {
|
||||
if (path_start < path_end) {
|
||||
if (std.mem.lastIndexOfScalar(u8, base[path_start + 1 .. path_end], '/')) |pos| {
|
||||
normalized_base = base[0 .. path_start + 1 + pos];
|
||||
}
|
||||
}
|
||||
@@ -973,6 +974,66 @@ test "URL: resolve" {
|
||||
.path = "something.js",
|
||||
.expected = "https://example/xyz/abc/something.js",
|
||||
},
|
||||
.{
|
||||
.base = "http://127.0.0.1:8123/#/login",
|
||||
.path = "api/users/login",
|
||||
.expected = "http://127.0.0.1:8123/api/users/login",
|
||||
},
|
||||
.{
|
||||
.base = "https://example/app/page?next=/foo/bar",
|
||||
.path = "api/users/login",
|
||||
.expected = "https://example/app/api/users/login",
|
||||
},
|
||||
.{
|
||||
.base = "https://example/app/page#/foo/bar",
|
||||
.path = "api/users/login",
|
||||
.expected = "https://example/app/api/users/login",
|
||||
},
|
||||
.{
|
||||
.base = "https://example?next=/foo/bar",
|
||||
.path = "api/users/login",
|
||||
.expected = "https://example/api/users/login",
|
||||
},
|
||||
.{
|
||||
.base = "https://example#/foo/bar",
|
||||
.path = "api/users/login",
|
||||
.expected = "https://example/api/users/login",
|
||||
},
|
||||
.{
|
||||
.base = "https://example?next=/foo/bar",
|
||||
.path = "/api/users/login",
|
||||
.expected = "https://example/api/users/login",
|
||||
},
|
||||
.{
|
||||
.base = "https://example/app/page?next=/foo/bar",
|
||||
.path = "../api/users/login",
|
||||
.expected = "https://example/api/users/login",
|
||||
},
|
||||
.{
|
||||
.base = "https://example/app/page#/foo/bar",
|
||||
.path = "../api/users/login",
|
||||
.expected = "https://example/api/users/login",
|
||||
},
|
||||
.{
|
||||
.base = "https://example/app/dir/?next=/foo/bar",
|
||||
.path = "../api/users/login",
|
||||
.expected = "https://example/app/api/users/login",
|
||||
},
|
||||
.{
|
||||
.base = "https://example/app/dir/#/foo/bar",
|
||||
.path = "../api/users/login",
|
||||
.expected = "https://example/app/api/users/login",
|
||||
},
|
||||
.{
|
||||
.base = "https://example/app/page?next=/foo/bar",
|
||||
.path = "?q=/api/users/login",
|
||||
.expected = "https://example/app/page?q=/api/users/login",
|
||||
},
|
||||
.{
|
||||
.base = "https://example/app/page#/foo/bar",
|
||||
.path = "#/api/users/login",
|
||||
.expected = "https://example/app/page#/api/users/login",
|
||||
},
|
||||
.{
|
||||
.base = "https://example/xyz/abc/123",
|
||||
.path = "/something.js",
|
||||
|
||||
28
src/browser/tests/net/fetch_hash_route.html
Normal file
28
src/browser/tests/net/fetch_hash_route.html
Normal file
@@ -0,0 +1,28 @@
|
||||
<!DOCTYPE html>
|
||||
<script src="../testing.js"></script>
|
||||
|
||||
<script id=fetch_relative_url_ignores_hash_route type=module>
|
||||
{
|
||||
const state = await testing.async();
|
||||
const originalUrl = location.href;
|
||||
|
||||
history.replaceState(null, '', '/#/login');
|
||||
const response = await fetch('xhr', { method: 'POST', body: 'foo' });
|
||||
const text = await response.text();
|
||||
|
||||
history.replaceState(null, '', originalUrl);
|
||||
state.resolve({
|
||||
ok: response.ok,
|
||||
status: response.status,
|
||||
url: response.url,
|
||||
length: text.length,
|
||||
});
|
||||
|
||||
await state.done((data) => {
|
||||
testing.expectEqual(true, data.ok);
|
||||
testing.expectEqual(200, data.status);
|
||||
testing.expectEqual('http://127.0.0.1:9582/xhr', data.url);
|
||||
testing.expectEqual(100, data.length);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
@@ -270,4 +270,5 @@ fn httpShutdownCallback(ctx: *anyopaque) void {
|
||||
const testing = @import("../../../testing.zig");
|
||||
test "WebApi: fetch" {
|
||||
try testing.htmlRunner("net/fetch.html", .{});
|
||||
try testing.htmlRunner("net/fetch_hash_route.html", .{});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user