Require http-registry URLs to end with a '/'

This commit is contained in:
Arlo Siemsen 2022-05-23 21:39:23 -05:00
parent 11d4599d32
commit 2622074d43
3 changed files with 31 additions and 15 deletions

View File

@ -126,16 +126,25 @@ struct CompletedDownload {
}
impl<'cfg> HttpRegistry<'cfg> {
pub fn new(source_id: SourceId, config: &'cfg Config, name: &str) -> HttpRegistry<'cfg> {
let url = source_id
.url()
.to_string()
pub fn new(
source_id: SourceId,
config: &'cfg Config,
name: &str,
) -> CargoResult<HttpRegistry<'cfg>> {
if !config.cli_unstable().http_registry {
anyhow::bail!("usage of HTTP-based registries requires `-Z http-registry`");
}
let url = source_id.url().as_str();
// Ensure the url ends with a slash so we can concatenate paths.
if !url.ends_with('/') {
anyhow::bail!("registry url must end in a slash `/`: {url}")
}
let url = url
.trim_start_matches("sparse+")
.trim_end_matches('/')
.into_url()
.expect("a url with the protocol stripped should still be valid");
HttpRegistry {
Ok(HttpRegistry {
index_path: config.registry_index_path().join(name),
cache_path: config.registry_cache_path().join(name),
source_id,
@ -149,7 +158,7 @@ impl<'cfg> HttpRegistry<'cfg> {
pending_ids: HashMap::new(),
results: HashMap::new(),
progress: RefCell::new(Some(Progress::with_style(
"Fetching",
"Fetch",
ProgressStyle::Ratio,
config,
))),
@ -159,7 +168,7 @@ impl<'cfg> HttpRegistry<'cfg> {
requested_update: false,
fetch_started: false,
registry_config: None,
}
})
}
fn handle_http_header(buf: &[u8]) -> Option<(&str, &str)> {
@ -245,7 +254,8 @@ impl<'cfg> HttpRegistry<'cfg> {
}
fn full_url(&self, path: &Path) -> String {
format!("{}/{}", self.url, path.display())
// self.url always ends with a slash.
format!("{}{}", self.url, path.display())
}
fn is_fresh(&self, path: &Path) -> bool {

View File

@ -546,10 +546,7 @@ impl<'cfg> RegistrySource<'cfg> {
) -> CargoResult<RegistrySource<'cfg>> {
let name = short_name(source_id);
let ops = if source_id.url().scheme().starts_with("sparse+") {
if !config.cli_unstable().http_registry {
anyhow::bail!("Usage of HTTP-based registries requires `-Z http-registry`");
}
Box::new(http_remote::HttpRegistry::new(source_id, config, &name)) as Box<_>
Box::new(http_remote::HttpRegistry::new(source_id, config, &name)?) as Box<_>
} else {
Box::new(remote::RemoteRegistry::new(source_id, config, &name)) as Box<_>
};

View File

@ -41,7 +41,7 @@ fn configure_source_replacement_for_http(addr: &str) {
replace-with = 'dummy-registry'
[source.dummy-registry]
registry = 'sparse+http://{}'
registry = 'sparse+http://{}/'
",
addr
)
@ -2680,6 +2680,15 @@ fn http_requires_z_flag() {
p.cargo("build")
.with_status(101)
.with_stderr_contains(" Usage of HTTP-based registries requires `-Z http-registry`")
.with_stderr_contains(" usage of HTTP-based registries requires `-Z http-registry`")
.run();
}
#[cargo_test]
fn http_requires_trailing_slash() {
cargo_process("-Z http-registry install bar --index sparse+https://index.crates.io")
.masquerade_as_nightly_cargo()
.with_status(101)
.with_stderr("[ERROR] registry url must end in a slash `/`: sparse+https://index.crates.io")
.run()
}