summaryrefslogtreecommitdiffstats
path: root/src/App.zig
diff options
context:
space:
mode:
authorsadbeast <sadbeast@sadbeast.com>2024-07-16 18:16:29 -0700
committersadbeast <sadbeast@sadbeast.com>2024-10-05 16:40:55 -0700
commit6bd24af2ffbea91db1b10a5d5258980ce2068c7f (patch)
tree66634833f2d45260be5fcaf9111400eda12f03cc /src/App.zig
downloadteamdraft-main.tar.gz
teamdraft-main.tar.bz2
let's goHEADmain
Diffstat (limited to 'src/App.zig')
-rw-r--r--src/App.zig105
1 files changed, 105 insertions, 0 deletions
diff --git a/src/App.zig b/src/App.zig
new file mode 100644
index 0000000..494ee8f
--- /dev/null
+++ b/src/App.zig
@@ -0,0 +1,105 @@
+const App = @This();
+
+allocator: std.mem.Allocator,
+
+pool: *pg.Pool,
+
+pub fn init(allocator: std.mem.Allocator) !App {
+ var env_map = try std.process.getEnvMap(allocator);
+ defer env_map.deinit();
+
+ const pool = try pg.Pool.init(allocator, .{
+ .size = 5,
+ .connect = .{
+ // .port = 5432,
+ .unix_socket = env_map.get("PGSOCKET") orelse "/tmp/db/.s.PGSQL.5432",
+ },
+ .auth = .{
+ .database = env_map.get("PGDATABASE") orelse "teamdraft",
+ .username = env_map.get("PGUSER") orelse "teamdraft_rw",
+ .password = env_map.get("PGPASSWORD") orelse "teamdraft",
+ .timeout = 10_000,
+ },
+ });
+
+ return .{
+ .allocator = allocator,
+ .pool = pool,
+ };
+}
+
+pub fn deinit(self: *App) void {
+ self.pool.deinit();
+}
+
+pub fn dispatch(self: *App, action: httpz.Action(*RequestContext), req: *httpz.Request, res: *httpz.Response) !void {
+ const start_time = std.time.milliTimestamp();
+
+ var logger = logz.logger().multiuse();
+
+ var ctx = RequestContext{
+ .app = self,
+ .user = try self.loadUser(req),
+ };
+ // defer env.deinit();
+
+ logger
+ .stringSafe("@l", "REQ")
+ .stringSafe("method", @tagName(req.method))
+ .string("path", req.url.path)
+ .string("query", req.url.query)
+ .int("status", res.status)
+ .int("uid", if (ctx.user) |u| u.id else 0)
+ .int("ms", std.time.milliTimestamp() - start_time)
+ .log();
+
+ return action(&ctx, req, res);
+}
+
+pub fn notFound(_: *App, req: *httpz.Request, res: *httpz.Response) !void {
+ try web.render("404", req, res);
+}
+
+pub fn uncaughtError(_: *App, _: *httpz.Request, res: *httpz.Response, err: anyerror) void {
+ logz.info().err(err).log();
+
+ res.status = 500;
+ res.body = "sorry";
+}
+
+const Account = struct {
+ account_id: i64,
+};
+
+fn loadUser(self: *App, req: *httpz.Request) !?User {
+ if (req.header("cookie")) |cookie_header| {
+ var cookies = Cookie.init(req.arena, cookie_header);
+ defer cookies.deinit();
+
+ try cookies.parse();
+ if (cookies.get("s")) |session_id| {
+ logz.info().string("session", session_id.value).log();
+ var row = (try self.pool.row("SELECT account_id FROM get_account_by_session_id($1)", .{session_id.value})) orelse return null;
+ defer row.deinit() catch {};
+
+ const account = try row.to(Account, .{});
+
+ return try User.init(req.arena, account.account_id, "");
+ }
+ // var it = req.headers.iterator();
+ // while (it.next()) |kv| {
+ // logz.info().string("header", kv.key).string("value", kv.value).log();
+ // }
+ }
+ return null;
+}
+
+const std = @import("std");
+const pg = @import("pg");
+const httpz = @import("httpz");
+const logz = @import("logz");
+
+const RequestContext = @import("RequestContext.zig");
+const User = @import("User.zig");
+const Cookie = @import("web/Cookie.zig");
+const web = @import("web/web.zig");