Skip to content

Commit

Permalink
Auto merge of #10698 - arlosi:http-slash, r=Eh2406
Browse files Browse the repository at this point in the history
Require http-registry URLs to end with a '/'

The `url` crate normalizes URLs with no path component to end in a trailing slash. This causes the current implementation to use urls containing two slashes for registries without a path component (such as `https://index.crates.io//config.json`).

This PR resolves the issue by requiring http registry URLs to end in a slash and generating paths by concatenating. A new error message is emitted for http registry URLs that do not end in a slash.

r? `@Eh2406`
  • Loading branch information
bors committed May 24, 2022
2 parents bf82412 + 2622074 commit e7c8ba7
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 15 deletions.
28 changes: 19 additions & 9 deletions src/cargo/sources/registry/http_remote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
))),
Expand All @@ -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)> {
Expand Down Expand Up @@ -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 {
Expand Down
5 changes: 1 addition & 4 deletions src/cargo/sources/registry/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<_>
};
Expand Down
13 changes: 11 additions & 2 deletions tests/testsuite/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
)
Expand Down Expand Up @@ -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()
}

0 comments on commit e7c8ba7

Please sign in to comment.