Skip to content

Commit ad66d4c

Browse files
author
Praful Makani
committed
removed overload method and add method withExtHostName in SignUrlOption
1 parent b5c5aa2 commit ad66d4c

File tree

3 files changed

+70
-127
lines changed

3 files changed

+70
-127
lines changed

google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/Storage.java

Lines changed: 9 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -892,7 +892,7 @@ class SignUrlOption implements Serializable {
892892
private final Object value;
893893

894894
enum Option {
895-
HTTP_METHOD, CONTENT_TYPE, MD5, EXT_HEADERS, SERVICE_ACCOUNT_CRED
895+
HTTP_METHOD, CONTENT_TYPE, MD5, EXT_HEADERS, SERVICE_ACCOUNT_CRED,EXT_HOST
896896
}
897897

898898
private SignUrlOption(Option option, Object value) {
@@ -953,6 +953,13 @@ public static SignUrlOption withExtHeaders(Map<String, String> extHeaders) {
953953
public static SignUrlOption signWith(ServiceAccountSigner signer) {
954954
return new SignUrlOption(Option.SERVICE_ACCOUNT_CRED, signer);
955955
}
956+
957+
/**
958+
* Provides a host name to sign the URL. If not provided than host name will be default
959+
*/
960+
public static SignUrlOption withExtHostName(String extHostName){
961+
return new SignUrlOption(Option.EXT_HOST, extHostName);
962+
}
956963
}
957964

958965
/**
@@ -2107,6 +2114,7 @@ public static Builder newBuilder() {
21072114
* granularity supported is 1 second, finer granularities will be truncated
21082115
* @param unit time unit of the {@code duration} parameter
21092116
* @param options optional URL signing options
2117+
* {@code SignUrlOption.withExtHostName()} option is used for external host name of signed url
21102118
* @throws IllegalStateException if {@link SignUrlOption#signWith(ServiceAccountSigner)} was not
21112119
* used and no implementation of {@link ServiceAccountSigner} was provided to
21122120
* {@link StorageOptions}
@@ -2119,70 +2127,6 @@ public static Builder newBuilder() {
21192127
*/
21202128
URL signUrl(BlobInfo blobInfo, long duration, TimeUnit unit, SignUrlOption... options);
21212129

2122-
/**
2123-
* Generates a signed URL for a blob. If you have a blob that you want to allow access to for a
2124-
* fixed amount of time, you can use this method to generate a URL that is only valid within a
2125-
* certain time period. This is particularly useful if you don't want publicly accessible blobs,
2126-
* but also don't want to require users to explicitly log in. Signing a URL requires
2127-
* a service account signer. If an instance of {@link com.google.auth.ServiceAccountSigner} was
2128-
* passed to {@link StorageOptions}' builder via {@code setCredentials(Credentials)} or the
2129-
* default credentials are being used and the environment variable
2130-
* {@code GOOGLE_APPLICATION_CREDENTIALS} is set or your application is running in App Engine,
2131-
* then {@code signUrl} will use that credentials to sign the URL. If the credentials passed to
2132-
* {@link StorageOptions} do not implement {@link ServiceAccountSigner} (this is the case, for
2133-
* instance, for Google Cloud SDK credentials) then {@code signUrl} will throw an
2134-
* {@link IllegalStateException} unless an implementation of {@link ServiceAccountSigner} is
2135-
* passed using the {@link SignUrlOption#signWith(ServiceAccountSigner)} option.
2136-
*
2137-
* <p>A service account signer is looked for in the following order:
2138-
* <ol>
2139-
* <li>The signer passed with the option {@link SignUrlOption#signWith(ServiceAccountSigner)}
2140-
* <li>The credentials passed to {@link StorageOptions}
2141-
* <li>The default credentials, if no credentials were passed to {@link StorageOptions}
2142-
* </ol>
2143-
*
2144-
* <p>Example of creating a signed URL that is valid for 2 weeks, using the default credentials
2145-
* for signing the URL.
2146-
* <pre> {@code
2147-
* String bucketName = "my_unique_bucket";
2148-
* String blobName = "my_blob_name";
2149-
* URL signedUrl = storage.signUrl(BlobInfo.newBuilder(bucketName, blobName).build(), 14,
2150-
* TimeUnit.DAYS);
2151-
* }</pre>
2152-
*
2153-
* <p>Example of creating a signed URL passing the
2154-
* {@link SignUrlOption#signWith(ServiceAccountSigner)} option, that will be used for signing the
2155-
* URL.
2156-
* <pre> {@code
2157-
* String bucketName = "my_unique_bucket";
2158-
* String blobName = "my_blob_name";
2159-
* String keyPath = "/path/to/key.json";
2160-
* URL signedUrl = storage.signUrl(BlobInfo.newBuilder(bucketName, blobName).build(),
2161-
* 14, TimeUnit.DAYS, SignUrlOption.signWith(
2162-
* ServiceAccountCredentials.fromStream(new FileInputStream(keyPath))));
2163-
* }</pre>
2164-
*
2165-
* <p>Note that the {@link ServiceAccountSigner} may require additional configuration to enable
2166-
* URL signing. See the documentation for the implementation for more details.</p>
2167-
*
2168-
* @param url can be customize
2169-
* @param blobInfo the blob associated with the signed URL
2170-
* @param duration time until the signed URL expires, expressed in {@code unit}. The finest
2171-
* granularity supported is 1 second, finer granularities will be truncated
2172-
* @param unit time unit of the {@code duration} parameter
2173-
* @param options optional URL signing options
2174-
* @throws IllegalStateException if {@link SignUrlOption#signWith(ServiceAccountSigner)} was not
2175-
* used and no implementation of {@link ServiceAccountSigner} was provided to
2176-
* {@link StorageOptions}
2177-
* @throws IllegalArgumentException if {@code SignUrlOption.withMd5()} option is used and
2178-
* {@code blobInfo.md5()} is {@code null}
2179-
* @throws IllegalArgumentException if {@code SignUrlOption.withContentType()} option is used and
2180-
* {@code blobInfo.contentType()} is {@code null}
2181-
* @throws SigningException if the attempt to sign the URL failed
2182-
* @see <a href="https://cloud.google.com/storage/docs/access-control#Signed-URLs">Signed-URLs</a>
2183-
*/
2184-
URL signUrl(String url, BlobInfo blobInfo, long duration, TimeUnit unit, SignUrlOption... options);
2185-
21862130
/**
21872131
* Gets the requested blobs. A batch request is used to perform this call.
21882132
*

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

Lines changed: 53 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,22 @@
3333
import static com.google.common.base.Preconditions.checkState;
3434
import static java.nio.charset.StandardCharsets.UTF_8;
3535

36+
import java.io.ByteArrayInputStream;
37+
import java.io.InputStream;
38+
import java.io.UnsupportedEncodingException;
39+
import java.net.MalformedURLException;
40+
import java.net.URI;
41+
import java.net.URL;
42+
import java.net.URLEncoder;
43+
import java.util.Arrays;
44+
import java.util.Collections;
45+
import java.util.EnumMap;
46+
import java.util.List;
47+
import java.util.Map;
48+
import java.util.Set;
49+
import java.util.concurrent.Callable;
50+
import java.util.concurrent.TimeUnit;
51+
3652
import com.google.api.gax.paging.Page;
3753
import com.google.api.services.storage.model.BucketAccessControl;
3854
import com.google.api.services.storage.model.ObjectAccessControl;
@@ -62,21 +78,6 @@
6278
import com.google.common.io.BaseEncoding;
6379
import com.google.common.net.UrlEscapers;
6480
import com.google.common.primitives.Ints;
65-
import java.io.ByteArrayInputStream;
66-
import java.io.InputStream;
67-
import java.io.UnsupportedEncodingException;
68-
import java.net.MalformedURLException;
69-
import java.net.URI;
70-
import java.net.URL;
71-
import java.net.URLEncoder;
72-
import java.util.Arrays;
73-
import java.util.Collections;
74-
import java.util.EnumMap;
75-
import java.util.List;
76-
import java.util.Map;
77-
import java.util.Set;
78-
import java.util.concurrent.Callable;
79-
import java.util.concurrent.TimeUnit;
8081

8182
final class StorageImpl extends BaseService<StorageOptions> implements Storage {
8283

@@ -500,52 +501,50 @@ private BlobWriteChannel writer(BlobInfo blobInfo, BlobTargetOption... options)
500501

501502
@Override
502503
public URL signUrl(BlobInfo blobInfo, long duration, TimeUnit unit, SignUrlOption... options) {
503-
return signUrlOptions(DEFAULT_STORAGE_HOST, blobInfo, duration, unit, options);
504-
}
505-
506-
@Override
507-
public URL signUrl(String url, BlobInfo blobInfo, long duration, TimeUnit unit, SignUrlOption... options) {
508-
return signUrlOptions(url, blobInfo, duration, unit, options);
509-
}
510-
511-
private URL signUrlOptions(String url, BlobInfo blobInfo, long duration, TimeUnit unit, SignUrlOption... options){
512504
EnumMap<SignUrlOption.Option, Object> optionMap = Maps.newEnumMap(SignUrlOption.Option.class);
513-
for (SignUrlOption option : options) {
514-
optionMap.put(option.getOption(), option.getValue());
515-
}
516-
ServiceAccountSigner credentials =
517-
(ServiceAccountSigner) optionMap.get(SignUrlOption.Option.SERVICE_ACCOUNT_CRED);
518-
if (credentials == null) {
519-
checkState(this.getOptions().getCredentials() instanceof ServiceAccountSigner,
520-
"Signing key was not provided and could not be derived");
521-
credentials = (ServiceAccountSigner) this.getOptions().getCredentials();
522-
}
523-
524-
long expiration = TimeUnit.SECONDS.convert(
525-
getOptions().getClock().millisTime() + unit.toMillis(duration), TimeUnit.MILLISECONDS);
505+
for (SignUrlOption option : options) {
506+
optionMap.put(option.getOption(), option.getValue());
507+
}
508+
ServiceAccountSigner credentials =
509+
(ServiceAccountSigner) optionMap.get(SignUrlOption.Option.SERVICE_ACCOUNT_CRED);
510+
if (credentials == null) {
511+
checkState(this.getOptions().getCredentials() instanceof ServiceAccountSigner,
512+
"Signing key was not provided and could not be derived");
513+
credentials = (ServiceAccountSigner) this.getOptions().getCredentials();
514+
}
526515

527-
StringBuilder stPath = new StringBuilder();
528-
if (!blobInfo.getBucket().startsWith(PATH_DELIMITER)) {
529-
stPath.append(PATH_DELIMITER);
530-
}
531-
stPath.append(blobInfo.getBucket());
532-
if (!blobInfo.getBucket().endsWith(PATH_DELIMITER)) {
533-
stPath.append(PATH_DELIMITER);
534-
}
535-
if (blobInfo.getName().startsWith(PATH_DELIMITER)) {
536-
stPath.setLength(stPath.length() - 1);
537-
}
516+
long expiration = TimeUnit.SECONDS.convert(
517+
getOptions().getClock().millisTime() + unit.toMillis(duration), TimeUnit.MILLISECONDS);
538518

539-
String escapedName = UrlEscapers.urlFragmentEscaper().escape(blobInfo.getName());
540-
stPath.append(escapedName.replace("?", "%3F"));
519+
StringBuilder stPath = new StringBuilder();
520+
if (!blobInfo.getBucket().startsWith(PATH_DELIMITER)) {
521+
stPath.append(PATH_DELIMITER);
522+
}
523+
stPath.append(blobInfo.getBucket());
524+
if (!blobInfo.getBucket().endsWith(PATH_DELIMITER)) {
525+
stPath.append(PATH_DELIMITER);
526+
}
527+
if (blobInfo.getName().startsWith(PATH_DELIMITER)) {
528+
stPath.setLength(stPath.length() - 1);
529+
}
541530

542-
URI path = URI.create(stPath.toString());
531+
String escapedName = UrlEscapers.urlFragmentEscaper().escape(blobInfo.getName());
532+
stPath.append(escapedName.replace("?", "%3F"));
533+
534+
URI path = URI.create(stPath.toString());
543535

544-
try {
536+
try {
545537
SignatureInfo signatureInfo = buildSignatureInfo(optionMap, blobInfo, expiration, path);
546538
byte[] signatureBytes =
547539
credentials.sign(signatureInfo.constructUnsignedPayload().getBytes(UTF_8));
548-
StringBuilder stBuilder = new StringBuilder(url).append(path);
540+
StringBuilder stBuilder = new StringBuilder();
541+
if(optionMap.get(SignUrlOption.Option.EXT_HOST) == null){
542+
stBuilder.append(DEFAULT_STORAGE_HOST).append(path);
543+
}
544+
else{
545+
stBuilder.append(optionMap.get(SignUrlOption.Option.EXT_HOST).toString()).append(path);
546+
}
547+
549548
String signature =
550549
URLEncoder.encode(BaseEncoding.base64().encode(signatureBytes), UTF_8.name());
551550
stBuilder.append("?GoogleAccessId=").append(credentials.getAccount());
@@ -556,7 +555,7 @@ private URL signUrlOptions(String url, BlobInfo blobInfo, long duration, TimeUni
556555

557556
} catch (MalformedURLException | UnsupportedEncodingException ex) {
558557
throw new IllegalStateException(ex);
559-
}
558+
}
560559
}
561560

562561
/**

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1645,7 +1645,7 @@ public void testSignUrlWithCustomUrl()
16451645
ServiceAccountCredentials credentials =
16461646
new ServiceAccountCredentials(null, ACCOUNT, privateKey, null, null);
16471647
storage = options.toBuilder().setCredentials(credentials).build().getService();
1648-
URL url = storage.signUrl("https://custom.host.com",BLOB_INFO1, 14, TimeUnit.DAYS);
1648+
URL url = storage.signUrl(BLOB_INFO1, 14, TimeUnit.DAYS, Storage.SignUrlOption.withExtHostName("https://custom.host.com"));
16491649
String stringUrl = url.toString();
16501650
String expectedUrl =
16511651
new StringBuilder("https://custom.host.com/")
@@ -1730,7 +1730,7 @@ public void testSignUrlLeadingSlashWithCustomUrl()
17301730
new ServiceAccountCredentials(null, ACCOUNT, privateKey, null, null);
17311731
storage = options.toBuilder().setCredentials(credentials).build().getService();
17321732
URL url =
1733-
storage.signUrl("https://custom.host.com",BlobInfo.newBuilder(BUCKET_NAME1, blobName).build(), 14, TimeUnit.DAYS);
1733+
storage.signUrl(BlobInfo.newBuilder(BUCKET_NAME1, blobName).build(), 14, TimeUnit.DAYS, Storage.SignUrlOption.withExtHostName("https://custom.host.com"));
17341734
String escapedBlobName = UrlEscapers.urlFragmentEscaper().escape(blobName);
17351735
String stringUrl = url.toString();
17361736
String expectedUrl =
@@ -1824,13 +1824,13 @@ public void testSignUrlWithOptionsAndCustomUrl()
18241824
storage = options.toBuilder().setCredentials(credentials).build().getService();
18251825
URL url =
18261826
storage.signUrl(
1827-
"https://custom.host.com",
18281827
BLOB_INFO1,
18291828
14,
18301829
TimeUnit.DAYS,
18311830
Storage.SignUrlOption.httpMethod(HttpMethod.POST),
18321831
Storage.SignUrlOption.withContentType(),
1833-
Storage.SignUrlOption.withMd5());
1832+
Storage.SignUrlOption.withMd5(),
1833+
Storage.SignUrlOption.withExtHostName("https://custom.host.com"));
18341834
String stringUrl = url.toString();
18351835
String expectedUrl =
18361836
new StringBuilder("https://custom.host.com/")
@@ -1937,7 +1937,7 @@ public void testSignUrlForBlobWithSpecialCharsAndCustomUrl()
19371937
for (char specialChar : specialChars) {
19381938
String blobName = "/a" + specialChar + "b";
19391939
URL url =
1940-
storage.signUrl("https://custom.host.com",BlobInfo.newBuilder(BUCKET_NAME1, blobName).build(), 14, TimeUnit.DAYS);
1940+
storage.signUrl(BlobInfo.newBuilder(BUCKET_NAME1, blobName).build(), 14, TimeUnit.DAYS, Storage.SignUrlOption.withExtHostName("https://custom.host.com"));
19411941
String escapedBlobName =
19421942
UrlEscapers.urlFragmentEscaper().escape(blobName).replace("?", "%3F");
19431943
String stringUrl = url.toString();
@@ -2041,13 +2041,13 @@ public void testSignUrlWithExtHeadersAndCustomUrl()
20412041
extHeaders.put("x-goog-meta-owner", "myself");
20422042
URL url =
20432043
storage.signUrl(
2044-
"https://custom.host.com",
20452044
BLOB_INFO1,
20462045
14,
20472046
TimeUnit.DAYS,
20482047
Storage.SignUrlOption.httpMethod(HttpMethod.PUT),
20492048
Storage.SignUrlOption.withContentType(),
2050-
Storage.SignUrlOption.withExtHeaders(extHeaders));
2049+
Storage.SignUrlOption.withExtHeaders(extHeaders),
2050+
Storage.SignUrlOption.withExtHostName("https://custom.host.com"));
20512051
String stringUrl = url.toString();
20522052
String expectedUrl =
20532053
new StringBuilder("https://custom.host.com/")
@@ -2140,7 +2140,7 @@ public void testSignUrlForBlobWithSlashesAndCustomUrl()
21402140

21412141
String blobName = "/foo/bar/baz #%20other cool stuff.txt";
21422142
URL url =
2143-
storage.signUrl("https://custom.host.com", BlobInfo.newBuilder(BUCKET_NAME1, blobName).build(), 14, TimeUnit.DAYS);
2143+
storage.signUrl(BlobInfo.newBuilder(BUCKET_NAME1, blobName).build(), 14, TimeUnit.DAYS, Storage.SignUrlOption.withExtHostName("https://custom.host.com"));
21442144
String escapedBlobName = UrlEscapers.urlFragmentEscaper().escape(blobName);
21452145
String stringUrl = url.toString();
21462146
String expectedUrl =

0 commit comments

Comments
 (0)