aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cli/bun_command.zig2
-rw-r--r--src/http.zig37
-rw-r--r--src/http/url_path.zig6
3 files changed, 39 insertions, 6 deletions
diff --git a/src/cli/bun_command.zig b/src/cli/bun_command.zig
index 454a9bf61..5807a5858 100644
--- a/src/cli/bun_command.zig
+++ b/src/cli/bun_command.zig
@@ -123,7 +123,7 @@ pub const BunCommand = struct {
};
if (ctx.debug.macros) |macros| {
- this_bundler.macro_context.?.remap = macros;
+ this_bundler.options.macro_remap = macros;
}
var loaded_route_config: ?Api.LoadedRouteConfig = brk: {
diff --git a/src/http.zig b/src/http.zig
index dacde86fb..491657811 100644
--- a/src/http.zig
+++ b/src/http.zig
@@ -662,12 +662,22 @@ pub const RequestContext = struct {
return ctx;
}
- pub inline fn isBrowserNavigation(req: *RequestContext) bool {
+ // not all browsers send this
+ pub const BrowserNavigation = enum {
+ yes,
+ no,
+ maybe,
+ };
+
+ pub inline fn isBrowserNavigation(req: *RequestContext) BrowserNavigation {
if (req.header("Sec-Fetch-Mode")) |mode| {
- return strings.eqlComptime(mode, "navigate");
+ return switch (strings.eqlComptime(mode, "navigate")) {
+ true => BrowserNavigation.yes,
+ false => BrowserNavigation.no,
+ };
}
- return false;
+ return .maybe;
}
pub fn sendNotFound(req: *RequestContext) !void {
@@ -3085,6 +3095,7 @@ pub const Server = struct {
pub const ConnectionFeatures = struct {
public_folder: PublicFolderPriority = PublicFolderPriority.none,
filesystem_router: bool = false,
+ single_page_app_routing: bool = false,
pub const PublicFolderPriority = enum {
none,
first,
@@ -3132,7 +3143,7 @@ pub const Server = struct {
req_ctx.timer.reset();
const is_navigation_request = req_ctx_.isBrowserNavigation();
- defer if (is_navigation_request) Analytics.enqueue(Analytics.EventName.http_build);
+ defer if (is_navigation_request == .yes) Analytics.enqueue(Analytics.EventName.http_build);
req_ctx.parseOrigin();
if (req_ctx.url.needs_redirect) {
@@ -3248,6 +3259,17 @@ pub const Server = struct {
finished = finished or req_ctx.has_called_done;
}
},
+ .none => {
+ if (comptime features.single_page_app_routing) {
+ if (req_ctx.url.isRoot(server.bundler.options.routes.asset_prefix_path)) {
+ req_ctx.sendSinglePageHTML() catch |err| {
+ Output.printErrorln("FAIL [{s}] - {s}: {s}", .{ @errorName(err), req.method, req.path });
+ did_print = true;
+ };
+ finished = true;
+ }
+ }
+ },
else => {},
}
}
@@ -3300,7 +3322,7 @@ pub const Server = struct {
}
}
- if (comptime features.public_folder != .none) {
+ if (comptime features.single_page_app_routing or features.public_folder != .none) {
if (!finished and (req_ctx.bundler.options.routes.single_page_app_routing and req_ctx.url.extname.len == 0)) {
req_ctx.sendSinglePageHTML() catch |err| {
Output.printErrorln("FAIL [{s}] - {s}: {s}", .{ @errorName(err), req.method, req.path });
@@ -3449,6 +3471,11 @@ pub const Server = struct {
);
}
} else if (server.bundler.options.routes.single_page_app_routing) {
+ try server.run(
+ ConnectionFeatures{
+ .single_page_app_routing = true,
+ },
+ );
} else {
try server.run(
ConnectionFeatures{ .filesystem_router = false },
diff --git a/src/http/url_path.zig b/src/http/url_path.zig
index f2c558517..e3e90a60f 100644
--- a/src/http/url_path.zig
+++ b/src/http/url_path.zig
@@ -22,6 +22,12 @@ first_segment: string = "",
query_string: string = "",
needs_redirect: bool = false,
+pub fn isRoot(this: *const URLPath, asset_prefix: string) bool {
+ const without = this.pathWithoutAssetPrefix(asset_prefix);
+ if (without.len == 1 and without[0] == '.') return true;
+ return strings.eqlComptime(without, "index");
+}
+
// TODO: use a real URL parser
// this treats a URL like /_next/ identically to /
pub fn pathWithoutAssetPrefix(this: *const URLPath, asset_prefix: string) string {