Fix handling of URLs with port in credential.helper
Credentials stored by Git for the URL `https://example.com:3000/foo/bar` use
`host=example.com:3000`. A CredentialHelper object for the same URL currently
queries the credential helper with `host=example.com` and thus can't access the
stored credentials.
@@ -22,6 +22,7 @@ pub struct CredentialHelper {
pub username: Option<String>,
protocol: Option<String>,
host: Option<String>,
+ port: Option<u16>,
path: Option<String>,
url: String,
commands: Vec<String>,
@@ -199,6 +200,7 @@ impl CredentialHelper {
let mut ret = CredentialHelper {
protocol: None,
host: None,
+ port: None,
path: None,
username: None,
url: url.to_string(),
@@ -210,6 +212,7 @@ impl CredentialHelper {
if let Some(url::Host::Domain(s)) = url.host() {
ret.host = Some(s.to_string());
}
+ ret.port = url.port();
ret.protocol = Some(url.scheme().to_string());
}
ret
@@ -408,8 +411,12 @@ impl CredentialHelper {
let _ = writeln!(stdin, "protocol={}", p);
}
if let Some(ref p) = self.host {
+ if let Some(ref p2) = self.port {
+ let _ = writeln!(stdin, "host={}:{}", p, p2);
+ } else {
let _ = writeln!(stdin, "host={}", p);
}
+ }
if let Some(ref p) = self.path {
let _ = writeln!(stdin, "path={}", p);
}
@@ -639,6 +646,19 @@ echo password=$2
assert_eq!(helper.path.as_deref(), Some("foo/bar"));
}
+ #[test]
+ fn credential_helper9() {
+ let cfg = test_cfg! {
+ "credential.helper" => "!f() { while read line; do eval $line; done; if [ \"$host\" = example.com:3000 ]; then echo username=a; echo password=b; fi; }; f"
+ };
+ let (u, p) = CredentialHelper::new("https://example.com:3000/foo/bar")
+ .config(&cfg)
+ .execute()
+ .unwrap();
+ assert_eq!(u, "a");
+ assert_eq!(p, "b");
+ }
+
#[test]
#[cfg(feature = "ssh")]
fn ssh_key_from_memory() {
