Skip to content

Commit 7e5c869

Browse files
author
Daniel Cohen
committed
bug fixes
1 parent 0dab9d5 commit 7e5c869

File tree

2 files changed

+43
-24
lines changed

2 files changed

+43
-24
lines changed

cloudinary-core/src/main/java/com/cloudinary/Configuration.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,11 @@ public class Configuration {
3535
public int proxyPort;
3636
public Map<String, Object> properties = new HashMap<String, Object>();
3737
public Boolean secureCdnSubdomain;
38+
public boolean useRootPath;
3839
public Configuration(){
3940
}
4041

41-
private Configuration(String cloudName, String apiKey, String apiSecret, String secureDistribution, String cname, String uploadPrefix, boolean secure, boolean privateCdn, boolean cdnSubdomain, boolean shorten, String callback,String proxyHost,int proxyPort,Boolean secureCdnSubdomain) {
42+
private Configuration(String cloudName, String apiKey, String apiSecret, String secureDistribution, String cname, String uploadPrefix, boolean secure, boolean privateCdn, boolean cdnSubdomain, boolean shorten, String callback,String proxyHost,int proxyPort,Boolean secureCdnSubdomain,boolean useRootPath) {
4243
this.cloudName = cloudName;
4344
this.apiKey = apiKey;
4445
this.apiSecret = apiSecret;
@@ -53,6 +54,7 @@ private Configuration(String cloudName, String apiKey, String apiSecret, String
5354
this.proxyHost = proxyHost;
5455
this.proxyPort = proxyPort;
5556
this.secureCdnSubdomain = secureCdnSubdomain;
57+
this.useRootPath = useRootPath;
5658
}
5759

5860

@@ -77,6 +79,7 @@ public void update(Map config) {
7779
this.proxyHost = (String) config.get("proxy_host");
7880
this.proxyPort = ObjectUtils.asInteger(config.get("proxy_port"),0);
7981
this.secureCdnSubdomain = ObjectUtils.asBoolean(config.get("secure_cdn_subdomain"), null);
82+
this.useRootPath = ObjectUtils.asBoolean(config.get("use_root_path"), false);
8083
}
8184

8285

@@ -96,6 +99,7 @@ public Configuration(Configuration other) {
9699
this.proxyHost = other.proxyHost;
97100
this.proxyPort = other.proxyPort;
98101
this.secureCdnSubdomain = other.secureCdnSubdomain;
102+
this.useRootPath = other.useRootPath;
99103
}
100104

101105

@@ -183,12 +187,13 @@ public static class Builder {
183187
private String proxyHost;
184188
private int proxyPort;
185189
private Boolean secureCdnSubdomain;
190+
private boolean useRootPath;
186191

187192

188193
/**
189194
* Creates a {@link Configuration} with the arguments supplied to this builder
190195
*/
191-
public Configuration build() { return new Configuration(cloudName, apiKey, apiSecret, secureDistribution, cname, uploadPrefix, secure, privateCdn, cdnSubdomain, shorten,callback,proxyHost,proxyPort,secureCdnSubdomain); }
196+
public Configuration build() { return new Configuration(cloudName, apiKey, apiSecret, secureDistribution, cname, uploadPrefix, secure, privateCdn, cdnSubdomain, shorten,callback,proxyHost,proxyPort,secureCdnSubdomain,useRootPath); }
192197

193198
/**
194199
* The unique name of your cloud at Cloudinary
@@ -279,6 +284,13 @@ public Builder setUploadPrefix(String uploadPrefix) {
279284
this.uploadPrefix = uploadPrefix;
280285
return this;
281286
}
287+
288+
public Builder setUseRootPath(boolean useRootPath) {
289+
this.useRootPath = useRootPath;
290+
return this;
291+
}
292+
293+
282294

283295
/**
284296
* Initialize builder from existing {@link Configuration}
@@ -300,6 +312,7 @@ public Builder from(Configuration other) {
300312
this.proxyHost = other.proxyHost;
301313
this.proxyPort = other.proxyPort;
302314
this.secureCdnSubdomain = other.secureCdnSubdomain;
315+
this.useRootPath = other.useRootPath;
303316
return this;
304317
}
305318

cloudinary-core/src/main/java/com/cloudinary/Url.java

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ public class Url {
2626
boolean signUrl;
2727
String source = null;
2828
private String urlSuffix;
29-
private boolean useRootPath;
30-
private String sourceToSign;
29+
private Boolean useRootPath;
3130
private static final String CL_BLANK = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
3231

3332
public Url(Cloudinary cloudinary) {
@@ -177,17 +176,22 @@ public String generate() {
177176
}
178177

179178
public String generate(String source) {
180-
179+
180+
boolean useRootPath =this.config.useRootPath;
181+
if (this.useRootPath!=null){
182+
useRootPath = this.useRootPath;
183+
}
184+
181185
if (StringUtils.isEmpty(this.config.cloudName)) {
182186
throw new IllegalArgumentException("Must supply cloud_name in tag or in configuration");
183187
}
184188

185189
if (!this.config.privateCdn) {
186190
if (StringUtils.isNotBlank(urlSuffix)) {
187-
throw new RuntimeException("URL Suffix only supported in private CDN");
191+
throw new IllegalArgumentException("URL Suffix only supported in private CDN");
188192
}
189193
if (useRootPath) {
190-
throw new RuntimeException("Root path only supported in private CDN");
194+
throw new IllegalArgumentException("Root path only supported in private CDN");
191195
}
192196
}
193197

@@ -201,21 +205,12 @@ public String generate(String source) {
201205
}
202206

203207

204-
205208
if (source.toLowerCase(Locale.US).matches("^https?:/.*")) {
206209
if (StringUtils.isEmpty(type) || "asset".equals(type) ) {
207210
return source;
208211
}
209212
}
210213

211-
if (source.contains("/") && !source.matches("v[0-9]+.*") && !source.matches("https?:/.*") && StringUtils.isEmpty(version)) {
212-
version = "1";
213-
}
214-
215-
if (version == null)
216-
version = "";
217-
else
218-
version = "v" + version;
219214

220215
if (type!=null && type.equals("fetch") && !StringUtils.isEmpty(format)) {
221216
transformation().fetchFormat(format);
@@ -227,10 +222,18 @@ public String generate(String source) {
227222

228223
String[] finalizedSource = finalizeSource(source,format,urlSuffix);
229224
source = finalizedSource[0];
230-
sourceToSign = finalizedSource[1];
231-
225+
String sourceToSign = finalizedSource[1];
232226

227+
if (sourceToSign.contains("/") && !sourceToSign.matches("v[0-9]+.*") && !sourceToSign.matches("https?:/.*") && StringUtils.isEmpty(version)) {
228+
version = "1";
229+
}
230+
231+
if (version == null)
232+
version = "";
233+
else
234+
version = "v" + version;
233235

236+
234237
if (signUrl) {
235238
MessageDigest md = null;
236239
try {
@@ -246,7 +249,7 @@ public String generate(String source) {
246249

247250
byte[] digest = md.digest((toSign + this.config.apiSecret).getBytes());
248251
signature = Base64Coder.encodeURLSafeString(digest);
249-
signature = "s--" + signature.substring(0, 8) + "--/" ;
252+
signature = "s--" + signature.substring(0, 8) + "--" ;
250253
}
251254

252255
String finalResourceType = finalizeResourceType(resourceType,type,urlSuffix,useRootPath,config.shorten);
@@ -259,6 +262,7 @@ private String[] finalizeSource(String source, String format, String urlSuffix)
259262
String[] result = new String[2];
260263
source = source.replaceAll("([^:])//", "\1/");
261264

265+
String sourceToSign;
262266
if (source.toLowerCase().matches("^https?:/.*")) {
263267
source = SmartUrlEncoder.encode(source);
264268
sourceToSign = source;
@@ -270,8 +274,10 @@ private String[] finalizeSource(String source, String format, String urlSuffix)
270274
}
271275
sourceToSign = source;
272276
if (StringUtils.isNotBlank(urlSuffix)) {
273-
if (urlSuffix.matches("\\w*[\\./]\\w*")) {
274-
throw new RuntimeException("url_suffix should not include . or /");
277+
Pattern pattern = Pattern.compile("[\\./]");
278+
Matcher matcher= pattern.matcher(urlSuffix);
279+
if (matcher.find()) {
280+
throw new IllegalArgumentException("url_suffix should not include . or /");
275281
}
276282
source = source + "/" + urlSuffix;
277283
}
@@ -297,15 +303,15 @@ public String finalizeResourceType(String resourceType, String type, String urlS
297303
resourceType = "files";
298304
type = null;
299305
} else {
300-
throw new RuntimeException("URL Suffix only supported for image/upload and raw/upload");
306+
throw new IllegalArgumentException("URL Suffix only supported for image/upload and raw/upload");
301307
}
302308
}
303309
if (useRootPath) {
304310
if ((resourceType.equals("image") && type.equals("upload")) || (resourceType.equals("images") && StringUtils.isBlank(type))) {
305311
resourceType = null;
306312
type = null;
307313
} else {
308-
throw new RuntimeException("Root path only supported for image/upload");
314+
throw new IllegalArgumentException("Root path only supported for image/upload");
309315
}
310316
}
311317
if (shorten && resourceType.equals("image") && type.equals("upload")) {
@@ -332,7 +338,7 @@ public String unsignedDownloadUrlPrefix(String source, String cloudName, boolean
332338
secureDistribution = this.config.privateCdn ? this.config.cloudName + "-res.cloudinary.com" : Cloudinary.SHARED_CDN;
333339
}
334340
if (!sharedDomain) {
335-
sharedDomain = (secureDistribution == Cloudinary.SHARED_CDN);
341+
sharedDomain = secureDistribution.equals(Cloudinary.SHARED_CDN);
336342
}
337343

338344
if (secureCdnSubdomain == null && sharedDomain) {

0 commit comments

Comments
 (0)