atproto relay implementation in zig zlay.waow.tech

fix: use dynamic allocation for admin/hosts endpoint and add auth check

the 64KB stack buffer overflows with 2800+ hosts, causing 502 responses.
switch to ArrayList writer for unbounded JSON response. also adds the
missing checkAdmin gate that other admin endpoints already have.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

+6 -4
+6 -4
src/main.zig
··· 387 387 // --- admin host management --- 388 388 389 389 fn handleAdminListHosts(request: *http.Server.Request, persist: *event_log_mod.DiskPersist, slurper: *slurper_mod.Slurper) void { 390 + if (!checkAdmin(request)) return; 391 + 390 392 const hosts = persist.listAllHosts(persist.allocator) catch { 391 393 respondJson(request, .internal_server_error, "{\"error\":\"DatabaseError\",\"message\":\"query failed\"}"); 392 394 return; ··· 399 401 persist.allocator.free(hosts); 400 402 } 401 403 402 - var buf: [65536]u8 = undefined; 403 - var fbs = std.io.fixedBufferStream(&buf); 404 - const w = fbs.writer(); 404 + var list: std.ArrayListUnmanaged(u8) = .{}; 405 + defer list.deinit(persist.allocator); 406 + const w = list.writer(persist.allocator); 405 407 406 408 w.writeAll("{\"hosts\":[") catch return; 407 409 ··· 417 419 } 418 420 419 421 std.fmt.format(w, "],\"active_workers\":{d}}}", .{slurper.workerCount()}) catch return; 420 - respondJson(request, .ok, fbs.getWritten()); 422 + respondJson(request, .ok, list.items); 421 423 } 422 424 423 425 fn handleAdminBlockHost(request: *http.Server.Request, persist: *event_log_mod.DiskPersist) void {