diff options
Diffstat (limited to 'support-Git-over-HTTP-by-proxying_git-http-backend.patch')
-rw-r--r-- | support-Git-over-HTTP-by-proxying_git-http-backend.patch | 223 |
1 files changed, 223 insertions, 0 deletions
diff --git a/support-Git-over-HTTP-by-proxying_git-http-backend.patch b/support-Git-over-HTTP-by-proxying_git-http-backend.patch new file mode 100644 index 0000000..d07ea7e --- /dev/null +++ b/support-Git-over-HTTP-by-proxying_git-http-backend.patch @@ -0,0 +1,223 @@ +From 2d8f83a3072970a51c45d2f72724696781ef6de8 Mon Sep 17 00:00:00 2001 +From: Wolfgang Müller +Date: Fri, 28 May 2021 16:03:01 +0200 +Subject: Support Git over HTTP by proxying git-http-backend(1) + +cgit lacks an easy way to support the "smart" HTTP protocol out of the +box. A patch [1] has been proposed in the past, but was never merged. +A few years later there was a short discussion at [2] which did not go +anywhere. + +The majority of users who want to support the "smart" HTTP protocol +right now seem to conditionally point their web server to +git-http-backend(1) directly. This relies on proper path-matching and +regular expression support in the web server as seen in the EXMAPLES +section of git-http-backend(1). + +As proposed in [3], it is possible to have cgit interface with the +necessary functionality in Git directly, but that would require more +work. It does not seem that this is something forthcoming in cgit. + +Instead, for now, use a modified version of the patch suggested in [1], +which simply executes git-http-backend(1) when needed. This removes the +need for any additional plumbing in the web server. + +Notable changes to the original patch: + + * Remove automatic handling of GIT_PROJECT_ROOT in favour of having the + user set the variable correctly themselves. This reduces complexity. + + * Use the correct function to generate error pages. The original patch + used html_status(), which does not exist anymore. + + * In cmd.c, adjust the struct entries to fit. Sadly we cannot use the + def_cmd() macro directly, as the endpoints "git-upload-pack" and + "git-receive-pack" contain dashes. + +[1] https://lists.zx2c4.com/pipermail/cgit/2014-December/002312.html +[2] https://lists.zx2c4.com/pipermail/cgit/2016-February/002907.html +[3] https://lists.zx2c4.com/pipermail/cgit/2016-February/002926.html +--- + cgit.c | 3 +++ + cgit.h | 1 + + cgitrc.5.txt | 8 ++++++++ + cmd.c | 13 +++++++++++++ + ui-clone.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ + ui-clone.h | 2 ++ + 6 files changed, 71 insertions(+) + +diff --git a/cgit.c b/cgit.c +index c4320f0..fc85c18 100644 +--- a/cgit.c ++++ b/cgit.c +@@ -151,6 +151,8 @@ static void config_cb(const char *name, const char *value) + ctx.cfg.head_include = xstrdup(value); + else if (!strcmp(name, "header")) + ctx.cfg.header = xstrdup(value); ++ else if (!strcmp(name, "http-backend-path")) ++ ctx.cfg.http_backend_path = xstrdup(value); + else if (!strcmp(name, "logo")) + ctx.cfg.logo = xstrdup(value); + else if (!strcmp(name, "logo-link")) +@@ -379,6 +381,7 @@ static void prepare_context(void) + ctx.cfg.css = "/cgit.css"; + ctx.cfg.logo = "/cgit.png"; + ctx.cfg.favicon = "/favicon.ico"; ++ ctx.cfg.http_backend_path = NULL; + ctx.cfg.local_time = 0; + ctx.cfg.enable_http_clone = 1; + ctx.cfg.enable_index_owner = 1; +diff --git a/cgit.h b/cgit.h +index 7ec46b4..cd29892 100644 +--- a/cgit.h ++++ b/cgit.h +@@ -200,6 +200,7 @@ struct cgit_config { + char *footer; + char *head_include; + char *header; ++ char *http_backend_path; + char *logo; + char *logo_link; + char *mimetype_file; +diff --git a/cgitrc.5.txt b/cgitrc.5.txt +index 33a6a8c..820cfa6 100644 +--- a/cgitrc.5.txt ++++ b/cgitrc.5.txt +@@ -234,6 +234,11 @@ header:: + The content of the file specified with this option will be included + verbatim at the top of all pages. Default value: none. + ++http-backend-path:: ++ Path to the git-http-backend binary. Setting this allows the git clone to ++ fetch/push via Git over HTTP. You'll also need to set enable-http-clone ++ for this to work. See git-http-backend(1). Default value: none. ++ + include:: + Name of a configfile to include before the rest of the current config- + file is parsed. Default value: none. See also: "MACRO EXPANSION". +@@ -824,6 +829,9 @@ enable-index-owner=1 + # Allow http transport git clone + enable-http-clone=1 + ++# Use git-http-backend to serve Git over HTTP ++http-backend-path=/usr/lib/git-core/git-http-backend ++ + + # Show extra links for each repository on the index page + enable-index-links=1 +diff --git a/cmd.c b/cmd.c +index bf6d8f5..7f1ca98 100644 +--- a/cmd.c ++++ b/cmd.c +@@ -164,6 +164,17 @@ static void tree_fn(void) + cgit_print_tree(ctx.qry.sha1, ctx.qry.path); + } + ++static void git_upload_pack_fn(void) ++{ ++ cgit_clone_git_upload_pack(); ++} ++ ++static void git_receive_pack_fn(void) ++{ ++ cgit_clone_git_receive_pack(); ++} ++ ++ + #define def_cmd(name, want_repo, want_vpath, is_clone) \ + {#name, name##_fn, want_repo, want_vpath, is_clone} + +@@ -191,6 +202,8 @@ struct cgit_cmd *cgit_get_cmd(void) + def_cmd(summary, 1, 0, 0), + def_cmd(tag, 1, 0, 0), + def_cmd(tree, 1, 1, 0), ++ {"git-upload-pack", git_upload_pack_fn, 1, 0, 1}, ++ {"git-receive-pack", git_receive_pack_fn, 1, 0, 1}, + }; + int i; + +diff --git a/ui-clone.c b/ui-clone.c +index 5dccb63..3a9cfeb 100644 +--- a/ui-clone.c ++++ b/ui-clone.c +@@ -77,8 +77,22 @@ static void send_file(const char *path) + html_include(path); + } + ++static void dispatch_to_git_http_backend(void) ++{ ++ if (execl(ctx.cfg.http_backend_path, "git-http-backend", NULL) == -1) { ++ fprintf(stderr, "[cgit] http-backend-path (%s) could not be spawned: %s\n", ++ ctx.cfg.http_backend_path, strerror(errno)); ++ cgit_print_error_page(500, "Internal Server Error", "Internal Server Error"); ++ } ++} ++ + void cgit_clone_info(void) + { ++ if (ctx.cfg.http_backend_path) { ++ dispatch_to_git_http_backend(); ++ return; ++ } ++ + if (!ctx.qry.path || strcmp(ctx.qry.path, "refs")) { + cgit_print_error_page(400, "Bad request", "Bad request"); + return; +@@ -94,6 +108,11 @@ void cgit_clone_objects(void) + { + char *p; + ++ if (ctx.cfg.http_backend_path) { ++ dispatch_to_git_http_backend(); ++ return; ++ } ++ + if (!ctx.qry.path) + goto err; + +@@ -122,5 +141,30 @@ err: + + void cgit_clone_head(void) + { ++ if (ctx.cfg.http_backend_path) { ++ dispatch_to_git_http_backend(); ++ return; ++ } ++ + send_file(git_path("%s", "HEAD")); + } ++ ++void cgit_clone_git_upload_pack(void) ++{ ++ if (ctx.cfg.http_backend_path) { ++ dispatch_to_git_http_backend(); ++ return; ++ } ++ ++ cgit_print_error_page(404, "Not found", "Not found"); ++} ++ ++void cgit_clone_git_receive_pack(void) ++{ ++ if (ctx.cfg.http_backend_path) { ++ dispatch_to_git_http_backend(); ++ return; ++ } ++ ++ cgit_print_error_page(404, "Not found", "Not found"); ++} +diff --git a/ui-clone.h b/ui-clone.h +index 3e460a3..b27087e 100644 +--- a/ui-clone.h ++++ b/ui-clone.h +@@ -4,5 +4,7 @@ + void cgit_clone_info(void); + void cgit_clone_objects(void); + void cgit_clone_head(void); ++void cgit_clone_git_upload_pack(void); ++void cgit_clone_git_receive_pack(void); + + #endif /* UI_CLONE_H */ +-- +cgit v1.2.3-2-gb3c3 + |