mirror of
https://github.com/rust-lang/cargo
synced 2024-10-02 14:04:23 +00:00
873f69c0b8
They were tweaked a bit recently so let's enusre they're not too strict.
214 lines
6.2 KiB
Rust
214 lines
6.2 KiB
Rust
extern crate bufstream;
|
|
extern crate git2;
|
|
extern crate cargotest;
|
|
extern crate hamcrest;
|
|
|
|
use std::collections::HashSet;
|
|
use std::io::prelude::*;
|
|
use std::net::TcpListener;
|
|
use std::thread;
|
|
|
|
use bufstream::BufStream;
|
|
use cargotest::support::paths;
|
|
use cargotest::support::{project, execs};
|
|
use hamcrest::assert_that;
|
|
|
|
// Test that HTTP auth is offered from `credential.helper`
|
|
#[test]
|
|
fn http_auth_offered() {
|
|
let server = TcpListener::bind("127.0.0.1:0").unwrap();
|
|
let addr = server.local_addr().unwrap();
|
|
|
|
fn headers(rdr: &mut BufRead) -> HashSet<String> {
|
|
let valid = ["GET", "Authorization", "Accept", "User-Agent"];
|
|
rdr.lines().map(|s| s.unwrap())
|
|
.take_while(|s| s.len() > 2)
|
|
.map(|s| s.trim().to_string())
|
|
.filter(|s| {
|
|
valid.iter().any(|prefix| s.starts_with(*prefix))
|
|
})
|
|
.collect()
|
|
}
|
|
|
|
let t = thread::spawn(move|| {
|
|
let mut conn = BufStream::new(server.accept().unwrap().0);
|
|
let req = headers(&mut conn);
|
|
let user_agent = if cfg!(windows) {
|
|
"User-Agent: git/1.0 (libgit2 0.26.0)"
|
|
} else {
|
|
"User-Agent: git/2.0 (libgit2 0.26.0)"
|
|
};
|
|
conn.write_all(b"\
|
|
HTTP/1.1 401 Unauthorized\r\n\
|
|
WWW-Authenticate: Basic realm=\"wheee\"\r\n
|
|
\r\n\
|
|
").unwrap();
|
|
assert_eq!(req, vec![
|
|
"GET /foo/bar/info/refs?service=git-upload-pack HTTP/1.1",
|
|
"Accept: */*",
|
|
user_agent,
|
|
].into_iter().map(|s| s.to_string()).collect());
|
|
drop(conn);
|
|
|
|
let mut conn = BufStream::new(server.accept().unwrap().0);
|
|
let req = headers(&mut conn);
|
|
conn.write_all(b"\
|
|
HTTP/1.1 401 Unauthorized\r\n\
|
|
WWW-Authenticate: Basic realm=\"wheee\"\r\n
|
|
\r\n\
|
|
").unwrap();
|
|
assert_eq!(req, vec![
|
|
"GET /foo/bar/info/refs?service=git-upload-pack HTTP/1.1",
|
|
"Authorization: Basic Zm9vOmJhcg==",
|
|
"Accept: */*",
|
|
user_agent,
|
|
].into_iter().map(|s| s.to_string()).collect());
|
|
});
|
|
|
|
let script = project("script")
|
|
.file("Cargo.toml", r#"
|
|
[project]
|
|
name = "script"
|
|
version = "0.0.1"
|
|
authors = []
|
|
"#)
|
|
.file("src/main.rs", r#"
|
|
fn main() {
|
|
println!("username=foo");
|
|
println!("password=bar");
|
|
}
|
|
"#)
|
|
.build();
|
|
|
|
assert_that(script.cargo("build").arg("-v"),
|
|
execs().with_status(0));
|
|
let script = script.bin("script");
|
|
|
|
let config = paths::home().join(".gitconfig");
|
|
let mut config = git2::Config::open(&config).unwrap();
|
|
config.set_str("credential.helper",
|
|
&script.display().to_string()).unwrap();
|
|
|
|
let p = project("foo")
|
|
.file("Cargo.toml", &format!(r#"
|
|
[project]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
authors = []
|
|
|
|
[dependencies.bar]
|
|
git = "http://127.0.0.1:{}/foo/bar"
|
|
"#, addr.port()))
|
|
.file("src/main.rs", "")
|
|
.file(".cargo/config","\
|
|
[net]
|
|
retry = 0
|
|
")
|
|
.build();
|
|
|
|
assert_that(p.cargo("build"),
|
|
execs().with_status(101).with_stderr(&format!("\
|
|
[UPDATING] git repository `http://{addr}/foo/bar`
|
|
[ERROR] failed to load source for a dependency on `bar`
|
|
|
|
Caused by:
|
|
Unable to update http://{addr}/foo/bar
|
|
|
|
Caused by:
|
|
failed to clone into: [..]
|
|
|
|
Caused by:
|
|
failed to authenticate when downloading repository
|
|
attempted to find username/password via `credential.helper`, but [..]
|
|
|
|
To learn more, run the command again with --verbose.
|
|
",
|
|
addr = addr)));
|
|
|
|
t.join().ok().unwrap();
|
|
}
|
|
|
|
// Boy, sure would be nice to have a TLS implementation in rust!
|
|
#[test]
|
|
fn https_something_happens() {
|
|
let server = TcpListener::bind("127.0.0.1:0").unwrap();
|
|
let addr = server.local_addr().unwrap();
|
|
let t = thread::spawn(move|| {
|
|
let mut conn = server.accept().unwrap().0;
|
|
drop(conn.write(b"1234"));
|
|
drop(conn.shutdown(std::net::Shutdown::Write));
|
|
drop(conn.read(&mut [0; 16]));
|
|
});
|
|
|
|
let p = project("foo")
|
|
.file("Cargo.toml", &format!(r#"
|
|
[project]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
authors = []
|
|
|
|
[dependencies.bar]
|
|
git = "https://127.0.0.1:{}/foo/bar"
|
|
"#, addr.port()))
|
|
.file("src/main.rs", "")
|
|
.file(".cargo/config","\
|
|
[net]
|
|
retry = 0
|
|
")
|
|
.build();
|
|
|
|
assert_that(p.cargo("build").arg("-v"),
|
|
execs().with_status(101).with_stderr_contains(&format!("\
|
|
[UPDATING] git repository `https://{addr}/foo/bar`
|
|
", addr = addr))
|
|
.with_stderr_contains(&format!("\
|
|
Caused by:
|
|
{errmsg}
|
|
",
|
|
errmsg = if cfg!(windows) {
|
|
"[..]failed to send request: [..]"
|
|
} else if cfg!(target_os = "macos") {
|
|
// OSX is difficult to tests as some builds may use
|
|
// Security.framework and others may use OpenSSL. In that case let's
|
|
// just not verify the error message here.
|
|
"[..]"
|
|
} else {
|
|
"[..]SSL error: [..]"
|
|
})));
|
|
|
|
t.join().ok().unwrap();
|
|
}
|
|
|
|
// Boy, sure would be nice to have an SSH implementation in rust!
|
|
#[test]
|
|
fn ssh_something_happens() {
|
|
let server = TcpListener::bind("127.0.0.1:0").unwrap();
|
|
let addr = server.local_addr().unwrap();
|
|
let t = thread::spawn(move|| {
|
|
drop(server.accept().unwrap());
|
|
});
|
|
|
|
let p = project("foo")
|
|
.file("Cargo.toml", &format!(r#"
|
|
[project]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
authors = []
|
|
|
|
[dependencies.bar]
|
|
git = "ssh://127.0.0.1:{}/foo/bar"
|
|
"#, addr.port()))
|
|
.file("src/main.rs", "")
|
|
.build();
|
|
|
|
assert_that(p.cargo("build").arg("-v"),
|
|
execs().with_status(101).with_stderr_contains(&format!("\
|
|
[UPDATING] git repository `ssh://{addr}/foo/bar`
|
|
", addr = addr))
|
|
.with_stderr_contains("\
|
|
Caused by:
|
|
[..]failed to start SSH session: Failed getting banner[..]
|
|
"));
|
|
t.join().ok().unwrap();
|
|
}
|