const std = @import("std"); const memora = @import("memora"); pub const std_options = std.Options { .logFn = memora.log.handler, }; const log = std.log.scoped(.main); var net_server: std.net.Server = undefined; fn signal_handler(signo: i32) callconv(.c) void { if (signo == std.os.linux.SIG.INT) { log.info("shutdown", .{}); net_server.deinit(); std.process.exit(0); } } fn register_sigaction() void { var sa = std.os.linux.Sigaction{ .handler = .{ .handler = signal_handler }, .mask = std.mem.zeroes(std.os.linux.sigset_t), .flags = 0, }; _ = std.os.linux.sigaction(std.os.linux.SIG.INT, &sa, null); } pub fn main() !void { register_sigaction(); var gpa = std.heap.GeneralPurposeAllocator(.{}){}; defer std.debug.assert(gpa.deinit() == .ok); const allocator = gpa.allocator(); const address = try std.net.Address.parseIpAndPort("0.0.0.0:8080"); net_server = try address.listen(.{ .reuse_address = true }); defer net_server.deinit(); log.info("listening on {f}", .{address}); while (true) { const connection = net_server.accept() catch |err| { log.err("error: {}", .{err}); continue; }; defer connection.stream.close(); var read_buf: [1024 * 8]u8 = undefined; var write_buf: [1024 * 8]u8 = undefined; var reader = connection.stream.reader(&read_buf); var writer = connection.stream.writer(&write_buf); var http_server = std.http.Server.init(reader.interface(), &writer.interface); var request = http_server.receiveHead() catch continue; log.info("{} {s}", .{request.head.method, request.head.target}); const handler_info = memora.routes.get(request.head.target); try handler_info.handle(&request, allocator); } }