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");