From 6bd24af2ffbea91db1b10a5d5258980ce2068c7f Mon Sep 17 00:00:00 2001 From: sadbeast Date: Tue, 16 Jul 2024 18:16:29 -0700 Subject: let's go --- src/App.zig | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 src/App.zig (limited to 'src/App.zig') 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"); -- cgit v1.2.3