diff --git a/src/runtime/loop.zig b/src/runtime/loop.zig index 6e022e44..64e3898f 100644 --- a/src/runtime/loop.zig +++ b/src/runtime/loop.zig @@ -187,6 +187,12 @@ pub const Loop = struct { } pub fn timeout(self: *Self, nanoseconds: u63, callback_node: ?*CallbackNode) !usize { + if (self.stopping) { + // Prevents a timeout callback from creating a new timeout, which + // would make `loop.run` run forever. + return 0; + } + const completion = try self.alloc.create(Completion); errdefer self.alloc.destroy(completion); completion.* = undefined; diff --git a/src/url.zig b/src/url.zig index 6244bf59..fa2dad8a 100644 --- a/src/url.zig +++ b/src/url.zig @@ -110,7 +110,13 @@ pub const URL = struct { } return src; } - if (src.len == 0) { + + var normalized_src = if (std.mem.startsWith(u8, src, "/")) src[1..] else src; + while (std.mem.startsWith(u8, normalized_src, "./")) { + normalized_src = normalized_src[2..]; + } + + if (normalized_src.len == 0) { if (opts.alloc == .always) { return allocator.dupe(u8, base); } @@ -125,8 +131,6 @@ pub const URL = struct { } }; - const normalized_src = if (src[0] == '/') src[1..] else src; - if (std.mem.lastIndexOfScalar(u8, base[protocol_end..], '/')) |index| { const last_slash_pos = index + protocol_end; if (last_slash_pos == base.len - 1) { @@ -216,41 +220,41 @@ test "URL: resolve size" { test "URL: Stitching Base & Src URLs (Basic)" { const allocator = testing.allocator; - const base = "https://www.google.com/xyz/abc/123"; + const base = "https://lightpanda.io/xyz/abc/123"; const src = "something.js"; const result = try URL.stitch(allocator, src, base, .{}); defer allocator.free(result); - try testing.expectString("https://www.google.com/xyz/abc/something.js", result); + try testing.expectString("https://lightpanda.io/xyz/abc/something.js", result); } test "URL: Stitching Base & Src URLs (Just Ending Slash)" { const allocator = testing.allocator; - const base = "https://www.google.com/"; + const base = "https://lightpanda.io/"; const src = "something.js"; const result = try URL.stitch(allocator, src, base, .{}); defer allocator.free(result); - try testing.expectString("https://www.google.com/something.js", result); + try testing.expectString("https://lightpanda.io/something.js", result); } test "URL: Stitching Base & Src URLs with leading slash" { const allocator = testing.allocator; - const base = "https://www.google.com/"; + const base = "https://lightpanda.io/"; const src = "/something.js"; const result = try URL.stitch(allocator, src, base, .{}); defer allocator.free(result); - try testing.expectString("https://www.google.com/something.js", result); + try testing.expectString("https://lightpanda.io/something.js", result); } test "URL: Stitching Base & Src URLs (No Ending Slash)" { const allocator = testing.allocator; - const base = "https://www.google.com"; + const base = "https://lightpanda.io"; const src = "something.js"; const result = try URL.stitch(allocator, src, base, .{}); defer allocator.free(result); - try testing.expectString("https://www.google.com/something.js", result); + try testing.expectString("https://lightpanda.io/something.js", result); } test "URL: Stiching Base & Src URLs (Both Local)" { @@ -275,11 +279,21 @@ test "URL: Stiching src as full path" { test "URL: Stitching Base & Src URLs (empty src)" { const allocator = testing.allocator; - const base = "https://www.google.com/xyz/abc/123"; + const base = "https://lightpanda.io/xyz/abc/123"; const src = ""; const result = try URL.stitch(allocator, src, base, .{}); defer allocator.free(result); - try testing.expectString("https://www.google.com/xyz/abc/123", result); + try testing.expectString("https://lightpanda.io/xyz/abc/123", result); +} + +test "URL: Stitching dotslash" { + const allocator = testing.allocator; + + const base = "https://lightpanda.io/hello/"; + const src = "./something.js"; + const result = try URL.stitch(allocator, src, base, .{}); + defer allocator.free(result); + try testing.expectString("https://lightpanda.io/hello/something.js", result); } test "URL: concatQueryString" {