Commit 05c1fb8a593c6aeb3869822ccc5cd551ba56d87f

Josh Bleecher Snyder 2019-12-06T11:04:40

http: avoid generating double slashes in url Prior to this change, given a remote url with a trailing slash, such as http://localhost/a/, service requests would contain a double slash: http://localhost/a//info/refs?service=git-receive-pack. Detect and prevent that. Updates #5321

diff --git a/src/transports/http.c b/src/transports/http.c
index 47094f7..b581d6f 100644
--- a/src/transports/http.c
+++ b/src/transports/http.c
@@ -183,7 +183,11 @@ static int gen_request(
 {
 	http_subtransport *t = OWNING_SUBTRANSPORT(s);
 	const char *path = t->server.url.path ? t->server.url.path : "/";
+	const char *service_url = s->service_url;
 	size_t i;
+	/* If path already ends in /, remove the leading slash from service_url */
+	if ((git__suffixcmp(path, "/") == 0) && (git__prefixcmp(service_url, "/") == 0))
+		service_url++;
 
 	if (t->proxy_opts.type == GIT_PROXY_SPECIFIED)
 		git_buf_printf(buf, "%s %s://%s:%s%s%s HTTP/1.1\r\n",
@@ -191,10 +195,10 @@ static int gen_request(
 			t->server.url.scheme,
 			t->server.url.host,
 			t->server.url.port,
-			path, s->service_url);
+			path, service_url);
 	else
 		git_buf_printf(buf, "%s %s%s HTTP/1.1\r\n",
-			s->verb, path, s->service_url);
+			s->verb, path, service_url);
 
 	git_buf_puts(buf, "User-Agent: ");
 	git_http__user_agent(buf);
diff --git a/src/transports/winhttp.c b/src/transports/winhttp.c
index 688b536..3a4497d 100644
--- a/src/transports/winhttp.c
+++ b/src/transports/winhttp.c
@@ -373,11 +373,15 @@ static int winhttp_stream_connect(winhttp_stream *s)
 	int default_connect_timeout = DEFAULT_CONNECT_TIMEOUT;
 	DWORD autologon_policy = WINHTTP_AUTOLOGON_SECURITY_LEVEL_HIGH;
 
+	const char *service_url = s->service_url;
 	size_t i;
 	const git_proxy_options *proxy_opts;
 
+	/* If path already ends in /, remove the leading slash from service_url */
+	if ((git__suffixcmp(t->server.url.path, "/") == 0) && (git__prefixcmp(service_url, "/") == 0))
+		service_url++;
 	/* Prepare URL */
-	git_buf_printf(&buf, "%s%s", t->server.url.path, s->service_url);
+	git_buf_printf(&buf, "%s%s", t->server.url.path, service_url);
 
 	if (git_buf_oom(&buf))
 		return -1;