aboutsummaryrefslogtreecommitdiffstats
path: root/ui-clone.c
diff options
context:
space:
mode:
authorFlorian Pritz <bluewind@xinu.at>2014-12-29 17:05:07 +0100
committerFlorian Pritz <bluewind@xinu.at>2014-12-29 17:52:56 +0100
commit4f5e9b0d6c1090681c489a10179ff1a7c215ac19 (patch)
treeac7bece975e3b7394b2c30a9a404212270d31955 /ui-clone.c
parent7552266aaccb9445e082fc04215afcb55ad543d8 (diff)
downloadcgit-working.tar.gz
cgit-working.tar.xz
Support Git over HTTP using git-http-backendworking
This saves users from the hassle of setting up git-http-backend when they already run cgit. References: man git-http-backend Signed-off-by: Florian Pritz <bluewind@xinu.at>
Diffstat (limited to 'ui-clone.c')
-rw-r--r--ui-clone.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/ui-clone.c b/ui-clone.c
index a4ffd6e..91d8306 100644
--- a/ui-clone.c
+++ b/ui-clone.c
@@ -69,8 +69,43 @@ static void send_file(char *path)
html_include(path);
}
+static void dispatch_to_git_http_backend(void)
+{
+ if (access(ctx.cfg.http_backend_path, X_OK) != -1) {
+ size_t git_root_len;
+ char *git_root = NULL;
+
+ /* git-http-backend does it's own URL parsing and concatenates
+ * GIT_PROJECT_ROOT and PATH_INFO to find the git repo.
+ * The root is the same as scan-path, but scan-path is not
+ * always available so we calculate the root path.
+ * Example:
+ * repo.path = /srv/git/some/more/dirs/
+ * qry.repo = some/more/dirs
+ * -> git_root = /srv/git/
+ */
+ strip_suffix(ctx.repo->path, "/", &git_root_len);
+ strip_suffix_mem(ctx.repo->path, &git_root_len, ctx.qry.repo);
+
+ git_root = xmalloc(git_root_len + 1);
+ strncpy(git_root, ctx.repo->path, git_root_len);
+ git_root[git_root_len] = '\0';
+
+ setenv("GIT_PROJECT_ROOT", git_root, 1);
+ execl(ctx.cfg.http_backend_path, "git-http-backend", NULL);
+ } else {
+ fprintf(stderr, "[cgit] http-backend-path (%s) is not executable: %s\n",
+ ctx.cfg.http_backend_path, strerror(errno));
+ html_status(500, "Internal Server Error", 0);
+ }
+}
+
void cgit_clone_info(void)
{
+ if (ctx.cfg.http_backend_path) {
+ return dispatch_to_git_http_backend();
+ }
+
if (!ctx.qry.path || strcmp(ctx.qry.path, "refs"))
return;
@@ -82,6 +117,10 @@ void cgit_clone_info(void)
void cgit_clone_objects(void)
{
+ if (ctx.cfg.http_backend_path) {
+ return dispatch_to_git_http_backend();
+ }
+
if (!ctx.qry.path) {
html_status(400, "Bad request", 0);
return;
@@ -97,5 +136,27 @@ void cgit_clone_objects(void)
void cgit_clone_head(void)
{
+ if (ctx.cfg.http_backend_path) {
+ return dispatch_to_git_http_backend();
+ }
+
send_file(git_path("%s", "HEAD"));
}
+
+void cgit_clone_git_upload_pack(void)
+{
+ if (ctx.cfg.http_backend_path) {
+ return dispatch_to_git_http_backend();
+ }
+
+ html_status(404, "Not found", 0);
+}
+
+void cgit_clone_git_receive_pack(void)
+{
+ if (ctx.cfg.http_backend_path) {
+ return dispatch_to_git_http_backend();
+ }
+
+ html_status(404, "Not found", 0);
+}