╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ serve_common.zig ─────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │http│ ssh │ │ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
19 requested: []const u8, 20 create_if_missing: bool, 21 ) !RepoPath { 22 const owner_repo = evt.parseOwnerRepoPath(requested) orelse return .invalid; 23 const event_id_hex = (try evt.resolveOrCreateRepo(io, allocator, admin_repo_path, owner_repo.owner, owner_repo.name, create_if_missing)) orelse return .not_found; 24 return .{ .ok = try std.fs.path.join(allocator, &.{ repo_root_path, &event_id_hex }) }; 25 } 26 27 pub fn logError(err: *std.Io.Writer, comptime fmt: []const u8, args: anytype) void { 28 err.print(fmt, args) catch return; 29 err.flush() catch {}; 30 } 31 32 // accept connections forever, spawning `handleConn(context, stream)` as a task 33 // for each. the handler owns the stream (it closes it). `name` labels accept 34 // errors in the log. shared by the http, ssh, and web ui listeners. 35 pub fn runListener( 36 io: std.Io, 37 net_server: *std.Io.net.Server, 38 tasks: *std.Io.Group, 39 err: *std.Io.Writer, 40 name: []const u8, 41 context: anytype, 42 comptime handleConn: fn (@TypeOf(context), std.Io.net.Stream) void, 43 ) void { 44 const Context = @TypeOf(context); 45 46 const Conn = struct { 47 context: Context, 48 stream: std.Io.net.Stream, 49 50 fn run(c: @This()) void { 51 handleConn(c.context, c.stream); 52 } 53 }; 54 55 const Listener = struct { 56 io: std.Io, 57 net_server: *std.Io.net.Server, 58 tasks: *std.Io.Group, 59 err: *std.Io.Writer, 60 name: []const u8, 61 context: Context, 62 63 fn run(self: @This()) void { 64 while (true) { 65 const stream = self.net_server.accept(self.io) catch |accept_err| { 66 if (accept_err == error.Canceled) return; 67 logError(self.err, "{s} accept failed: {s}\n", .{ self.name, @errorName(accept_err) }); 68 continue; 69 }; 70 self.tasks.async(self.io, Conn.run, .{Conn{ .context = self.context, .stream = stream }}); 71 } 72 } 73 }; 74 75 tasks.async(io, Listener.run, .{Listener{ 76 .io = io, 77 .net_server = net_server, 78 .tasks = tasks, 79 .err = err, 80 .name = name, 81 .context = context, 82 }}); 83 } 84