Commit 54ffc1f773369d797e4065fcd62719cd4c22c04c

Ben Straub 2013-01-31T14:41:01

HTTP: use creds in url if available

diff --git a/src/transports/http.c b/src/transports/http.c
index 6c116d8..964bafb 100644
--- a/src/transports/http.c
+++ b/src/transports/http.c
@@ -63,6 +63,7 @@ typedef struct {
 	char *user_from_url;
 	char *pass_from_url;
 	git_cred *cred;
+	git_cred *url_cred;
 	http_authmechanism_t auth_mechanism;
 	unsigned connected : 1,
 		use_ssl : 1;
@@ -146,6 +147,14 @@ static int gen_request(
 		apply_basic_credential(buf, t->cred) < 0)
 		return -1;
 
+	/* Use url-parsed basic auth if username and password are both provided */
+	if (!t->cred && t->user_from_url && t->pass_from_url) {
+		if (!t->url_cred &&
+			 git_cred_userpass_plaintext_new(&t->url_cred, t->user_from_url, t->pass_from_url) < 0)
+			return -1;
+		if (apply_basic_credential(buf, t->url_cred) < 0) return -1;
+	}
+
 	git_buf_puts(buf, "\r\n");
 
 	if (git_buf_oom(buf))
@@ -812,6 +821,11 @@ static int http_close(git_smart_subtransport *subtransport)
 		t->cred = NULL;
 	}
 
+	if (t->url_cred) {
+		t->url_cred->free(t->url_cred);
+		t->url_cred = NULL;
+	}
+
 	if (t->host) {
 		git__free(t->host);
 		t->host = NULL;
diff --git a/src/transports/winhttp.c b/src/transports/winhttp.c
index 4ac085e..780b84e 100644
--- a/src/transports/winhttp.c
+++ b/src/transports/winhttp.c
@@ -960,6 +960,11 @@ static int winhttp_close(git_smart_subtransport *subtransport)
 		t->cred = NULL;
 	}
 
+	if (t->url_cred) {
+		t->url_cred->free(t->url_cred);
+		t->url_cred = NULL;
+	}
+
 	if (t->connection) {
 		if (!WinHttpCloseHandle(t->connection)) {
 			giterr_set(GITERR_OS, "Unable to close connection");
diff --git a/tests-clar/online/clone.c b/tests-clar/online/clone.c
index 0bc7440..6a46fa5 100644
--- a/tests-clar/online/clone.c
+++ b/tests-clar/online/clone.c
@@ -8,6 +8,7 @@
 #define LIVE_EMPTYREPO_URL "http://github.com/libgit2/TestEmptyRepository"
 #define BB_REPO_URL "https://libgit2@bitbucket.org/libgit2/testgitrepository.git"
 #define BB_REPO_URL_WITH_PASS "https://libgit2:libgit2@bitbucket.org/libgit2/testgitrepository.git"
+#define BB_REPO_URL_WITH_WRONG_PASS "https://libgit2:wrong@bitbucket.org/libgit2/testgitrepository.git"
 
 static git_repository *g_repo;
 static git_clone_options g_options;
@@ -169,7 +170,15 @@ void test_online_clone__bitbucket_style(void)
 	git_repository_free(g_repo); g_repo = NULL;
 	cl_fixture_cleanup("./foo");
 
+	/* User and pass from URL */
+	user_pass.password = "wrong";
 	cl_git_pass(git_clone(&g_repo, BB_REPO_URL_WITH_PASS, "./foo", &g_options));
 	git_repository_free(g_repo); g_repo = NULL;
 	cl_fixture_cleanup("./foo");
+
+	/* Wrong password in URL, fall back to user_pass */
+	user_pass.password = "libgit2";
+	cl_git_pass(git_clone(&g_repo, BB_REPO_URL_WITH_WRONG_PASS, "./foo", &g_options));
+	git_repository_free(g_repo); g_repo = NULL;
+	cl_fixture_cleanup("./foo");
 }