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

[PATCH v8 6/9] connect: make parse_connect_url() return the user part of the url as a separate value

From
Mike Hommey <mh@glandium.org>
Date
May 27, 2016, 02:27 UTC
Message-ID
<20160527022756.22904-7-mh@glandium.org>
In-Reply-To
<20160527022756.22904-1-mh@glandium.org>
Signed-off-by: Mike Hommey <mh@glandium.org>
---
 connect.c | 54 ++++++++++++++++++++++++++++++++++++------------------
 1 file changed, 36 insertions(+), 18 deletions(-)
diff --git a/connect.c b/connect.c
index 4be06f4..0819c25 100644
--- a/connect.c
+++ b/connect.c
@@ -588,11 +588,13 @@ static char *get_port(char *host)
  * Extract protocol and relevant parts from the specified connection URL.
  * The caller must free() the returned strings.
  */
-static enum protocol parse_connect_url(const char *url_orig, char **ret_host,
-				       char **ret_port, char **ret_path)
+static enum protocol parse_connect_url(const char *url_orig, char **ret_user,
+				       char **ret_host, char **ret_port,
+				       char **ret_path)
 {
 	char *url;
 	char *host, *path;
+	const char *user = NULL;
 	const char *port = NULL;
 	char *end;
 	int separator = '/';
@@ -650,23 +652,31 @@ static enum protocol parse_connect_url(const char *url_orig, char **ret_host,
 
 	get_host_and_port(&host, &port);
 
-	if (*host && !port) {
+	if (*host) {
 		/*
-		 * get_host_and_port does not return a port in the
-		 * [host:port]:path case. In that case, it is called with
-		 * "[host:port]" and returns "host:port" and NULL.
-		 * To support this undocumented legacy we still need to split
-		 * the port.
-		 * "host:port" may also look like "user@host:port". As the
-		 * `user` portion tends to be less strict than `host:port`,
-		 * we first put it out of the equation: since a hostname
-		 * cannot contain a '@', we start from the last '@' in the
-		 * string.
+		 * At this point, the host part may look like user@host:port.
+		 * As the `user` portion tends to be less strict than
+		 * `host:port`, we first put it out of the equation: since a
+		 * hostname cannot contain a '@', we start from the last '@'
+		 * in the string.
 		 */
 		char *end_user = strrchr(host, '@');
-		port = get_port(end_user ? end_user : host);
+		if (end_user) {
+			*end_user = '\0';
+			user = host;
+			host = end_user + 1;
+		}
 	}
+	/*
+	 * get_host_and_port does not return a port in the [host:port]:path
+	 * case. In that case, it is called with "[host:port]" and returns
+	 * "host:port" and NULL.
+	 * To support this undocumented legacy we still need to split the port.
+	 */
+	if (!port)
+		port = get_port(host);
 
+	*ret_user = user ? xstrdup(user) : NULL;
 	*ret_host = xstrdup(host);
 	*ret_port = port ? xstrdup(port) : NULL;
 	*ret_path = path;
@@ -690,7 +700,7 @@ static struct child_process no_fork = CHILD_PROCESS_INIT;
 struct child_process *git_connect(int fd[2], const char *url,
 				  const char *prog, int flags)
 {
-	char *host, *port, *path;
+	char *user, *host, *port, *path;
 	struct child_process *conn = &no_fork;
 	enum protocol protocol;
 	struct strbuf cmd = STRBUF_INIT;
@@ -700,11 +710,14 @@ struct child_process *git_connect(int fd[2], const char *url,
 	 */
 	signal(SIGCHLD, SIG_DFL);
 
-	protocol = parse_connect_url(url, &host, &port, &path);
+	protocol = parse_connect_url(url, &user, &host, &port, &path);
 	if (flags & CONNECT_DIAG_URL) {
 		printf("Diag: url=%s\n", url ? url : "NULL");
 		printf("Diag: protocol=%s\n", prot_name(protocol));
-		printf("Diag: userandhost=%s\n", host ? host : "NULL");
+		if (user)
+			printf("Diag: userandhost=%s@%s\n", user, host);
+		else
+			printf("Diag: userandhost=%s\n", host ? host : "NULL");
 		printf("Diag: port=%s\n", port ? port : "NONE");
 		printf("Diag: path=%s\n", path ? path : "NULL");
 		conn = NULL;
@@ -813,7 +826,11 @@ struct child_process *git_connect(int fd[2], const char *url,
 				argv_array_push(&conn->args, putty ? "-P" : "-p");
 				argv_array_push(&conn->args, port);
 			}
-			argv_array_push(&conn->args, host);
+			if (user)
+				argv_array_pushf(&conn->args, "%s@%s",
+						 user, host);
+			else
+				argv_array_push(&conn->args, host);
 		} else {
 			transport_check_allowed("file");
 		}
@@ -826,6 +843,7 @@ struct child_process *git_connect(int fd[2], const char *url,
 		fd[1] = conn->in;  /* write to child's stdin */
 		strbuf_release(&cmd);
 	}
+	free(user);
 	free(host);
 	free(port);
 	free(path);
-- 
2.8.3
Previous: Mike HommeyNext: Mike Hommey
Message 7 of 16 in “connect: various cleanups”
  1. 0/9 connect: various cleanupsMike Hommey, May 27, 2016
  2. 1/9 connect: document why we sometimes call get_port after get_host_and_portMike Hommey, May 27, 2016
  3. 2/9 connect: call get_host_and_port() earlierMike Hommey, May 27, 2016
  4. 3/9 connect: re-derive a host:port string from the separate host and port variablesMike Hommey, May 27, 2016
  5. 4/9 connect: make parse_connect_url() return separated host and portMike Hommey, May 27, 2016
  6. 5/9 connect: group CONNECT_DIAG_URL handling codeMike Hommey, May 27, 2016
  7. 6/9 connect: make parse_connect_url() return the user part of the url as a separate valueMike Hommey, May 27, 2016
  8. 7/9 connect: change the --diag-url output to separate user and hostMike Hommey, May 27, 2016
  9. 8/9 connect: actively reject git:// urls with a user partMike Hommey, May 27, 2016
  10. 9/9 connect: move ssh command line preparation to a separate functionMike Hommey, May 27, 2016
  11. Torsten BögershausenMay 27, 2016
  12. Mike HommeyMay 27, 2016
  13. Torsten BögershausenMay 28, 2016
  14. Mike HommeyMay 28, 2016
  15. Torsten BögershausenMay 28, 2016
  16. Mike HommeyMay 28, 2016

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.