Skip to content

Commit 2622074

Browse files
committed
Require http-registry URLs to end with a '/'
1 parent 11d4599 commit 2622074

File tree

3 files changed

+31
-15
lines changed

3 files changed

+31
-15
lines changed

src/cargo/sources/registry/http_remote.rs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -126,16 +126,25 @@ struct CompletedDownload {
126126
}
127127

128128
impl<'cfg> HttpRegistry<'cfg> {
129-
pub fn new(source_id: SourceId, config: &'cfg Config, name: &str) -> HttpRegistry<'cfg> {
130-
let url = source_id
131-
.url()
132-
.to_string()
129+
pub fn new(
130+
source_id: SourceId,
131+
config: &'cfg Config,
132+
name: &str,
133+
) -> CargoResult<HttpRegistry<'cfg>> {
134+
if !config.cli_unstable().http_registry {
135+
anyhow::bail!("usage of HTTP-based registries requires `-Z http-registry`");
136+
}
137+
let url = source_id.url().as_str();
138+
// Ensure the url ends with a slash so we can concatenate paths.
139+
if !url.ends_with('/') {
140+
anyhow::bail!("registry url must end in a slash `/`: {url}")
141+
}
142+
let url = url
133143
.trim_start_matches("sparse+")
134-
.trim_end_matches('/')
135144
.into_url()
136145
.expect("a url with the protocol stripped should still be valid");
137146

138-
HttpRegistry {
147+
Ok(HttpRegistry {
139148
index_path: config.registry_index_path().join(name),
140149
cache_path: config.registry_cache_path().join(name),
141150
source_id,
@@ -149,7 +158,7 @@ impl<'cfg> HttpRegistry<'cfg> {
149158
pending_ids: HashMap::new(),
150159
results: HashMap::new(),
151160
progress: RefCell::new(Some(Progress::with_style(
152-
"Fetching",
161+
"Fetch",
153162
ProgressStyle::Ratio,
154163
config,
155164
))),
@@ -159,7 +168,7 @@ impl<'cfg> HttpRegistry<'cfg> {
159168
requested_update: false,
160169
fetch_started: false,
161170
registry_config: None,
162-
}
171+
})
163172
}
164173

165174
fn handle_http_header(buf: &[u8]) -> Option<(&str, &str)> {
@@ -245,7 +254,8 @@ impl<'cfg> HttpRegistry<'cfg> {
245254
}
246255

247256
fn full_url(&self, path: &Path) -> String {
248-
format!("{}/{}", self.url, path.display())
257+
// self.url always ends with a slash.
258+
format!("{}{}", self.url, path.display())
249259
}
250260

251261
fn is_fresh(&self, path: &Path) -> bool {

src/cargo/sources/registry/mod.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -546,10 +546,7 @@ impl<'cfg> RegistrySource<'cfg> {
546546
) -> CargoResult<RegistrySource<'cfg>> {
547547
let name = short_name(source_id);
548548
let ops = if source_id.url().scheme().starts_with("sparse+") {
549-
if !config.cli_unstable().http_registry {
550-
anyhow::bail!("Usage of HTTP-based registries requires `-Z http-registry`");
551-
}
552-
Box::new(http_remote::HttpRegistry::new(source_id, config, &name)) as Box<_>
549+
Box::new(http_remote::HttpRegistry::new(source_id, config, &name)?) as Box<_>
553550
} else {
554551
Box::new(remote::RemoteRegistry::new(source_id, config, &name)) as Box<_>
555552
};

tests/testsuite/registry.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ fn configure_source_replacement_for_http(addr: &str) {
4141
replace-with = 'dummy-registry'
4242
4343
[source.dummy-registry]
44-
registry = 'sparse+http://{}'
44+
registry = 'sparse+http://{}/'
4545
",
4646
addr
4747
)
@@ -2680,6 +2680,15 @@ fn http_requires_z_flag() {
26802680

26812681
p.cargo("build")
26822682
.with_status(101)
2683-
.with_stderr_contains(" Usage of HTTP-based registries requires `-Z http-registry`")
2683+
.with_stderr_contains(" usage of HTTP-based registries requires `-Z http-registry`")
26842684
.run();
26852685
}
2686+
2687+
#[cargo_test]
2688+
fn http_requires_trailing_slash() {
2689+
cargo_process("-Z http-registry install bar --index sparse+https://index.crates.io")
2690+
.masquerade_as_nightly_cargo()
2691+
.with_status(101)
2692+
.with_stderr("[ERROR] registry url must end in a slash `/`: sparse+https://index.crates.io")
2693+
.run()
2694+
}

0 commit comments

Comments
 (0)