git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] git-daemon virtual hosting implementation.

From
Pierre Habouzit <madcoder@debian.org>
Date
Aug 23, 2006, 18:52 UTC
Message-ID
<11563591572194-git-send-email-madcoder@debian.org>

just add the hostname in the path when using --base-path and --user-path. this should be enough for most needs.

Signed-off-by: Pierre Habouzit <madcoder@debian.org>
---
 Here is a proposal for daemon side virtualhosting support.
 This is quite simple, and just uses the hostname in the path where it looks
 for the git repository. Only works in conjuction of --base-path or
 --user-path btw.
 Documentation/git-daemon.txt |   12 +++++++
 daemon.c                     |   73 +++++++++++++++++++++++++++++++++++-------
 2 files changed, 73 insertions(+), 12 deletions(-)
diff --git a/Documentation/git-daemon.txt b/Documentation/git-daemon.txt
index 0f7d274..ab5b232 100644
--- a/Documentation/git-daemon.txt
+++ b/Documentation/git-daemon.txt
@@ -79,6 +79,18 @@ OPTIONS
 	taken as a request to access `path/foo` repository in
 	the home directory of user `alice`.
 
+--use-vhosts::
+	Use git daemon cheap virtual hosting scheme.
++
+Used with --base-path=/foo, it will search the repositories in /foo/HOSTNAME
+instead of /foo - if you try to pull git://git.example.com/hello.git, it will
+search into /foo/git.example.com/hello.git.
++
+When using --user-path the HOSTNAME is appended to the path as well, so for
+--user-path=some/path, request to git://git.example.com/~alice/foo is taken as
+a request to access some/path/git.example.com/foo in the home directory of
+user `alice`.
+
 --verbose::
 	Log details about the incoming connections and requested files.
 
diff --git a/daemon.c b/daemon.c
index 012936f..146482c 100644
--- a/daemon.c
+++ b/daemon.c
@@ -17,7 +17,7 @@ static int reuseaddr;
 
 static const char daemon_usage[] =
 "git-daemon [--verbose] [--syslog] [--inetd | --port=n] [--export-all]\n"
-"           [--timeout=n] [--init-timeout=n] [--strict-paths]\n"
+"           [--timeout=n] [--init-timeout=n] [--use-vhosts] [--strict-paths]\n"
 "           [--base-path=path] [--user-path | --user-path=path]\n"
 "           [--reuseaddr] [--detach] [--pid-file=file] [directory...]";
 
@@ -25,6 +25,8 @@ static const char daemon_usage[] =
 static char **ok_paths;
 static int strict_paths;
 
+static int use_vhosts;
+
 /* If this is set, git-daemon-export-ok is not required */
 static int export_all_trees;
 
@@ -148,7 +150,7 @@ static int avoid_alias(char *p)
 	}
 }
 
-static char *path_ok(char *dir)
+static char *path_ok(char *dir, char *vhost)
 {
 	static char rpath[PATH_MAX];
 	char *path;
@@ -158,6 +160,11 @@ static char *path_ok(char *dir)
 		return NULL;
 	}
 
+	if (use_vhosts && !vhost) {
+		logerror("using virtual hosting, and not host= was specified !");
+		return NULL;
+	}
+
 	if (*dir == '~') {
 		if (!user_path) {
 			logerror("'%s': User-path not allowed", dir);
@@ -174,9 +181,25 @@ static char *path_ok(char *dir)
 				slash = dir + restlen;
 			namlen = slash - dir;
 			restlen -= namlen;
-			loginfo("userpath <%s>, request <%s>, namlen %d, restlen %d, slash <%s>", user_path, dir, namlen, restlen, slash);
-			snprintf(rpath, PATH_MAX, "%.*s/%s%.*s",
-				 namlen, dir, user_path, restlen, slash);
+
+			if (use_vhosts) {
+				loginfo("host <%s>, "
+					"userpath <%s>, request <%s>, "
+					"namlen %d, restlen %d, slash <%s>",
+					vhost,
+					user_path, dir,
+					namlen, restlen, slash);
+				snprintf(rpath, PATH_MAX, "%.*s/%s/%s%.*s",
+					 namlen, dir, user_path, vhost,
+					 restlen, slash);
+			} else {
+				loginfo("userpath <%s>, request <%s>, "
+					"namlen %d, restlen %d, slash <%s>",
+					user_path, dir,
+					namlen, restlen, slash);
+				snprintf(rpath, PATH_MAX, "%.*s/%s%.*s",
+					 namlen, dir, user_path, restlen, slash);
+			}
 			dir = rpath;
 		}
 	}
@@ -187,7 +210,11 @@ static char *path_ok(char *dir)
 			return NULL;
 		}
 		else {
-			snprintf(rpath, PATH_MAX, "%s%s", base_path, dir);
+			if (use_vhosts) {
+				snprintf(rpath, PATH_MAX, "%s/%s%s", base_path, vhost, dir);
+			} else {
+				snprintf(rpath, PATH_MAX, "%s%s", base_path, dir);
+			}
 			dir = rpath;
 		}
 	}
@@ -229,15 +256,19 @@ static char *path_ok(char *dir)
 	return NULL;		/* Fallthrough. Deny by default */
 }
 
-static int upload(char *dir)
+static int upload(char *dir, char *vhost)
 {
 	/* Timeout as string */
 	char timeout_buf[64];
 	const char *path;
 
-	loginfo("Request for '%s'", dir);
+	if (vhost) {
+		loginfo("Request for '%s' (host = %s)", dir, vhost);
+	} else {
+		loginfo("Request for '%s'", dir);
+	}
 
-	if (!(path = path_ok(dir)))
+	if (!(path = path_ok(dir, vhost)))
 		return -1;
 
 	/*
@@ -274,6 +305,7 @@ static int execute(struct sockaddr *addr
 {
 	static char line[1000];
 	int pktlen, len;
+        char *vhost = NULL;
 
 	if (addr) {
 		char addrbuf[256] = "";
@@ -303,15 +335,28 @@ #endif
 	alarm(0);
 
 	len = strlen(line);
-	if (pktlen != len)
+	if (pktlen != len) {
+		int arg_pos = len + 1;
+
 		loginfo("Extended attributes (%d bytes) exist <%.*s>",
 			(int) pktlen - len,
-			(int) pktlen - len, line + len + 1);
+			(int) pktlen - len, line + arg_pos);
+
+		while (arg_pos < pktlen) {
+			int arg_len = strlen(line + arg_pos);
+
+			if (!strncmp("host=", line + arg_pos, 5)) {
+				vhost = line + arg_pos + 5;
+			}
+
+			arg_pos += arg_len + 1;
+		}
+	}
 	if (len && line[len-1] == '\n')
 		line[--len] = 0;
 
 	if (!strncmp("git-upload-pack ", line, 16))
-		return upload(line+16);
+		return upload(line+16, vhost);
 
 	logerror("Protocol error: '%s'", line);
 	return -1;
@@ -762,6 +807,10 @@ int main(int argc, char **argv)
 			init_timeout = atoi(arg+15);
 			continue;
 		}
+		if (!strcmp(arg, "--use-vhosts")) {
+			use_vhosts = 1;
+			continue;
+		}
 		if (!strcmp(arg, "--strict-paths")) {
 			strict_paths = 1;
 			continue;
-- 
1.4.1.1
Next: Junio C Hamano
Message 1 of 16 in “git-daemon virtual hosting implementation.”
  1. git-daemon virtual hosting implementation.Pierre Habouzit, Aug 23, 2006
  2. Junio C HamanoAug 23, 2006
  3. Pierre HabouzitAug 23, 2006
  4. Jon LoeligerAug 24, 2006
  5. Junio C HamanoAug 24, 2006
  6. Jon LoeligerAug 24, 2006
  7. git-daemon: more powerful base-path/user-path settings, using formats.Pierre Habouzit, Aug 23, 2006
  8. Junio C HamanoAug 24, 2006
  9. Pierre HabouzitAug 24, 2006
  10. Junio C HamanoAug 27, 2006
  11. Pierre HabouzitAug 27, 2006
  12. Junio C HamanoAug 27, 2006
  13. Pierre HabouzitAug 27, 2006
  14. Jakub NarebskiAug 27, 2006
  15. Pierre HabouzitAug 27, 2006
  16. Randal L. SchwartzAug 27, 2006

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.