@@ -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