List for cgit developers and users
 help / color / mirror / Atom feed
* [PATCH] Support Git over HTTP using git-http-backend
@ 2014-12-29 16:13 bluewind
  2014-12-29 16:56 ` [PATCH v2] " bluewind
  0 siblings, 1 reply; 9+ messages in thread
From: bluewind @ 2014-12-29 16:13 UTC (permalink / raw)


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 at xinu.at>
---

I've messed up updating my master branch and used git-send-email on it. You
might have gotten 1 or 2 patches that are already applied because of that.
Sorry.

 cgit.c       |  3 +++
 cgit.h       |  1 +
 cgitrc.5.txt |  8 ++++++++
 cmd.c        | 12 ++++++++++++
 ui-clone.c   | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 ui-clone.h   |  2 ++
 6 files changed, 86 insertions(+)

diff --git a/cgit.c b/cgit.c
index 79019c2..0c4a292 100644
--- a/cgit.c
+++ b/cgit.c
@@ -124,6 +124,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, "index-header"))
@@ -353,6 +355,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 42140ac..dcd44f0 100644
--- a/cgit.h
+++ b/cgit.h
@@ -190,6 +190,7 @@ struct cgit_config {
 	char *footer;
 	char *head_include;
 	char *header;
+	char *http_backend_path;
 	char *index_header;
 	char *index_info;
 	char *logo;
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index be6703f..62b73ba 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -218,6 +218,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 smart HTTP backend binary. Setting this
+	allows the git clone to fetch/push via Git over HTTP. You'll also
+	need to enable enable-http-clone for this to work. 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".
@@ -766,6 +771,9 @@ enable-index-owner=1
 # Allow http transport git clone
 enable-http-clone=1
 
+# Use 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 188cd56..889ed05 100644
--- a/cmd.c
+++ b/cmd.c
@@ -136,6 +136,16 @@ 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_layout, want_vpath, is_clone) \
 	{#name, name##_fn, want_repo, want_layout, want_vpath, is_clone}
 
@@ -162,6 +172,8 @@ struct cgit_cmd *cgit_get_cmd(void)
 		def_cmd(summary, 1, 1, 0, 0),
 		def_cmd(tag, 1, 1, 0, 0),
 		def_cmd(tree, 1, 1, 1, 0),
+		{"git-upload-pack", git_upload_pack_fn, 1, 0, 0, 1},
+		{"git-receive-pack", git_receive_pack_fn, 1, 0, 0, 1},
 	};
 	int i;
 
diff --git a/ui-clone.c b/ui-clone.c
index a4ffd6e..15bd78b 100644
--- a/ui-clone.c
+++ b/ui-clone.c
@@ -69,8 +69,42 @@ 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);
+		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 +116,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 +135,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);
+}
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 */
-- 
2.2.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2] Support Git over HTTP using git-http-backend
  2014-12-29 16:13 [PATCH] Support Git over HTTP using git-http-backend bluewind
@ 2014-12-29 16:56 ` bluewind
  2014-12-29 17:16   ` cgit
                     ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: bluewind @ 2014-12-29 16:56 UTC (permalink / raw)


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 at xinu.at>
---

v2:
 - git_root allocation was too small by 1
 - change comment style to c89

 cgit.c       |  3 +++
 cgit.h       |  1 +
 cgitrc.5.txt |  8 ++++++++
 cmd.c        | 12 ++++++++++++
 ui-clone.c   | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 ui-clone.h   |  2 ++
 6 files changed, 87 insertions(+)

diff --git a/cgit.c b/cgit.c
index 79019c2..0c4a292 100644
--- a/cgit.c
+++ b/cgit.c
@@ -124,6 +124,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, "index-header"))
@@ -353,6 +355,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 42140ac..dcd44f0 100644
--- a/cgit.h
+++ b/cgit.h
@@ -190,6 +190,7 @@ struct cgit_config {
 	char *footer;
 	char *head_include;
 	char *header;
+	char *http_backend_path;
 	char *index_header;
 	char *index_info;
 	char *logo;
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index be6703f..62b73ba 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -218,6 +218,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 smart HTTP backend binary. Setting this
+	allows the git clone to fetch/push via Git over HTTP. You'll also
+	need to enable enable-http-clone for this to work. 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".
@@ -766,6 +771,9 @@ enable-index-owner=1
 # Allow http transport git clone
 enable-http-clone=1
 
+# Use 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 188cd56..889ed05 100644
--- a/cmd.c
+++ b/cmd.c
@@ -136,6 +136,16 @@ 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_layout, want_vpath, is_clone) \
 	{#name, name##_fn, want_repo, want_layout, want_vpath, is_clone}
 
@@ -162,6 +172,8 @@ struct cgit_cmd *cgit_get_cmd(void)
 		def_cmd(summary, 1, 1, 0, 0),
 		def_cmd(tag, 1, 1, 0, 0),
 		def_cmd(tree, 1, 1, 1, 0),
+		{"git-upload-pack", git_upload_pack_fn, 1, 0, 0, 1},
+		{"git-receive-pack", git_receive_pack_fn, 1, 0, 0, 1},
 	};
 	int i;
 
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);
+}
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 */
-- 
2.2.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2] Support Git over HTTP using git-http-backend
  2014-12-29 16:56 ` [PATCH v2] " bluewind
@ 2014-12-29 17:16   ` cgit
  2015-01-15 23:57     ` bluewind
  2015-01-19 16:55   ` Jason
  2015-01-19 16:58   ` Jason
  2 siblings, 1 reply; 9+ messages in thread
From: cgit @ 2014-12-29 17:16 UTC (permalink / raw)


On Mon, 29 Dec 2014 at 17:56:05, Florian Pritz wrote:
> 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 at xinu.at>
> ---
> 
> v2:
>  - git_root allocation was too small by 1
>  - change comment style to c89
> 
>  cgit.c       |  3 +++
>  cgit.h       |  1 +
>  cgitrc.5.txt |  8 ++++++++
>  cmd.c        | 12 ++++++++++++
>  ui-clone.c   | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  ui-clone.h   |  2 ++
>  6 files changed, 87 insertions(+)
> [...]

Note that directly invoking http-backend from cgit without the overhead
of execl() seems to be a bit more involved -- almost everything in
http-backend.c is marked static:

    Acked-by: Lukas Fleischer <cgit at cryptocrack.de>


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2] Support Git over HTTP using git-http-backend
  2014-12-29 17:16   ` cgit
@ 2015-01-15 23:57     ` bluewind
  0 siblings, 0 replies; 9+ messages in thread
From: bluewind @ 2015-01-15 23:57 UTC (permalink / raw)


On 29.12.2014 18:16, Lukas Fleischer wrote:
> On Mon, 29 Dec 2014 at 17:56:05, Florian Pritz wrote:
>> This saves users from the hassle of setting up git-http-backend when
>> they already run cgit.
>> 
>> References: man git-http-backend

Since this has not yet been merged and it currently conflicts with
master: Is there any interest in the patch? If yes, I'd be happy to
resolve the conflict.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: OpenPGP digital signature
URL: <http://lists.zx2c4.com/pipermail/cgit/attachments/20150116/669ef9dd/attachment.asc>


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2] Support Git over HTTP using git-http-backend
  2014-12-29 16:56 ` [PATCH v2] " bluewind
  2014-12-29 17:16   ` cgit
@ 2015-01-19 16:55   ` Jason
  2015-01-19 17:08     ` cgit
  2015-01-19 16:58   ` Jason
  2 siblings, 1 reply; 9+ messages in thread
From: Jason @ 2015-01-19 16:55 UTC (permalink / raw)


On Mon, Dec 29, 2014 at 5:56 PM, Florian Pritz <bluewind at xinu.at> wrote:
>
> +http-backend-path::
> +       Path to the git-http-backend smart HTTP backend binary.
> +http-backend-path=/usr/lib/git-core/git-http-backend
>

Instead of all this, why not just a:

execlp("git", "git", "http-backend", NULL);

This leaves resolution to PATH and git's resolver, which should be more
coherent.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.zx2c4.com/pipermail/cgit/attachments/20150119/77cfe538/attachment.html>


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2] Support Git over HTTP using git-http-backend
  2014-12-29 16:56 ` [PATCH v2] " bluewind
  2014-12-29 17:16   ` cgit
  2015-01-19 16:55   ` Jason
@ 2015-01-19 16:58   ` Jason
  2015-01-19 17:13     ` cgit
  2 siblings, 1 reply; 9+ messages in thread
From: Jason @ 2015-01-19 16:58 UTC (permalink / raw)


Do we really want to be enabling git-receive-pack? Seems like in its
present form, this could lead to some unexpected security results...

More generally, is this the right approach? Since we're linking against
git's sources anyway, couldn't any enhanced functionality be included
within cgit by calling into the right functions in the git source?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.zx2c4.com/pipermail/cgit/attachments/20150119/6bcd3310/attachment.html>


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2] Support Git over HTTP using git-http-backend
  2015-01-19 16:55   ` Jason
@ 2015-01-19 17:08     ` cgit
  0 siblings, 0 replies; 9+ messages in thread
From: cgit @ 2015-01-19 17:08 UTC (permalink / raw)


On Mon, 19 Jan 2015 at 17:55:41, Jason A. Donenfeld wrote:
> On Mon, Dec 29, 2014 at 5:56 PM, Florian Pritz <bluewind at xinu.at> wrote:
> >
> > +http-backend-path::
> > +       Path to the git-http-backend smart HTTP backend binary.
> > +http-backend-path=/usr/lib/git-core/git-http-backend
> >
> 
> Instead of all this, why not just a:
> 
> execlp("git", "git", "http-backend", NULL);
> 
> This leaves resolution to PATH and git's resolver, which should be more
> coherent.
> [...]

Making it configurable allows for using another smart HTTP backend,
though.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2] Support Git over HTTP using git-http-backend
  2015-01-19 16:58   ` Jason
@ 2015-01-19 17:13     ` cgit
  2015-01-19 17:19       ` Jason
  0 siblings, 1 reply; 9+ messages in thread
From: cgit @ 2015-01-19 17:13 UTC (permalink / raw)


On Mon, 19 Jan 2015 at 17:58:15, Jason A. Donenfeld wrote:
> Do we really want to be enabling git-receive-pack? Seems like in its
> present form, this could lead to some unexpected security results...
> 

Not sure. But note that by default, git-receive-pack is not enabled.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2] Support Git over HTTP using git-http-backend
  2015-01-19 17:13     ` cgit
@ 2015-01-19 17:19       ` Jason
  0 siblings, 0 replies; 9+ messages in thread
From: Jason @ 2015-01-19 17:19 UTC (permalink / raw)


On Mon, Jan 19, 2015 at 6:13 PM, Lukas Fleischer <cgit at cryptocrack.de>
wrote:
>
> Please check my reply to v2 of Florian's patch, almost everything in
> http-backend.c is static which makes this difficult. We would need to
> convince Junio (the current Git maintainer) to make those functions
> public and probably send patches to Git. I would say it is okay to merge
> this implementation now and eventually switch to direct function calls.
>

On the contrary, I don't see any pressing need for this functionality now,
aside from an optimization of something that already exists. So I'd say
push ahead with actually implementing this properly - i.e. convincing Junio
& friends - and then go the correct route.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.zx2c4.com/pipermail/cgit/attachments/20150119/ed2ae03c/attachment.html>


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2015-01-19 17:19 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-12-29 16:13 [PATCH] Support Git over HTTP using git-http-backend bluewind
2014-12-29 16:56 ` [PATCH v2] " bluewind
2014-12-29 17:16   ` cgit
2015-01-15 23:57     ` bluewind
2015-01-19 16:55   ` Jason
2015-01-19 17:08     ` cgit
2015-01-19 16:58   ` Jason
2015-01-19 17:13     ` cgit
2015-01-19 17:19       ` Jason

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).