From 644bd7c166c30ce5df9594c03c0dab62dd144926 Mon Sep 17 00:00:00 2001 From: "Carol (Nichols || Goulding)" Date: Tue, 2 Aug 2022 12:11:22 -0400 Subject: [PATCH 1/2] Write a test for publishing a crate with build metadata in the version --- .../krate_publish_new_krate_version_with_plus | 136 ++++++++++++++++++ src/tests/krate/downloads.rs | 15 ++ src/tests/krate/publish.rs | 11 ++ 3 files changed, 162 insertions(+) create mode 100644 src/tests/http-data/krate_publish_new_krate_version_with_plus diff --git a/src/tests/http-data/krate_publish_new_krate_version_with_plus b/src/tests/http-data/krate_publish_new_krate_version_with_plus new file mode 100644 index 00000000000..dc840cce28d --- /dev/null +++ b/src/tests/http-data/krate_publish_new_krate_version_with_plus @@ -0,0 +1,136 @@ +[ + { + "request": { + "uri": "http://alexcrichton-test.s3.amazonaws.com/crates/foo_plus/foo_plus-1.0.0+build-metadata.crate", + "method": "PUT", + "headers": [ + [ + "host", + "alexcrichton-test.s3.amazonaws.com" + ], + [ + "accept-encoding", + "gzip" + ], + [ + "authorization", + "AWS AKIAICL5IWUZYWWKA7JA:eW1SP7V3WdqHXWZLcbN1BI2Zo0g=" + ], + [ + "content-length", + "35" + ], + [ + "date", + "Fri, 15 Sep 2017 07:53:06 -0700" + ], + [ + "content-type", + "application/gzip" + ], + [ + "accept", + "*/*" + ] + ], + "body": "H4sIAAAAAAAA/+3AAQEAAACCIP+vbkhQwKsBLq+17wAEAAA=" + }, + "response": { + "status": 200, + "headers": [ + [ + "ETag", + "\"f9016ad360cebb4fe2e6e96e5949f022\"" + ], + [ + "content-length", + "0" + ], + [ + "Server", + "AmazonS3" + ], + [ + "x-amz-request-id", + "11703800587FA328" + ], + [ + "date", + "Fri, 15 Sep 2017 14:53:07 GMT" + ], + [ + "x-amz-id-2", + "fIN5XfJH1PExUU+fEoYZiLAlq/GVmVohMf24Gi5CEHocX1oLc56Mhq9ILtXEsC5xgXEtboWFrEI=" + ] + ], + "body": "" + } + }, + { + "request": { + "uri": "http://alexcrichton-test.s3.amazonaws.com/fo/o_/foo_plus", + "method": "PUT", + "headers": [ + [ + "accept-encoding", + "gzip" + ], + [ + "accept", + "*/*" + ], + [ + "content-length", + "177" + ], + [ + "date", + "Fri, 15 Sep 2017 07:53:06 -0700" + ], + [ + "authorization", + "AWS AKIAICL5IWUZYWWKA7JA:uDc39eNdF6CcwB+q+JwKsoDLQc4=" + ], + [ + "content-type", + "text/plain" + ], + [ + "host", + "alexcrichton-test.s3.amazonaws.com" + ] + ], + "body": "eyJuYW1lIjoiZm9vX3BsdXMiLCJ2ZXJzIjoiMS4wLjArYnVpbGQtbWV0YWRhdGEiLCJkZXBzIjpbXSwiY2tzdW0iOiJhY2I1NjA0YjEyNmFjODk0YzFlYjExYzQ1NzViZjIwNzJmZWE2MTIzMmE4ODhlNDUzNzcwYzc5ZDdlZDU2NDE5IiwiZmVhdHVyZXMiOnt9LCJ5YW5rZWQiOmZhbHNlLCJsaW5rcyI6bnVsbH0K" + }, + "response": { + "status": 200, + "headers": [ + [ + "x-amz-request-id", + "26589A5E52F8395C" + ], + [ + "x-amz-id-2", + "JdIvnNTw53aqXjBIqBLNuN4kxf/w1XWX+xuIiGBDYy7yzOSDuAMtBSrTW4ZWetcCIdqCUHuQ51A=" + ], + [ + "content-length", + "0" + ], + [ + "Server", + "AmazonS3" + ], + [ + "date", + "Fri,15 Sep 2017 14:53:07 GMT" + ], + [ + "ETag", + "\"f9016ad360cebb4fe2e6e96e5949f022\"" + ] + ], + "body": "" + } + } +] diff --git a/src/tests/krate/downloads.rs b/src/tests/krate/downloads.rs index fcdb208859f..62f39aa4668 100644 --- a/src/tests/krate/downloads.rs +++ b/src/tests/krate/downloads.rs @@ -95,6 +95,21 @@ fn download_nonexistent_version_of_existing_crate_404s() { .assert_not_found(); } +#[test] +fn download_version_with_plus() { + let (app, anon, user) = TestApp::init().with_user(); + let user = user.as_model(); + + app.db(|conn| { + CrateBuilder::new("foo_plus", user.id) + .version(VersionBuilder::new("1.0.0+hello")) + .expect_build(conn); + }); + + anon.get::<()>("/api/v1/crates/foo_plus/1.0.0+hello/download") + .assert_redirect_ends_with("/crates/foo_plus/foo_plus-1.0.0+hello.crate"); +} + #[test] fn download_noncanonical_crate_name() { let (app, anon, user) = TestApp::init().with_user(); diff --git a/src/tests/krate/publish.rs b/src/tests/krate/publish.rs index 9e9eaa4ae22..c186c854d2f 100644 --- a/src/tests/krate/publish.rs +++ b/src/tests/krate/publish.rs @@ -145,6 +145,17 @@ fn new_krate_weird_version() { assert_eq!(json.krate.max_version, "0.0.0-pre"); } +#[test] +fn new_krate_version_with_plus() { + let (_, _, _, token) = TestApp::full().with_token(); + + let crate_to_publish = PublishBuilder::new("foo_plus").version("1.0.0+build-metadata"); + let json: GoodCrate = token.enqueue_publish(crate_to_publish).good(); + + assert_eq!(json.krate.name, "foo_plus"); + assert_eq!(json.krate.max_version, "1.0.0+build-metadata"); +} + #[test] fn new_with_renamed_dependency() { let (app, _, user, token) = TestApp::full().with_token(); From b4343197e0a417971c761f04e279e8022d7d1937 Mon Sep 17 00:00:00 2001 From: "Carol (Nichols || Goulding)" Date: Tue, 2 Aug 2022 21:38:17 -0400 Subject: [PATCH 2/2] Encode plus signs in URLs for versions with build metadata --- .../krate_publish_new_krate_version_with_plus | 2 +- src/tests/krate/downloads.rs | 2 +- src/tests/krate/publish.rs | 2 +- src/tests/util/response.rs | 11 ++++++++--- src/uploaders.rs | 1 + 5 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/tests/http-data/krate_publish_new_krate_version_with_plus b/src/tests/http-data/krate_publish_new_krate_version_with_plus index dc840cce28d..eb90b2ca340 100644 --- a/src/tests/http-data/krate_publish_new_krate_version_with_plus +++ b/src/tests/http-data/krate_publish_new_krate_version_with_plus @@ -1,7 +1,7 @@ [ { "request": { - "uri": "http://alexcrichton-test.s3.amazonaws.com/crates/foo_plus/foo_plus-1.0.0+build-metadata.crate", + "uri": "http://alexcrichton-test.s3.amazonaws.com/crates/foo_plus/foo_plus-1.0.0%2Bbuild-metadata.crate", "method": "PUT", "headers": [ [ diff --git a/src/tests/krate/downloads.rs b/src/tests/krate/downloads.rs index 62f39aa4668..3b39e60850f 100644 --- a/src/tests/krate/downloads.rs +++ b/src/tests/krate/downloads.rs @@ -107,7 +107,7 @@ fn download_version_with_plus() { }); anon.get::<()>("/api/v1/crates/foo_plus/1.0.0+hello/download") - .assert_redirect_ends_with("/crates/foo_plus/foo_plus-1.0.0+hello.crate"); + .assert_redirect_ends_with("/crates/foo_plus/foo_plus-1.0.0%2Bhello.crate"); } #[test] diff --git a/src/tests/krate/publish.rs b/src/tests/krate/publish.rs index c186c854d2f..78a0147c7d1 100644 --- a/src/tests/krate/publish.rs +++ b/src/tests/krate/publish.rs @@ -150,7 +150,7 @@ fn new_krate_version_with_plus() { let (_, _, _, token) = TestApp::full().with_token(); let crate_to_publish = PublishBuilder::new("foo_plus").version("1.0.0+build-metadata"); - let json: GoodCrate = token.enqueue_publish(crate_to_publish).good(); + let json: GoodCrate = token.publish_crate(crate_to_publish).good(); assert_eq!(json.krate.name, "foo_plus"); assert_eq!(json.krate.max_version, "1.0.0+build-metadata"); diff --git a/src/tests/util/response.rs b/src/tests/util/response.rs index 1a80c3012b2..c1b248cc3ee 100644 --- a/src/tests/util/response.rs +++ b/src/tests/util/response.rs @@ -48,14 +48,19 @@ impl Response { #[track_caller] pub fn assert_redirect_ends_with(&self, target: &str) -> &Self { - assert!(self + let redirect_url = self .response .headers() .get(header::LOCATION) .unwrap() .to_str() - .unwrap() - .ends_with(target)); + .unwrap(); + assert!( + redirect_url.ends_with(target), + "assertion failed: `redirect_url.ends_with(target)` + redirect_url: `\"{redirect_url}\"` + target: `\"{target}\"`" + ); self } } diff --git a/src/uploaders.rs b/src/uploaders.rs index 9fa12768e85..29bd35cef14 100644 --- a/src/uploaders.rs +++ b/src/uploaders.rs @@ -79,6 +79,7 @@ impl Uploader { /// Returns the internal path of an uploaded crate's version archive. fn crate_path(name: &str, version: &str) -> String { + let version = version.replace('+', "%2B"); format!("crates/{name}/{name}-{version}.crate") }