diff options
-rw-r--r-- | cgit.c | 3 | ||||
-rw-r--r-- | cgit.h | 1 | ||||
-rw-r--r-- | cgitrc.5.txt | 8 | ||||
-rw-r--r-- | cmd.c | 13 | ||||
-rw-r--r-- | ui-clone.c | 44 | ||||
-rw-r--r-- | ui-clone.h | 2 |
6 files changed, 71 insertions, 0 deletions
@@ -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; @@ -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 @@ -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; @@ -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"); +} @@ -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 */ |