From 95699a6ed77e1480e7b9256035225981cb33bfbb Mon Sep 17 00:00:00 2001 From: Martin Ashby Date: Sun, 6 Aug 2023 06:59:44 +0100 Subject: Add path parsing, use it --- src/main.zig | 89 ++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 48 insertions(+), 41 deletions(-) (limited to 'src/main.zig') diff --git a/src/main.zig b/src/main.zig index 54e6b4b..1f4d8f9 100644 --- a/src/main.zig +++ b/src/main.zig @@ -2,65 +2,72 @@ const std = @import("std"); const zws = @import("zigwebserver.zig"); // extremely basic http file server -pub fn main() !void { - var allocator = std.heap.GeneralPurposeAllocator(.{}){}; - defer _ = allocator.deinit(); - const alloc = allocator.allocator(); - var svr = std.http.Server.init(alloc, .{ .reuse_address = true }); - defer svr.deinit(); - const addr = try std.net.Address.resolveIp("127.0.0.1", 8080); - - try svr.listen(addr); - while (true) { - var res = try svr.accept(.{ .allocator = alloc }); - defer res.deinit(); - try res.wait(); - const target = res.request.target; - const path = try std.fs.path.join(alloc, &[_][]const u8{ ".", target }); - defer alloc.free(path); +const Context = struct { + pub fn clone(_: Context) Context { + return .{}; + } + pub fn deinit(_: Context) void {} +}; +const Handler = struct { + pub fn handle(_: Handler, res: *std.http.Server.Response, _: Context) !void { + const p = try zws.Path.parse(res.request.target); + const path = try std.fs.path.join(res.allocator, &[_][]const u8{ ".", p.path }); + defer res.allocator.free(path); if (std.fs.cwd().openFile(path, .{})) |file| { const md = try file.metadata(); if (md.kind() == .directory) { - const index_path = try std.fs.path.join(alloc, &[_][]const u8{ path, "index.html" }); - defer alloc.free(index_path); + const index_path = try std.fs.path.join(res.allocator, &[_][]const u8{ path, "index.html" }); + defer res.allocator.free(index_path); if (std.fs.cwd().openFile(index_path, .{})) |index_file| { const index_md = try index_file.metadata(); - try serve_file(&res, index_file, index_md); + try serve_file(res, index_file, index_md); } else |_| { - try serve_error(&res, .not_found); + try serve_error(res, .not_found); } } else { - try serve_file(&res, file, md); + try serve_file(res, file, md); } } else |err| { switch (err) { - error.FileNotFound => try serve_error(&res, .not_found), - else => try serve_error(&res, .bad_request), + error.FileNotFound => try serve_error(res, .not_found), + else => try serve_error(res, .bad_request), } } try res.finish(); } -} -fn serve_file(res: *std.http.Server.Response, file: std.fs.File, md: std.fs.File.Metadata) !void { - res.transfer_encoding = .{ .content_length = md.size() }; - try res.do(); - var buf = [_]u8{0} ** 1024; - while (true) { - const read = try file.read(&buf); - if (read == 0) break; - _ = try res.write(buf[0..read]); + fn serve_file(res: *std.http.Server.Response, file: std.fs.File, md: std.fs.File.Metadata) !void { + res.transfer_encoding = .{ .content_length = md.size() }; + try res.do(); + var buf = [_]u8{0} ** 1024; + while (true) { + const read = try file.read(&buf); + if (read == 0) break; + _ = try res.write(buf[0..read]); + } } -} -fn serve_error(res: *std.http.Server.Response, status: std.http.Status) !void { - res.status = status; - res.transfer_encoding = .chunked; - try res.do(); - const phrase = status.phrase() orelse "error!"; - try std.fmt.format(res.writer(), - \\ {s} - , .{phrase}); + fn serve_error(res: *std.http.Server.Response, status: std.http.Status) !void { + res.status = status; + res.transfer_encoding = .chunked; + try res.do(); + const phrase = status.phrase() orelse "error!"; + try std.fmt.format(res.writer(), + \\ {s} + , .{phrase}); + } +}; +const Server = zws.Server(Context, Handler); +var allocator = std.heap.GeneralPurposeAllocator(.{}){}; +var svr = Server{ + .allocator = allocator.allocator(), + .address = std.net.Address{ .in = std.net.Ip4Address.init(.{ 127, 0, 0, 1 }, 8080) }, + .context = Context{}, + .handler = Handler{}, +}; + +pub fn main() !void { + try svr.serve(); } test { -- cgit v1.2.3-ZIG