diff options
-rw-r--r-- | Documentation/git-http-backend.txt | 39 | ||||
-rw-r--r-- | http-backend.c | 25 |
2 files changed, 39 insertions, 25 deletions
diff --git a/Documentation/git-http-backend.txt b/Documentation/git-http-backend.txt index 022a2433a8..99dbbfb966 100644 --- a/Documentation/git-http-backend.txt +++ b/Documentation/git-http-backend.txt @@ -41,29 +41,24 @@ http.receivepack:: URL TRANSLATION --------------- -'git-http-backend' relies on the invoking web server to perform -URL to path translation, and store the repository path into the -PATH_TRANSLATED environment variable. Most web servers will do -this translation automatically, resolving the suffix after the -CGI name relative to the server's document root. +To determine the location of the repository on disk, 'git-http-backend' +concatenates the environment variables PATH_INFO, which is set +automatically by the web server, and GIT_PROJECT_ROOT, which must be set +manually in the web server configuration. If GIT_PROJECT_ROOT is not +set, 'git-http-backend' reads PATH_TRANSLATED, which is also set +automatically by the web server. EXAMPLES -------- Apache 2.x:: - To serve all Git repositories contained within the '/git/' - subdirectory of the DocumentRoot, ensure mod_cgi and - mod_alias are enabled, and create a ScriptAlias to the CGI: + Ensure mod_cgi, mod_alias, and mod_env are enabled, set + GIT_PROJECT_ROOT (or DocumentRoot) appropriately, and + create a ScriptAlias to the CGI: + ---------------------------------------------------------------- -ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/git/ - -<Directory /usr/libexec/git-core> - Options None -</Directory> -<Files /usr/libexec/git-core/git-http-backend> - Options ExecCGI -</Files> +SetEnv GIT_PROJECT_ROOT /var/www/git +ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/ ---------------------------------------------------------------- + To enable anonymous read access but authenticated write access, @@ -78,16 +73,16 @@ require authorization with a LocationMatch directive: </LocationMatch> ---------------------------------------------------------------- + -To require authentication for both reads and writes, use a Directory +To require authentication for both reads and writes, use a Location directive around the repository, or one of its parent directories: + ---------------------------------------------------------------- -<Directory /var/www/git/private> +<Location /git/private> AuthType Basic AuthName "Private Git Access" Require group committers ... -</Directory> +</Location> ---------------------------------------------------------------- Accelerated static Apache 2.x:: @@ -97,9 +92,9 @@ Accelerated static Apache 2.x:: file contents from the file system directly to the network: + ---------------------------------------------------------------- -DocumentRoot /var/www +SetEnv GIT_PROJECT_ROOT /var/www/git -ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/git/ +ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/ Alias /git_static/ /var/www/git/ RewriteEngine on @@ -114,7 +109,7 @@ ENVIRONMENT 'git-http-backend' relies upon the CGI environment variables set by the invoking web server, including: -* PATH_TRANSLATED +* PATH_INFO (if GIT_PROJECT_ROOT is set, otherwise PATH_TRANSLATED) * REMOTE_USER * REMOTE_ADDR * CONTENT_TYPE diff --git a/http-backend.c b/http-backend.c index bfce52063f..7900cda69a 100644 --- a/http-backend.c +++ b/http-backend.c @@ -528,6 +528,26 @@ static NORETURN void die_webcgi(const char *err, va_list params) exit(0); } +static char* getdir(void) +{ + struct strbuf buf = STRBUF_INIT; + char *pathinfo = getenv("PATH_INFO"); + char *root = getenv("GIT_PROJECT_ROOT"); + char *path = getenv("PATH_TRANSLATED"); + + if (root && *root) { + if (!pathinfo || !*pathinfo) + die("GIT_PROJECT_ROOT is set but PATH_INFO is not"); + strbuf_addstr(&buf, root); + strbuf_addstr(&buf, pathinfo); + return strbuf_detach(&buf, NULL); + } else if (path && *path) { + return xstrdup(path); + } else + die("No GIT_PROJECT_ROOT or PATH_TRANSLATED from server"); + return NULL; +} + static struct service_cmd { const char *method; const char *pattern; @@ -549,7 +569,7 @@ static struct service_cmd { int main(int argc, char **argv) { char *method = getenv("REQUEST_METHOD"); - char *dir = getenv("PATH_TRANSLATED"); + char *dir; struct service_cmd *cmd = NULL; char *cmd_arg = NULL; int i; @@ -561,8 +581,7 @@ int main(int argc, char **argv) die("No REQUEST_METHOD from server"); if (!strcmp(method, "HEAD")) method = "GET"; - if (!dir) - die("No PATH_TRANSLATED from server"); + dir = getdir(); for (i = 0; i < ARRAY_SIZE(services); i++) { struct service_cmd *c = &services[i]; |