Skip to content

Commit

Permalink
Merge branch 'srv'
Browse files Browse the repository at this point in the history
  • Loading branch information
ringtailsoftware committed Nov 30, 2024
2 parents 3dd5b0f + 1f895c3 commit 87b0e0d
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 10 deletions.
6 changes: 0 additions & 6 deletions Dockerfile

This file was deleted.

3 changes: 0 additions & 3 deletions Makefile

This file was deleted.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Terminal version:

Web version:

zig build -Dweb=true && make
zig build -Dweb=true && zig build serve -- zig-out -p 8000

Browse to http://localhost:8000

Expand Down
20 changes: 20 additions & 0 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,24 @@ pub fn build(b: *std.Build) void {
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);


// web server
const serve_exe = b.addExecutable(.{
.name = "serve",
.root_source_file = b.path("serve.zig"),
.target = stdTarget,
.optimize = optimize,
});
const StaticHttpFileServer = b.dependency("StaticHttpFileServer", .{
.target = stdTarget,
.optimize = optimize,
});

serve_exe.root_module.addImport("StaticHttpFileServer", StaticHttpFileServer.module("StaticHttpFileServer"));
const run_serve_exe = b.addRunArtifact(serve_exe);
if (b.args) |args| run_serve_exe.addArgs(args);

const serve_step = b.step("serve", "Serve a directory of files");
serve_step.dependOn(&run_serve_exe.step);

}
8 changes: 8 additions & 0 deletions build.zig.zon
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@
.url = "git+https://github.com/prajwalch/yazap#c2e3122d5dd6192513ba590f229dbc535110efb8",
.hash = "122054439ec36ac10987c87ae69f3b041b40b2e451af3fe3ef1fc578b3bad756a800",
},
.StaticHttpFileServer = .{
.url = "git+https://github.com/andrewrk/StaticHttpFileServer.git#b65e1a27c9b2d4bb892e5ffd1a76715d6c0557ab",
.hash = "1220db11bb50364857ec6047cfcdf0938dea6af3f24d360c6b6a6103364c8e353679",
},
.mime = .{
.url = "https://github.com/andrewrk/mime/archive/refs/tags/2.0.1.tar.gz",
.hash = "12209083b0c43d0f68a26a48a7b26ad9f93b22c9cff710c78ddfebb47b89cfb9c7a4",
},
},
.paths = .{
"build.zig",
Expand Down
83 changes: 83 additions & 0 deletions serve.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
const std = @import("std");
const StaticHttpFileServer = @import("StaticHttpFileServer");

var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{}){};

pub fn main() !void {
var arena_state = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena_state.deinit();
const arena = arena_state.allocator();
const gpa = general_purpose_allocator.allocator();

const args = try std.process.argsAlloc(arena);

var listen_port: u16 = 0;
var opt_root_dir_path: ?[]const u8 = null;

{
var i: usize = 1;
while (i < args.len) : (i += 1) {
const arg = args[i];
if (std.mem.startsWith(u8, arg, "-")) {
if (std.mem.eql(u8, arg, "-p")) {
i += 1;
if (i >= args.len) fatal("expected arg after '{s}'", .{arg});
listen_port = std.fmt.parseInt(u16, args[i], 10) catch |err| {
fatal("unable to parse port '{s}': {s}", .{ args[i], @errorName(err) });
};
} else {
fatal("unrecognized argument: '{s}'", .{arg});
}
} else if (opt_root_dir_path == null) {
opt_root_dir_path = arg;
} else {
fatal("unexpected positional argument: '{s}'", .{arg});
}
}
}

const root_dir_path = opt_root_dir_path orelse fatal("missing root dir path", .{});

var root_dir = std.fs.cwd().openDir(root_dir_path, .{ .iterate = true }) catch |err|
fatal("unable to open directory '{s}': {s}", .{ root_dir_path, @errorName(err) });
defer root_dir.close();

const aliases:[2]StaticHttpFileServer.Options.Alias = .{
.{ .request_path = "/", .file_path = "/index.html" },
.{ .request_path = "404", .file_path = "/index.html" },
};

var static_http_file_server = try StaticHttpFileServer.init(.{
.allocator = gpa,
.root_dir = root_dir,
.aliases = &aliases,
});
defer static_http_file_server.deinit(gpa);

const address = try std.net.Address.parseIp("127.0.0.1", listen_port);
var http_server = try address.listen(.{
.reuse_address = true,
});
const port = http_server.listen_address.in.getPort();
std.debug.print("Listening at http://127.0.0.1:{d}/\n", .{port});

var read_buffer: [8000]u8 = undefined;
accept: while (true) {
const connection = try http_server.accept();
defer connection.stream.close();

var server = std.http.Server.init(connection, &read_buffer);
while (server.state == .ready) {
var request = server.receiveHead() catch |err| {
std.debug.print("error: {s}\n", .{@errorName(err)});
continue :accept;
};
try static_http_file_server.serve(&request);
}
}
}

fn fatal(comptime format: []const u8, args: anytype) noreturn {
std.debug.print(format ++ "\n", args);
std.process.exit(1);
}

0 comments on commit 87b0e0d

Please sign in to comment.