╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ─────────╮ │src/serve_http.zig│ ╰──────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │22 admin_repo_path: []const u8, │ │51 - stream: std.Io.net.Stream, │ │23 + http_server: *std.http.Server, │ │24 + request: *std.http.Server.Request, │ │25 err: *std.Io.Writer, │ │53 -) !void { │ │54 - var send_buffer: [any_repo_opts.net_buffer_size]u8 = @splat(0); │ │55 - var recv_buffer: [any_repo_opts.net_buffer_size]u8 = @splat(0); │ │56 - var conn_br = stream.reader(io, &recv_buffer); │ │57 - var conn_bw = stream.writer(io, &send_buffer); │ │58 - var http_server = std.http.Server.init(&conn_br.interface, &conn_bw.interface); │ │26 +) anyerror!void; │ │27 │ │60 - if (http_server.reader.state == .ready) { │ │61 - var request = http_server.receiveHead() catch |receive_err| switch (receive_err) { │ │62 - error.HttpConnectionClosing => return, │ │63 - error.ReadFailed => return, │ │64 - else => |e| return e, │ │65 - }; │ │66 - │ │67 - handleGitRequest(repo_kind, any_repo_opts, io, allocator, users_dir, admin_repo_path, &http_server, &request) catch |request_err| { │ │68 - serve_common.logError(io, err, "request failed: {s}\n", .{@errorName(request_err)}); │ │69 - if (http_server.reader.state == .received_head) { │ │70 - http_server.reader.state = .ready; │ │71 - } │ │72 - try writeSimpleResponse(&http_server, 500, "Internal Server Error", "text/plain", @errorName(request_err)); │ │73 - }; │ │74 - try http_server.out.flush(); │ │75 - } │ │28 +// the git request handler for one repo backend, so the web listener needn't be generic │ │29 +pub fn gitHandler(comptime repo_kind: rp.RepoKind, comptime any_repo_opts: rp.AnyRepoOpts(repo_kind)) GitHandler { │ │30 + return struct { │ │31 + fn handle( │ │32 + io: std.Io, │ │33 + allocator: std.mem.Allocator, │ │34 + users_dir: []const u8, │ │35 + admin_repo_path: []const u8, │ │36 + http_server: *std.http.Server, │ │37 + request: *std.http.Server.Request, │ │38 + err: *std.Io.Writer, │ │39 + ) anyerror!void { │ │40 + handleGitRequest(repo_kind, any_repo_opts, io, allocator, users_dir, admin_repo_path, http_server, request) catch |request_err| {│ │41 + serve_common.logError(io, err, "request failed: {s}\n", .{@errorName(request_err)}); │ │42 + if (http_server.reader.state == .received_head) { │ │43 + http_server.reader.state = .ready; │ │44 + } │ │45 + try writeSimpleResponse(http_server, 500, "Internal Server Error", "text/plain", @errorName(request_err)); │ │46 + }; │ │47 + try http_server.out.flush(); │ │48 + } │ │49 + }.handle; │ │50 } │ │51 │ │52 fn handleGitRequest( │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ────────╮ │src/serve_ssh.zig│ ╰─────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────╮ │30 admin_repo_path: []const u8, │ │31 // where event writes go │ │32 server: evt.Host.Server, │ │33 - wui_port: u16, // port the web UI is served on, shown in the TUI footer's url│ │34 - git_http_port: ?u16, │ │35 - git_ssh_port: ?u16, │ │33 + // the web UI's url, shown in the TUI footer and shared by git's http clones │ │34 + web_url: []const u8, │ │35 + ssh_url: ?[]const u8, │ │36 git_ssh_prefix: []const u8, │ │37 err: *std.Io.Writer, │ │38 │ ╰─────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────╮ │231 var ui_session = try ui.Session.init(&session_arena, &repo, .{});│ │232 ui_session.is_terminal = true; │ │233 ui_session.color = color; │ │234 - ui_session.web_port = handler.wui_port; │ │235 - ui_session.data.git_http_port = handler.git_http_port; │ │236 - ui_session.data.git_ssh_port = handler.git_ssh_port; │ │234 + ui_session.web_url = handler.web_url; │ │235 + ui_session.data.git_http_url = handler.web_url; │ │236 + ui_session.data.git_ssh_url = handler.ssh_url; │ │237 ui_session.data.git_ssh_prefix = handler.git_ssh_prefix; │ │238 // let page builders open on-disk repos │ │239 ui_session.io = io; │ ╰──────────────────────────────────────────────────────────────────────────╯ ╭ changed ───────╮ │src/test/net.zig│ ╰────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────╮ │149 const haxy_path = try std.Io.Dir.path.join(allocator, &.{ cwd_path, "zig-out/bin/haxy" });│ │150 defer allocator.free(haxy_path); │ │151 │ │152 - const http_listen_arg = std.fmt.comptimePrint("127.0.0.1:{}", .{port}); │ │152 + const web_listen_arg = std.fmt.comptimePrint("127.0.0.1:{}", .{port}); │ │153 const ssh_listen_arg = std.fmt.comptimePrint("127.0.0.1:{}", .{port + 1}); │ │154 │ │155 const process = try std.process.spawn(io, .{ │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │156 - .argv = &.{ haxy_path, "serve", "--http-listen", http_listen_arg, "--ssh-listen", ssh_listen_arg, "--data-dir", temp_path },│ │156 + .argv = &.{ haxy_path, "serve", "--web-listen", web_listen_arg, "--ssh-listen", ssh_listen_arg, "--data-dir", temp_path }, │ │157 .stdin = .ignore, │ │158 .stdout = .ignore, │ │159 .stderr = .ignore, │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ──╮ │src/try.zig│ ╰───────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ 993 io: std.Io, │ │ 994 key_path: []const u8, │ │ 995 │ │ 996 - pub fn run(self: @This(), web_port: u16, http_port: ?u16, ssh_port_maybe: ?u16) !void {│ │ 997 - _ = web_port; │ │ 998 - _ = http_port; │ │ 999 - const ssh_port = ssh_port_maybe orelse return error.SshDisabled; │ │ 996 + pub fn run(self: @This(), web_url: []const u8, ssh_url_maybe: ?[]const u8) !void { │ │ 997 + _ = web_url; │ │ 998 + const ssh_url = ssh_url_maybe orelse return error.SshDisabled; │ │ 999 std.debug.print( │ │1000 \\ │ │1001 \\connect to the TUI with: │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1003 - \\ ssh -p {d} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null localhost│ │1002 + \\ ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null {s} │ │1003 \\ │ │1004 \\create a git repo and push over SSH: │ │1005 \\ mkdir -p temp-try/client/test │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1008 \\ echo "hello" > hello.txt │ │1009 \\ git add hello.txt │ │1010 \\ git commit -m "let there be light" │ │1012 - \\ GIT_SSH_COMMAND='ssh -p {d} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o IdentitiesOnly=yes -i {s}' git push localhost:admin:test HEAD:master│ │1011 + \\ GIT_SSH_COMMAND='ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o IdentitiesOnly=yes -i {s}' git push {s}/admin:test HEAD:master │ │1012 \\ │ │1013 \\to quit, press enter. │ │1014 \\ │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────╮ │1016 - , .{ ssh_port, ssh_port, self.key_path }); │ │1015 + , .{ ssh_url, self.key_path, ssh_url }); │ │1016 // portable stdin read via std.Io — equivalent to the │ │1017 // std.posix.read(STDIN_FILENO, ...) that doesn't compile│ │1018 // on windows. │ ╰───────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────╮ │1033 session: *ui.Session, │ │1034 repo: *Repo, │ │1035 │ │1037 - pub fn run(self: @This(), web_port: u16, http_port: ?u16, ssh_port: ?u16) !void {│ │1036 + pub fn run(self: @This(), web_url: []const u8, ssh_url: ?[]const u8) !void { │ │1037 // launch the TUI; the footer points at whatever port was bound │ │1039 - self.session.web_port = web_port; │ │1040 - self.session.data.git_http_port = http_port; │ │1041 - self.session.data.git_ssh_port = ssh_port; │ │1038 + self.session.web_url = web_url; │ │1039 + self.session.data.git_http_url = web_url; │ │1040 + self.session.data.git_ssh_url = ssh_url; │ │1041 try hx.ui.run(self.io, self.allocator, self.session, self.repo); │ │1042 } │ │1043 }; │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯