Skip to content

Commit a4d75e9

Browse files
committed
Fix generation of signed urls for blobs containing spaces and other special chars
1 parent 05a2a32 commit a4d75e9

File tree

2 files changed

+6
-3
lines changed

2 files changed

+6
-3
lines changed

google-cloud-storage/src/main/java/com/google/cloud/storage/StorageImpl.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
import com.google.common.hash.Hashing;
5656
import com.google.common.io.BaseEncoding;
5757
import com.google.common.primitives.Ints;
58+
import com.google.common.net.UrlEscapers;
5859

5960
import java.io.ByteArrayInputStream;
6061
import java.io.InputStream;
@@ -524,7 +525,7 @@ public URL signUrl(BlobInfo blobInfo, long duration, TimeUnit unit, SignUrlOptio
524525
if (blobInfo.name().startsWith("/")) {
525526
path.setLength(path.length() - 1);
526527
}
527-
path.append(blobInfo.name());
528+
path.append(UrlEscapers.urlPathSegmentEscaper().escape(blobInfo.name()));
528529
stBuilder.append(path);
529530
try {
530531
byte[] signatureBytes = authCredentials.sign(stBuilder.toString().getBytes(UTF_8));

google-cloud-storage/src/test/java/com/google/cloud/storage/StorageImplTest.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import com.google.common.collect.ImmutableMap;
5151
import com.google.common.collect.Iterables;
5252
import com.google.common.io.BaseEncoding;
53+
import com.google.common.net.UrlEscapers;
5354

5455
import org.easymock.Capture;
5556
import org.easymock.EasyMock;
@@ -1252,16 +1253,17 @@ public void testSignUrlLeadingSlash() throws NoSuchAlgorithmException, InvalidKe
12521253
ServiceAccountAuthCredentials.createFor(ACCOUNT, privateKey);
12531254
storage = options.toBuilder().authCredentials(authCredentials).build().service();
12541255
URL url = storage.signUrl(BlobInfo.builder(BUCKET_NAME1, blobName).build(), 14, TimeUnit.DAYS);
1256+
String escapedBlobName = UrlEscapers.urlPathSegmentEscaper().escape(blobName);
12551257
String stringUrl = url.toString();
12561258
String expectedUrl = new StringBuilder("https://storage.googleapis.com/").append(BUCKET_NAME1)
1257-
.append(blobName).append("?GoogleAccessId=").append(ACCOUNT).append("&Expires=")
1259+
.append(escapedBlobName).append("?GoogleAccessId=").append(ACCOUNT).append("&Expires=")
12581260
.append(42L + 1209600).append("&Signature=").toString();
12591261
assertTrue(stringUrl.startsWith(expectedUrl));
12601262
String signature = stringUrl.substring(expectedUrl.length());
12611263

12621264
StringBuilder signedMessageBuilder = new StringBuilder();
12631265
signedMessageBuilder.append(HttpMethod.GET).append("\n\n\n").append(42L + 1209600).append("\n/")
1264-
.append(BUCKET_NAME1).append(blobName);
1266+
.append(BUCKET_NAME1).append(escapedBlobName);
12651267

12661268
Signature signer = Signature.getInstance("SHA256withRSA");
12671269
signer.initVerify(publicKey);

0 commit comments

Comments
 (0)