1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
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);
while (true) {
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();
}
|