Skip to content

Commit 5869157

Browse files
committed
Escape + to %2B in response URLs
1 parent 4ee8981 commit 5869157

File tree

2 files changed

+26
-4
lines changed

2 files changed

+26
-4
lines changed

src/tests/routes/crates/versions/download.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,21 @@ fn download_caches_version_id() {
9797
// Check download count against the new name, rather than rename it back to the original value
9898
downloads::assert_dl_count(&anon, "other/1.0.0", None, 2);
9999
}
100+
101+
#[test]
102+
fn download_with_build_metadata() {
103+
let (app, anon, user) = TestApp::init().with_user();
104+
let user = user.as_model();
105+
106+
app.db(|conn| {
107+
CrateBuilder::new("foo", user.id)
108+
.version(VersionBuilder::new("1.0.0+bar"))
109+
.expect_build(conn);
110+
});
111+
112+
anon.get::<()>("/api/v1/crates/foo/1.0.0+bar/download")
113+
.assert_redirect_ends_with("/crates/foo/foo-1.0.0%2Bbar.crate");
114+
115+
anon.get::<()>("/api/v1/crates/foo/1.0.0+bar/readme")
116+
.assert_redirect_ends_with("/readmes/foo/foo-1.0.0%2Bbar.html");
117+
}

src/uploaders.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,39 +37,43 @@ impl Uploader {
3737
///
3838
/// The function doesn't check for the existence of the file.
3939
pub fn crate_location(&self, crate_name: &str, version: &str) -> String {
40+
let version = version.replace('+', "%2B");
41+
4042
match *self {
4143
Uploader::S3 {
4244
ref bucket,
4345
ref cdn,
4446
..
4547
} => {
46-
let path = Uploader::crate_path(crate_name, version);
48+
let path = Uploader::crate_path(crate_name, &version);
4749
match *cdn {
4850
Some(ref host) => format!("https://{host}/{path}"),
4951
None => bucket.url(&path).unwrap(),
5052
}
5153
}
52-
Uploader::Local => format!("/{}", Uploader::crate_path(crate_name, version)),
54+
Uploader::Local => format!("/{}", Uploader::crate_path(crate_name, &version)),
5355
}
5456
}
5557

5658
/// Returns the URL of an uploaded crate's version readme.
5759
///
5860
/// The function doesn't check for the existence of the file.
5961
pub fn readme_location(&self, crate_name: &str, version: &str) -> String {
62+
let version = version.replace('+', "%2B");
63+
6064
match *self {
6165
Uploader::S3 {
6266
ref bucket,
6367
ref cdn,
6468
..
6569
} => {
66-
let path = Uploader::readme_path(crate_name, version);
70+
let path = Uploader::readme_path(crate_name, &version);
6771
match *cdn {
6872
Some(ref host) => format!("https://{host}/{path}"),
6973
None => bucket.url(&path).unwrap(),
7074
}
7175
}
72-
Uploader::Local => format!("/{}", Uploader::readme_path(crate_name, version)),
76+
Uploader::Local => format!("/{}", Uploader::readme_path(crate_name, &version)),
7377
}
7478
}
7579

0 commit comments

Comments
 (0)