diff --git a/src/browser/URL.zig b/src/browser/URL.zig index f2650164..9a87b8ed 100644 --- a/src/browser/URL.zig +++ b/src/browser/URL.zig @@ -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", diff --git a/src/browser/tests/net/fetch_hash_route.html b/src/browser/tests/net/fetch_hash_route.html new file mode 100644 index 00000000..8a794550 --- /dev/null +++ b/src/browser/tests/net/fetch_hash_route.html @@ -0,0 +1,28 @@ + + + + diff --git a/src/browser/webapi/net/Fetch.zig b/src/browser/webapi/net/Fetch.zig index 1f69ef0e..74b3351c 100644 --- a/src/browser/webapi/net/Fetch.zig +++ b/src/browser/webapi/net/Fetch.zig @@ -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", .{}); }