Skip to content

Commit

Permalink
build(wasm): embed HTML files in the builder
Browse files Browse the repository at this point in the history
The `prefix` path had stopped working following the latest Zig update,
which means an alternative had to be found that doesn't depend on
`@src().file` (which now only returns paths relative to the module
root). For now, the best solution I've found is to embed the files in
the WebServerStep.
  • Loading branch information
zenith391 committed Nov 10, 2024
1 parent 3d4efcc commit 5d46749
Showing 1 changed file with 26 additions and 14 deletions.
40 changes: 26 additions & 14 deletions build_capy.zig
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ const WebServerStep = struct {

fn handler(self: *WebServerStep, build: *std.Build, res: *Server) !void {
const allocator = build.allocator;
const prefix = (comptime std.fs.path.dirname(@src().file) orelse "./") ++ std.fs.path.sep_str;

var req = try res.receiveHead();
var arena = std.heap.ArenaAllocator.init(allocator);
Expand All @@ -100,10 +99,17 @@ const WebServerStep = struct {

const path = req.head.target;
var file_path: []const u8 = "";
var file_content: ?[]const u8 = null;
var content_type: []const u8 = "text/html";
if (std.mem.eql(u8, path, "/")) {
file_path = try std.fs.path.join(req_allocator, &.{ prefix, "src/backends/wasm/index.html" });
file_content = @embedFile("src/backends/wasm/index.html");
content_type = "text/html";
} else if (std.mem.eql(u8, path, "/capy.js")) {
file_content = @embedFile("src/backends/wasm/capy.js");
content_type = "application/javascript";
} else if (std.mem.eql(u8, path, "/capy-worker.js")) {
file_content = @embedFile("src/backends/wasm/capy-worker.js");
content_type = "application/javascript";
} else if (std.mem.eql(u8, path, "/zig-app.wasm")) {
file_path = self.exe.getEmittedBin().getPath2(build, &self.step);
content_type = "application/wasm";
Expand All @@ -113,28 +119,34 @@ const WebServerStep = struct {
content_type = "application/javascript";
}
} else {
file_path = try std.fs.path.join(req_allocator, &.{ prefix, "src/backends/wasm", path });
// else try the HTML files supplied by the application (in the 'html' project relative
// to the project root)
file_path = try std.fs.path.join(req_allocator, &.{ "html", path });
content_type = "application/javascript";
}

if (self.options.wasm_debug_requests) {
std.log.debug("{s} -> {s}", .{ path, file_path });
}
const file: ?std.fs.File = std.fs.cwd().openFile(file_path, .{ .mode = .read_only }) catch |err| blk: {
switch (err) {
error.FileNotFound => break :blk null,
else => return err,
}
};

var status: std.http.Status = .ok;
const content = blk: {
if (file) |f| {
defer f.close();
break :blk try f.readToEndAlloc(req_allocator, std.math.maxInt(usize));
if (file_content) |presupplied_content| {
break :blk presupplied_content;
} else {
status = .not_found;
break :blk "404 Not Found";
const file: ?std.fs.File = std.fs.cwd().openFile(file_path, .{ .mode = .read_only }) catch |err| blk2: {
switch (err) {
error.FileNotFound => break :blk2 null,
else => return err,
}
};
if (file) |f| {
defer f.close();
break :blk try f.readToEndAlloc(req_allocator, std.math.maxInt(usize));
} else {
status = .not_found;
break :blk "404 Not Found";
}
}
};

Expand Down

0 comments on commit 5d46749

Please sign in to comment.