Skip to content

Commit c16250c

Browse files
committed
convert URLUtils to java since this contains hotspots
1 parent 3f73d92 commit c16250c

File tree

2 files changed

+96
-78
lines changed

2 files changed

+96
-78
lines changed

src/groovy/org/grails/plugin/resource/URLUtils.groovy

Lines changed: 0 additions & 78 deletions
This file was deleted.
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package org.grails.plugin.resource;
2+
3+
import java.io.UnsupportedEncodingException;
4+
import java.net.URI;
5+
import java.net.URISyntaxException;
6+
import java.net.URLDecoder;
7+
import java.util.regex.Pattern;
8+
9+
/**
10+
* @author Marc Palmer (marc@grailsrocks.com)
11+
*/
12+
class URLUtils {
13+
14+
public static Pattern externalURLPattern = Pattern.compile("^((https?:?)?//).*");
15+
private static final int MAX_NORMALIZE_ITERATIONS = 3;
16+
17+
/**
18+
* Take a base URI and a target URI and resolve target against the base
19+
* using the normal rules e.g. "../x", "./x" "x" results in a link relative to the base's folder
20+
* and / is app-absolute, and anything with a protocol // is absolute
21+
*
22+
* Please note, I take full responsibility for the nastiness of this code. I could not
23+
* find a nice way to do this, and I wanted to find an existing lib to do it. Its
24+
* certainly not my finest moment. Sorry. Rely on the MenuTagTests.
25+
*
26+
* It's quite ugly in there.
27+
*/
28+
public static String relativeURI(String base, String target) {
29+
try {
30+
return new URI(base).resolve(new URI(target)).normalize().toString();
31+
}
32+
catch (URISyntaxException e) {
33+
throw new RuntimeException(e);
34+
}
35+
}
36+
37+
/**
38+
* Works out if url is relative, such that it would need to be corrected if
39+
* the file containing the url is moved
40+
*/
41+
public static Boolean isRelativeURL(String url) {
42+
return !url.startsWith("data:") &&
43+
!url.startsWith("#") &&
44+
!(url.indexOf("//") >= 0);
45+
}
46+
47+
public static Boolean isExternalURL(String url){
48+
if(url == null) return false;
49+
return externalURLPattern.matcher(url).matches();
50+
}
51+
52+
/**
53+
* Normalizes and decodes uri once.
54+
* Check if result contains \ , /../ , /./ or // after decoding and throws IllegalArgumentException in that case
55+
*
56+
* @param uri
57+
* @return
58+
*/
59+
public static String normalizeUri(String uri) {
60+
String current = uri;
61+
int counter=0;
62+
boolean changed = true;
63+
// handle double-encoding
64+
while (changed) {
65+
if (counter++ > MAX_NORMALIZE_ITERATIONS) {
66+
throw new IllegalArgumentException("unable to normalize input uri " + uri);
67+
}
68+
String normalized = doNormalizeUri(current);
69+
changed = (!current.equals(normalized));
70+
current = normalized;
71+
}
72+
return current;
73+
}
74+
75+
private static String doNormalizeUri(String uri) {
76+
if (uri == null) return null;
77+
78+
String normalized = RequestUtil.normalize(uri);
79+
if (normalized == null) {
80+
throw new IllegalArgumentException("illegal uri " + uri);
81+
}
82+
83+
String decoded;
84+
try {
85+
decoded = URLDecoder.decode(normalized, "UTF-8");
86+
}
87+
catch (UnsupportedEncodingException e) {
88+
throw new RuntimeException(e);
89+
}
90+
if(decoded.contains("\\") || decoded.contains("/./") || decoded.contains("/../") || decoded.contains("//")) {
91+
throw new IllegalArgumentException("illegal uri " + uri);
92+
}
93+
94+
return decoded;
95+
}
96+
}

0 commit comments

Comments
 (0)