diff --git a/app/lib/frontend/backend.dart b/app/lib/frontend/backend.dart index ae4b9b061d..2486985db9 100644 --- a/app/lib/frontend/backend.dart +++ b/app/lib/frontend/backend.dart @@ -1071,9 +1071,7 @@ class TarballStorageNamer { (namespace == null || namespace.isEmpty) ? '' : 'ns/$namespace/'; /// The GCS object name of a tarball object - excluding leading '/'. - String tarballObjectName(String package, String version) - // TODO: Do we need some kind of escaping here? - => + String tarballObjectName(String package, String version) => '${prefix}packages/$package-$version.tar.gz'; /// The GCS object name of an temporary object [guid] - excluding leading '/'. @@ -1081,7 +1079,7 @@ class TarballStorageNamer { /// The http URL of a publicly accessable GCS object. String tarballObjectUrl(String package, String version) { - final object = tarballObjectName(package, version); + final object = tarballObjectName(package, Uri.encodeComponent(version)); return '$storageBaseUrl/$bucket/$object'; } } diff --git a/app/test/frontend/backend_test.dart b/app/test/frontend/backend_test.dart index 2ea6083b41..4e12f4beed 100644 --- a/app/test/frontend/backend_test.dart +++ b/app/test/frontend/backend_test.dart @@ -159,10 +159,18 @@ void main() { }); }); - testWithServices('Backend.downloadUrl', () async { - final url = await backend.downloadUrl('hydrogen', '2.0.8'); - expect(url.toString(), - 'http://localhost:0/fake-bucket-pub/packages/hydrogen-2.0.8.tar.gz'); + group('Backend.downloadUrl', () { + testWithServices('no escape needed', () async { + final url = await backend.downloadUrl('hydrogen', '2.0.8'); + expect(url.toString(), + 'http://localhost:0/fake-bucket-pub/packages/hydrogen-2.0.8.tar.gz'); + }); + + testWithServices('version escape needed', () async { + final url = await backend.downloadUrl('hydrogen', '2.0.8+5'); + expect(url.toString(), + 'http://localhost:0/fake-bucket-pub/packages/hydrogen-2.0.8%2B5.tar.gz'); + }); }); });