aboutsummaryrefslogtreecommitdiff
path: root/src/server.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/server.zig')
-rw-r--r--src/server.zig71
1 files changed, 71 insertions, 0 deletions
diff --git a/src/server.zig b/src/server.zig
new file mode 100644
index 0000000..184af92
--- /dev/null
+++ b/src/server.zig
@@ -0,0 +1,71 @@
+const std = @import("std");
+const log = std.log.scoped(.server);
+
+const routes = @import("routes/root.zig");
+const Storage = @import("storage/root.zig");
+const config = @import("config");
+
+const Self = @This();
+
+storage: Storage = undefined,
+net_server: std.net.Server = undefined,
+pool: std.Thread.Pool = undefined,
+
+pub fn init(
+ self: *Self,
+ address: std.net.Address,
+ allocator: std.mem.Allocator,
+) !void {
+ self.storage = try .init(allocator);
+ self.net_server = try address.listen(.{ .reuse_address = true });
+ try self.pool.init(.{ .allocator = allocator });
+ log.info("listing on {f}", .{address});
+
+ if (comptime config.disable_auth) {
+ log.warn("authentication is disabled", .{});
+ }
+}
+
+pub fn run(self: *Self, allocator: std.mem.Allocator) void {
+ while (true) {
+ const connection = self.net_server.accept() catch |err| {
+ log.err("error: {}", .{err});
+ continue;
+ };
+
+ self.pool.spawn(handle_connection, .{self, allocator, connection}) catch |err| {
+ std.log.err("failed to spawn thread: {}", .{err});
+ };
+ }
+}
+
+fn handle_connection(
+ self: *Self,
+ allocator: std.mem.Allocator,
+ connection: std.net.Server.Connection,
+) void {
+ 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 return;
+ log.info("{s} {s}", .{
+ std.enums.tagName(std.http.Method, request.head.method) orelse "<unknown>",
+ request.head.target,
+ });
+
+ const handler_info = routes.get(request.head.target);
+ handler_info.handle(&request, &self.storage, allocator) catch |err| {
+ std.log.err("{}", .{err});
+ };
+}
+
+pub fn deinit(self: *Self) void {
+ log.info("shutdown", .{});
+ self.net_server.deinit();
+ self.storage.deinit();
+}