Commit f30d91ce48f444031b1c65749758008c6f204130

Ben Straub 2013-09-26T11:03:27

Refactor URL handling to use library call

diff --git a/src/transports/winhttp.c b/src/transports/winhttp.c
index 377f2ef..7ec936d 100644
--- a/src/transports/winhttp.c
+++ b/src/transports/winhttp.c
@@ -420,70 +420,6 @@ static void free_connection_data(winhttp_subtransport *t)
 	}
 }
 
-static int set_connection_data_from_url(
-	winhttp_subtransport *t, const char *url, const char *service_suffix)
-{
-	int error = 0;
-	const char *default_port = NULL;
-	char *original_host = NULL;
-	const char *original_url = url;
-
-	if (!git__prefixcmp(url, prefix_http)) {
-		url += strlen(prefix_http);
-		default_port = "80";
-
-		if (t->use_ssl) {
-			giterr_set(GITERR_NET, "Redirect from HTTPS to HTTP not allowed");
-			return -1;
-		}
-	}
-
-	if (!git__prefixcmp(url, prefix_https)) {
-		url += strlen(prefix_https);
-		default_port = "443";
-		t->use_ssl = 1;
-	}
-
-	if (!default_port) {
-		giterr_set(GITERR_NET, "Unrecognized URL prefix");
-		return -1;
-	}
-
-	/* preserve original host name for checking */
-	original_host = t->host;
-	t->host = NULL;
-
-	free_connection_data(t);
-
-	error = gitno_extract_url_parts(
-		&t->host, &t->port, &t->user_from_url, &t->pass_from_url,
-		url, default_port);
-
-	if (!error) {
-		const char *path = strchr(url, '/');
-		size_t pathlen = strlen(path);
-		size_t suffixlen = service_suffix ? strlen(service_suffix) : 0;
-
-		if (suffixlen &&
-			!memcmp(path + pathlen - suffixlen, service_suffix, suffixlen))
-			t->path = git__strndup(path, pathlen - suffixlen);
-		else
-			t->path = git__strdup(path);
-
-		/* Allow '/'-led urls, or a change of protocol */
-		if (original_host != NULL) {
-			if (strcmp(original_host, t->host) && original_url[0] != '/') {
-				giterr_set(GITERR_NET, "Cross host redirect not allowed");
-				error = -1;
-			}
-
-			git__free(original_host);
-		}
-	}
-
-	return error;
-}
-
 static int winhttp_connect(
 	winhttp_subtransport *t,
 	const char *url)
@@ -699,7 +635,18 @@ replay:
 
 			if (!git__prefixcmp_icase(location8, prefix_https)) {
 				/* Upgrade to secure connection; disconnect and start over */
-				set_connection_data_from_url(t, location8, s->service_url);
+				gitno_connection_data data = { 0 };
+				if (gitno_connection_data_from_url(&data, location8, s->service_url, t->host, t->use_ssl) < 0) {
+					gitno_connection_data_free_ptrs(&data);
+					return -1;
+				}
+				free_connection_data(t);
+				t->host = data.host;
+				t->port = data.port;
+				t->path = data.path;
+				t->user_from_url = data.user;
+				t->pass_from_url = data.pass;
+				t->use_ssl = data.use_ssl;
 				winhttp_connect(t, location8);
 			}
 
@@ -1101,10 +1048,22 @@ static int winhttp_action(
 	winhttp_stream *s;
 	int ret = -1;
 
-	if (!t->connection &&
-		(set_connection_data_from_url(t, url, NULL) < 0 ||
-		 winhttp_connect(t, url) < 0))
-		return -1;
+	if (!t->connection) {
+		gitno_connection_data data = { 0 };
+		if (gitno_connection_data_from_url(&data, url, NULL, NULL, false) < 0) {
+			gitno_connection_data_free_ptrs(&data);
+			return -1;
+		}
+		free_connection_data(t);
+		t->host = data.host;
+		t->port = data.port;
+		t->path = data.path;
+		t->user_from_url = data.user;
+		t->pass_from_url = data.pass;
+		t->use_ssl = data.use_ssl;
+		if (winhttp_connect(t, url) < 0)
+			return -1;
+	}
 
 	if (winhttp_stream_alloc(t, &s) < 0)
 		return -1;