╭ changed ──╮ │src/web.zig│ ╰───────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────╮ │← previous│ ╰──────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1329 try hunks.append(aa, try std.mem.replaceOwned(u8, aa, posted, "\r\n", "\n")); │ │1330 } │ │1331 │ │1262 - const not_found = "issue not found"; │ │1263 - const parts = issueBaseParts(base) orelse { │ │1264 - try request.respond(not_found, .{ │ │1332 + const parts = commentBaseParts(base) orelse { │ │1333 + try request.respond("thread not found", .{ │ │1334 + .status = .not_found, │ │1335 + .extra_headers = &.{.{ .name = "content-type", .value = "text/plain" }}, │ │1336 + }); │ │1337 + return; │ │1338 + }; │ │1339 + if (parts.comment_id != null or (parts.thread_kind != .issue and parts.thread_kind != .patch)) {│ │1340 + try request.respond("thread not found", .{ │ │1341 + .status = .not_found, │ │1342 + .extra_headers = &.{.{ .name = "content-type", .value = "text/plain" }}, │ │1343 + }); │ │1344 + return; │ │1345 + } │ │1346 + const route = ui.RoutablePage.fromUrl(base) orelse ui.RoutablePage.fromUrlLocal(base) orelse { │ │1347 + try request.respond("thread not found", .{ │ │1348 .status = .not_found, │ │1349 .extra_headers = &.{.{ .name = "content-type", .value = "text/plain" }}, │ │1350 }); │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1351 return; │ │1352 }; │ │1353 + const theirs: []const u8 = switch (route) { │ │1354 + .repo_patches => |*patch| patch.theirs.slice(), │ │1355 + .repo_issues => "", │ │1356 + else => unreachable, │ │1357 + }; │ │1358 + const not_found = if (parts.thread_kind == .patch) "patch not found" else "issue not found"; │ │1359 │ │1271 - updateIssue(io, allocator, host, parts, .{ .resolve = .{ │ │1272 - .title = title, │ │1273 - .tags = tags, │ │1274 - .hunks = hunks.items, │ │1275 - } }, author) catch |err| switch (err) { │ │1360 + (switch (parts.thread_kind) { │ │1361 + .issue => updateThread(evt.Issue, io, allocator, host, parts.repo_base, &parts.thread_id, .{ .resolve = .{│ │1362 + .title = title, │ │1363 + .tags = tags, │ │1364 + .hunks = hunks.items, │ │1365 + } }, author), │ │1366 + .patch => updateThread(evt.Patch, io, allocator, host, parts.repo_base, &parts.thread_id, .{ .resolve = .{│ │1367 + .title = title, │ │1368 + .tags = tags, │ │1369 + .hunks = hunks.items, │ │1370 + .theirs = theirs, │ │1371 + } }, author), │ │1372 + else => unreachable, │ │1373 + }) catch |err| switch (err) { │ │1374 error.NotFound => { │ │1375 try request.respond(not_found, .{ │ │1376 .status = .not_found, │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ │1986 return null; │ │1987 } │ │1988 │ │1989 +fn readFormBody(request: *std.http.Server.Request, allocator: std.mem.Allocator) ![]u8 {│ │1990 + var buffer: [256]u8 = undefined; │ │1991 + return request.readerExpectNone(&buffer).allocRemaining(allocator, .limited(65536));│ │1992 +} │ │1993 + │ │1994 fn decodeFormValue(allocator: std.mem.Allocator, encoded: []const u8) ![]u8 { │ │1995 var out: std.ArrayList(u8) = .empty; │ │1996 errdefer out.deinit(allocator); │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯