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> { impl<'cfg> HttpRegistry<'cfg> {
pub fn new(source_id: SourceId, config: &'cfg Config, name: &str) -> HttpRegistry<'cfg> { pub fn new(
let url = source_id source_id: SourceId,
.url() config: &'cfg Config,
.to_string() 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_start_matches("sparse+")
.trim_end_matches('/')
.into_url() .into_url()
.expect("a url with the protocol stripped should still be valid"); .expect("a url with the protocol stripped should still be valid");
HttpRegistry { Ok(HttpRegistry {
index_path: config.registry_index_path().join(name), index_path: config.registry_index_path().join(name),
cache_path: config.registry_cache_path().join(name), cache_path: config.registry_cache_path().join(name),
source_id, source_id,
@ -149,7 +158,7 @@ impl<'cfg> HttpRegistry<'cfg> {
pending_ids: HashMap::new(), pending_ids: HashMap::new(),
results: HashMap::new(), results: HashMap::new(),
progress: RefCell::new(Some(Progress::with_style( progress: RefCell::new(Some(Progress::with_style(
"Fetching", "Fetch",
ProgressStyle::Ratio, ProgressStyle::Ratio,
config, config,
))), ))),
@ -159,7 +168,7 @@ impl<'cfg> HttpRegistry<'cfg> {
requested_update: false, requested_update: false,
fetch_started: false, fetch_started: false,
registry_config: None, registry_config: None,
} })
} }
fn handle_http_header(buf: &[u8]) -> Option<(&str, &str)> { fn handle_http_header(buf: &[u8]) -> Option<(&str, &str)> {
@ -245,7 +254,8 @@ impl<'cfg> HttpRegistry<'cfg> {
} }
fn full_url(&self, path: &Path) -> String { 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 { fn is_fresh(&self, path: &Path) -> bool {

View File

@ -546,10 +546,7 @@ impl<'cfg> RegistrySource<'cfg> {
) -> CargoResult<RegistrySource<'cfg>> { ) -> CargoResult<RegistrySource<'cfg>> {
let name = short_name(source_id); let name = short_name(source_id);
let ops = if source_id.url().scheme().starts_with("sparse+") { let ops = if source_id.url().scheme().starts_with("sparse+") {
if !config.cli_unstable().http_registry { Box::new(http_remote::HttpRegistry::new(source_id, config, &name)?) as Box<_>
anyhow::bail!("Usage of HTTP-based registries requires `-Z http-registry`");
}
Box::new(http_remote::HttpRegistry::new(source_id, config, &name)) as Box<_>
} else { } else {
Box::new(remote::RemoteRegistry::new(source_id, config, &name)) as Box<_> 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' replace-with = 'dummy-registry'
[source.dummy-registry] [source.dummy-registry]
registry = 'sparse+http://{}' registry = 'sparse+http://{}/'
", ",
addr addr
) )
@ -2680,6 +2680,15 @@ fn http_requires_z_flag() {
p.cargo("build") p.cargo("build")
.with_status(101) .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(); .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()
}