http-backend: add GIT_PROJECT_ROOT environment var
Add a new environment variable, GIT_PROJECT_ROOT, to override the method of using PATH_TRANSLATED to find the git repository on disk. This makes it much easier to configure the web server, especially when the web server's DocumentRoot does not contain the git repositories, which is the usual case. Signed-off-by: Mark Lodato <lodatom@gmail.com> Signed-off-by: Shawn O. Pearce <spearce@spearce.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Mark Lodato committed
Oct 30, 2009 at 17:47 UTC
917adc036086f52b0277ff03d10b7044c9d9d0d2
2 files changed
+39
-25
Documentation/git-http-backend.txt
+17
-22
@@ -41,29 +41,24 @@ http.receivepack::
41
42
URL TRANSLATION
43
---------------
44
-'git-http-backend' relies on the invoking web server to perform
45
-URL to path translation, and store the repository path into the
46
-PATH_TRANSLATED environment variable. Most web servers will do
47
-this translation automatically, resolving the suffix after the
48
-CGI name relative to the server's document root.
44
+To determine the location of the repository on disk, 'git-http-backend'
45
+concatenates the environment variables PATH_INFO, which is set
46
+automatically by the web server, and GIT_PROJECT_ROOT, which must be set
47
+manually in the web server configuration. If GIT_PROJECT_ROOT is not
48
+set, 'git-http-backend' reads PATH_TRANSLATED, which is also set
49
+automatically by the web server.
50
51
EXAMPLES
52
--------
53
54
Apache 2.x::
54
- To serve all Git repositories contained within the '/git/'
55
- subdirectory of the DocumentRoot, ensure mod_cgi and
56
- mod_alias are enabled, and create a ScriptAlias to the CGI:
55
+ Ensure mod_cgi, mod_alias, and mod_env are enabled, set
56
+ GIT_PROJECT_ROOT (or DocumentRoot) appropriately, and
57
+ create a ScriptAlias to the CGI:
58
+
59
----------------------------------------------------------------
59
-ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/git/
60
-
61
-<Directory /usr/libexec/git-core>
62
- Options None
63
-</Directory>
64
-<Files /usr/libexec/git-core/git-http-backend>
65
- Options ExecCGI
66
-</Files>
60
+SetEnv GIT_PROJECT_ROOT /var/www/git
61
+ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/
62
----------------------------------------------------------------
63
+
64
To enable anonymous read access but authenticated write access,
@@ -78,16 +73,16 @@ require authorization with a LocationMatch directive:
73
</LocationMatch>
74
----------------------------------------------------------------
75
+
81
-To require authentication for both reads and writes, use a Directory
76
+To require authentication for both reads and writes, use a Location
77
directive around the repository, or one of its parent directories:
78
+
79
----------------------------------------------------------------
85
-<Directory /var/www/git/private>
80
+<Location /git/private>
81
AuthType Basic
82
AuthName "Private Git Access"
83
Require group committers
84
...
90
-</Directory>
85
+</Location>
86
----------------------------------------------------------------
87
88
Accelerated static Apache 2.x::
@@ -97,9 +92,9 @@ Accelerated static Apache 2.x::
92
file contents from the file system directly to the network:
93
+
94
----------------------------------------------------------------
100
-DocumentRoot /var/www
95
+SetEnv GIT_PROJECT_ROOT /var/www/git
96
102
-ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/git/
97
+ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/
98
Alias /git_static/ /var/www/git/
99
100
RewriteEngine on
@@ -114,7 +109,7 @@ ENVIRONMENT
109
'git-http-backend' relies upon the CGI environment variables set
110
by the invoking web server, including:
111
117
-* PATH_TRANSLATED
112
+* PATH_INFO (if GIT_PROJECT_ROOT is set, otherwise PATH_TRANSLATED)
113
* REMOTE_USER
114
* REMOTE_ADDR
115
* CONTENT_TYPE
http-backend.c
+22
-3
@@ -528,6 +528,26 @@ static NORETURN void die_webcgi(const char *err, va_list params)
528
exit(0);
529
}
530
531
+static char* getdir(void)
532
+{
533
+ struct strbuf buf = STRBUF_INIT;
534
+ char *pathinfo = getenv("PATH_INFO");
535
+ char *root = getenv("GIT_PROJECT_ROOT");
536
+ char *path = getenv("PATH_TRANSLATED");
537
+
538
+ if (root && *root) {
539
+ if (!pathinfo || !*pathinfo)
540
+ die("GIT_PROJECT_ROOT is set but PATH_INFO is not");
541
+ strbuf_addstr(&buf, root);
542
+ strbuf_addstr(&buf, pathinfo);
543
+ return strbuf_detach(&buf, NULL);
544
+ } else if (path && *path) {
545
+ return xstrdup(path);
546
+ } else
547
+ die("No GIT_PROJECT_ROOT or PATH_TRANSLATED from server");
548
+ return NULL;
549
+}
550
+
551
static struct service_cmd {
552
const char *method;
553
const char *pattern;
@@ -549,7 +569,7 @@ static struct service_cmd {
569
int main(int argc, char **argv)
570
{
571
char *method = getenv("REQUEST_METHOD");
552
- char *dir = getenv("PATH_TRANSLATED");
572
+ char *dir;
573
struct service_cmd *cmd = NULL;
574
char *cmd_arg = NULL;
575
int i;
@@ -561,8 +581,7 @@ int main(int argc, char **argv)
581
die("No REQUEST_METHOD from server");
582
if (!strcmp(method, "HEAD"))
583
method = "GET";
564
- if (!dir)
565
- die("No PATH_TRANSLATED from server");
584
+ dir = getdir();
585
586
for (i = 0; i < ARRAY_SIZE(services); i++) {
587
struct service_cmd *c = &services[i];