diff options
author | Jiri Vanek <[email protected]> | 2012-05-18 16:23:30 +0200 |
---|---|---|
committer | Jiri Vanek <[email protected]> | 2012-05-18 16:23:30 +0200 |
commit | 2e03a3ed2358fcdcba03b1a0536197e9510a4a7e (patch) | |
tree | a62325e35c780ae7c0bd69c8d37d7d2fa0f955c8 /netx/net/sourceforge/jnlp | |
parent | 258fcac4b63f8e8be5a972d0f6a1eecca625772d (diff) |
Fixed behavior when encoded/characters needed encoding included in url (PR811)
Diffstat (limited to 'netx/net/sourceforge/jnlp')
-rw-r--r-- | netx/net/sourceforge/jnlp/cache/CacheUtil.java | 38 | ||||
-rw-r--r-- | netx/net/sourceforge/jnlp/cache/ResourceTracker.java | 128 |
2 files changed, 155 insertions, 11 deletions
diff --git a/netx/net/sourceforge/jnlp/cache/CacheUtil.java b/netx/net/sourceforge/jnlp/cache/CacheUtil.java index d61da4b..ec65094 100644 --- a/netx/net/sourceforge/jnlp/cache/CacheUtil.java +++ b/netx/net/sourceforge/jnlp/cache/CacheUtil.java @@ -61,22 +61,40 @@ public class CacheUtil { * ie sourceforge.net and www.sourceforge.net). */ public static boolean urlEquals(URL u1, URL u2) { - if (u1 == u2) + if (u1 == u2) { return true; - if (u1 == null || u2 == null) + } + if (u1 == null || u2 == null) { return false; + } - if (!compare(u1.getProtocol(), u2.getProtocol(), true) || - !compare(u1.getHost(), u2.getHost(), true) || - //u1.getDefaultPort() != u2.getDefaultPort() || // only in 1.4 - !compare(u1.getPath(), u2.getPath(), false) || - !compare(u1.getQuery(), u2.getQuery(), false) || - !compare(u1.getRef(), u2.getRef(), false)) - return false; - else + if (notNullUrlEquals(u1, u2)) { return true; + } + try { + URL nu1 = ResourceTracker.normalizeUrl(u1, false); + URL nu2 = ResourceTracker.normalizeUrl(u2, false); + if (notNullUrlEquals(nu1, nu2)) { + return true; + } + } catch (Exception ex) { + //keep silent here and return false + } + return false; } + private static boolean notNullUrlEquals(URL u1, URL u2) { + if (!compare(u1.getProtocol(), u2.getProtocol(), true) + || !compare(u1.getHost(), u2.getHost(), true) + || //u1.getDefaultPort() != u2.getDefaultPort() || // only in 1.4 + !compare(u1.getPath(), u2.getPath(), false) + || !compare(u1.getQuery(), u2.getQuery(), false) + || !compare(u1.getRef(), u2.getRef(), false)) { + return false; + } else { + return true; + } + } /** * Caches a resource and returns a URL for it in the cache; * blocks until resource is cached. If the resource location is diff --git a/netx/net/sourceforge/jnlp/cache/ResourceTracker.java b/netx/net/sourceforge/jnlp/cache/ResourceTracker.java index 058ae99..db05177 100644 --- a/netx/net/sourceforge/jnlp/cache/ResourceTracker.java +++ b/netx/net/sourceforge/jnlp/cache/ResourceTracker.java @@ -24,10 +24,13 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; +import java.net.URLDecoder; +import java.net.URLEncoder; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.ArrayList; @@ -108,6 +111,15 @@ public class ResourceTracker { private static final int ERROR = Resource.ERROR; private static final int STARTED = Resource.STARTED; + // normalization of url + private static final char PATH_DELIMITER_MARK = '/'; + private static final String PATH_DELIMITER = "" + PATH_DELIMITER_MARK; + private static final char QUERY_DELIMITER_MARK = '&'; + private static final String QUERY_DELIMITER = "" + QUERY_DELIMITER_MARK; + private static final char QUERY_MARK = '?'; + private static final char HREF_MARK = '#'; + private static final String UTF8 = "utf-8"; + /** max threads */ private static final int maxThreads = 5; @@ -173,7 +185,12 @@ public class ResourceTracker { public void addResource(URL location, Version version, DownloadOptions options, UpdatePolicy updatePolicy) { if (location == null) throw new IllegalArgumentException("location==null"); - + try { + location = normalizeUrl(location, JNLPRuntime.isDebug()); + } catch (Exception ex) { + System.err.println("Normalization of " + location.toString() + " have failed"); + ex.printStackTrace(); + } Resource resource = Resource.getResource(location, version, updatePolicy); boolean downloaded = false; @@ -1127,4 +1144,113 @@ public class ResourceTracker { } }; + private static String normalizeChunk(String base, boolean debug) throws UnsupportedEncodingException { + if (base == null) { + return base; + } + if ("".equals(base)) { + return base; + } + String result = base; + String ssE = URLDecoder.decode(base, UTF8); + // System.out.println("*" + base + "*"); + // System.out.println("-" + ssE + "-"); + if (base.equals(ssE)) { + result = URLEncoder.encode(base, UTF8); + if (debug) { + System.out.println(base + " chunk needs to be encoded => " + result); + } + } else { + if (debug) { + System.out.println(base + " chunk already encoded"); + } + } + return result; + } + + public static URL normalizeUrl(URL u, boolean debug) throws MalformedURLException, UnsupportedEncodingException { + if (u == null) { + return null; + } + String protocol = u.getProtocol(); + if (protocol == null || "file".equals(protocol)) { + return u; + } + String file = u.getPath(); + if (file == null) { + return u; + } + String host = u.getHost(); + String ref = u.getRef(); + int port = u.getPort(); + String query = u.getQuery(); + String[] qq = {}; + if (query != null) { + qq = query.split(QUERY_DELIMITER); + } + String[] ss = file.split(PATH_DELIMITER); + int normalized = 0; + if (debug) { + System.out.println("normalizing path " + file + " in " + u.toString()); + } + for (int i = 0; i < ss.length; i++) { + String base = ss[i]; + String r = normalizeChunk(base, debug); + if (!r.equals(ss[i])) { + normalized++; + } + ss[i] = r; + } + if (debug) { + System.out.println("normalizing query " + query + " in " + u.toString()); + } + for (int i = 0; i < qq.length; i++) { + String base = qq[i]; + String r = normalizeChunk(base, debug); + if (!r.equals(qq[i])) { + normalized++; + } + qq[i] = r; + } + if (normalized == 0) { + if (debug) { + System.out.println("Nothing was normalized in this url"); + } + return u; + } else { + System.out.println(normalized + " chunks normalized, rejoining url"); + } + StringBuilder composed = new StringBuilder(""); + for (int i = 0; i < ss.length; i++) { + String string = ss[i]; + if (ss.length <= 1 || (string != null && !"".equals(string))) { + composed.append(PATH_DELIMITER_MARK).append(string); + } + } + String composed1 = composed.toString(); + if (query != null && !query.trim().equals("")) { + composed.append(QUERY_MARK); + for (int i = 0; i < qq.length; i++) { + String string = qq[i]; + if ((string != null && !"".equals(string))) { + composed.append(string); + if (i != qq.length - 1) { + composed.append(QUERY_DELIMITER_MARK); + } + } + } + } + String composed2 = composed.substring(composed1.length() - 1); + if (ref != null && !ref.trim().equals("")) { + composed.append(HREF_MARK).append(ref); + } + + URL result = new URL(protocol, host, port, composed.toString()); + + if (debug) { + System.out.println("normalized `" + composed1 + "` and `" + composed2 + "` in " + result.toString()); + } + return result; + + } } |