╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ─────────╮ │src/serve_http.zig│ ╰──────────────────╯ ╭───────────────────────────────────────────────╮ │36 .allocator = allocator, │ │37 .repo_root_path = repo_root_path, │ │38 .admin_repo_path = admin_repo_path,│ │41 - .is_test = is_test, │ │39 .err = err, │ │40 }, handle); │ │41 } │ ╰───────────────────────────────────────────────╯ ╭─────────────────────────────────────╮ │47 allocator: std.mem.Allocator,│ │48 repo_root_path: []const u8, │ │49 admin_repo_path: []const u8, │ │53 - is_test: bool, │ │50 stream: std.Io.net.Stream, │ │51 err: *std.Io.Writer, │ │52 ) !void { │ ╰─────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │63 else => |e| return e, │ │64 }; │ │65 │ │70 - handleGitRequest(repo_kind, any_repo_opts, io, allocator, repo_root_path, admin_repo_path, is_test, &http_server, &request) catch |request_err| {│ │66 + handleGitRequest(repo_kind, any_repo_opts, io, allocator, repo_root_path, admin_repo_path, &http_server, &request) catch |request_err| { │ │67 try err.print("request failed: {s}\n", .{@errorName(request_err)}); │ │68 try err.flush(); │ │69 if (http_server.reader.state == .received_head) { │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────╮ │83 allocator: std.mem.Allocator, │ │84 repo_root_path: []const u8, │ │85 admin_repo_path: []const u8, │ │90 - is_test: bool, │ │86 http_server: *std.http.Server, │ │87 request: *std.http.Server.Request,│ │88 ) !void { │ ╰──────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────╮ │111 const has_remote_user = findHeader(request, "authorization") != null; │ │112 const protocol_version = protocolVersionFromHeader(findHeader(request, "git-protocol"));│ │113 │ │119 - const create_if_missing = isReceivePack(handler, suffix, uri.query); │ │120 - │ │121 - // pushing over HTTP is disabled outside test mode; pushes go over SSH │ │122 - if (create_if_missing and !is_test) { │ │114 + // pushing over HTTP is not supported; pushes go over SSH │ │115 + if (isReceivePack(handler, suffix, uri.query)) { │ │116 if (http_server.reader.state == .received_head) { │ │117 http_server.reader.state = .ready; │ │118 } │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │126 - try writeSimpleResponse(http_server, 403, "Forbidden", "text/plain", "push over HTTP is disabled"); │ │119 + try writeSimpleResponse(http_server, 403, "Forbidden", "text/plain", "push over HTTP is not supported");│ │120 return; │ │121 } │ │122 │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │130 http_server.reader.state = .ready; │ │131 } │ │132 │ │140 - const repo_path = switch (try serve_common.resolveRepoPath(io, allocator, is_test, repo_root_path, admin_repo_path, repo_rel, create_if_missing)) {│ │133 + const repo_path = switch (try serve_common.resolveRepoPath(io, allocator, repo_root_path, admin_repo_path, repo_rel, false)) { │ │134 .ok => |p| p, │ │135 .invalid => return writeSimpleResponse(http_server, 400, "Bad Request", "text/plain", "repo path must be <owner>/<repo>"), │ │136 .not_found => return error.RepoNotFound, │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │148 .protocol_version = protocol_version, │ │149 }; │ │150 │ │158 - try openRepoAndServe(repo_kind, any_repo_opts, io, allocator, repo_path, create_if_missing, GitService{│ │151 + try openRepoAndServe(repo_kind, any_repo_opts, io, allocator, repo_path, GitService{ │ │152 .body_reader = &body_reader, │ │153 .writer = http_server.out, │ │154 .options = http_backend_options, │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │170 io: std.Io, │ │171 allocator: std.mem.Allocator, │ │172 repo_path: []const u8, │ │180 - create_if_missing: bool, │ │173 service: anytype, │ │174 ) !void { │ │183 - // serve the existing on-disk repo at its event-id directory │ │175 + // serve the existing on-disk repo at its event-id directory; HTTP only │ │176 + // handles fetch/clone, so a missing repo is simply not found │ │177 if (try serveIfExists(repo_kind, any_repo_opts, io, allocator, repo_path, service)) return; │ │185 - if (!create_if_missing) return error.RepoNotFound; │ │186 - │ │187 - // create the on-disk repo for the just-minted event and serve the push │ │188 - if (any_repo_opts.hash) |hash_kind| { │ │189 - var repo = try openRepo(repo_kind, any_repo_opts.toRepoOptsWithHash(hash_kind), io, allocator, repo_path, true);│ │190 - defer repo.deinit(io, allocator); │ │191 - try service.serve(repo_kind, any_repo_opts.toRepoOptsWithHash(hash_kind), &repo, io, allocator); │ │192 - } else { │ │193 - var repo = try openRepo(repo_kind, any_repo_opts.toRepoOpts(), io, allocator, repo_path, true); │ │194 - defer repo.deinit(io, allocator); │ │195 - try service.serve(repo_kind, any_repo_opts.toRepoOpts(), &repo, io, allocator); │ │196 - } │ │178 + return error.RepoNotFound; │ │179 } │ │180 │ │181 // serve an existing repo at `repo_path`, or return false if none is there │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │209 } │ │210 } │ │211 return true; │ │230 -} │ │231 - │ │232 -fn openRepo( │ │233 - comptime repo_kind: rp.RepoKind, │ │234 - comptime repo_opts: rp.RepoOpts(repo_kind), │ │235 - io: std.Io, │ │236 - allocator: std.mem.Allocator, │ │237 - repo_path: []const u8, │ │238 - create_if_missing: bool, │ │239 -) !rp.Repo(repo_kind, repo_opts) { │ │240 - return rp.Repo(repo_kind, repo_opts).open(io, allocator, .{ .path = repo_path }) catch |open_err| switch (open_err) {│ │241 - error.RepoNotFound => { │ │242 - if (!create_if_missing) return open_err; │ │243 - │ │244 - var repo = try rp.Repo(repo_kind, repo_opts).init(io, allocator, .{ .path = repo_path }); │ │245 - errdefer repo.deinit(io, allocator); │ │246 - try repo.addConfig(io, allocator, .{ .name = "http.receivepack", .value = "true" }); │ │247 - try repo.addConfig(io, allocator, .{ .name = "receive.denycurrentbranch", .value = "updateinstead" }); │ │248 - return repo; │ │249 - }, │ │250 - else => |e| return e, │ │251 - }; │ │212 } │ │213 │ │214 const GitService = struct { │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯