use response arena rather than db allocator for responses

This commit is contained in:
Emil Lerch 2026-07-22 06:22:59 -07:00
parent 61efcae568
commit a09088ebff
Signed by: lobo
GPG key ID: A7B62D657EF764F8

View file

@ -130,7 +130,7 @@ pub fn main() !u8 {
return 0;
}
fn indexHandler(db: *root.NotmuchDb, _: *httpz.Request, res: *httpz.Response) !void {
fn indexHandler(_: *root.NotmuchDb, _: *httpz.Request, res: *httpz.Response) !void {
const file = std.fs.cwd().openFile("static/index.html", .{}) catch {
res.status = 500;
res.body = "Error loading index.html";
@ -138,7 +138,7 @@ fn indexHandler(db: *root.NotmuchDb, _: *httpz.Request, res: *httpz.Response) !v
};
defer file.close();
const content = file.readToEndAlloc(db.allocator, 1024 * 1024) catch {
const content = file.readToEndAlloc(res.arena, 1024 * 1024) catch {
res.status = 500;
res.body = "Error reading index.html";
return;
@ -149,7 +149,7 @@ fn indexHandler(db: *root.NotmuchDb, _: *httpz.Request, res: *httpz.Response) !v
res.body = content;
}
fn staticHandler(db: *root.NotmuchDb, req: *httpz.Request, res: *httpz.Response) !void {
fn staticHandler(_: *root.NotmuchDb, req: *httpz.Request, res: *httpz.Response) !void {
const path = req.url.path;
const file_path = if (std.mem.eql(u8, path, "/style.css"))
@ -169,7 +169,7 @@ fn staticHandler(db: *root.NotmuchDb, req: *httpz.Request, res: *httpz.Response)
};
defer file.close();
const content = file.readToEndAlloc(db.allocator, 1024 * 1024) catch {
const content = file.readToEndAlloc(res.arena, 1024 * 1024) catch {
res.status = 500;
res.body = "Error reading file";
return;
@ -345,8 +345,13 @@ fn attachmentHandler(db: *root.NotmuchDb, req: *httpz.Request, res: *httpz.Respo
}
const att = msg.attachments[num];
res.header("Content-Type", att.content_type);
res.header("Content-Disposition", try std.fmt.allocPrint(db.allocator, "attachment; filename=\"{s}\"", .{att.filename}));
// httpz stores header values by reference and serializes them after this
// handler returns -- i.e. after `defer msg.deinit` has freed att.* and
// without ever freeing anything allocated here. Copy both values into the
// per-request arena (reset by httpz after the response is written) to avoid
// a use-after-free on Content-Type and a leak on Content-Disposition.
res.header("Content-Type", try res.arena.dupe(u8, att.content_type));
res.header("Content-Disposition", try std.fmt.allocPrint(res.arena, "attachment; filename=\"{s}\"", .{att.filename}));
// TODO: Actually retrieve and send attachment content
// For now, just send metadata