diff options
Diffstat (limited to 'libjava/java/net/URLStreamHandler.java')
-rw-r--r-- | libjava/java/net/URLStreamHandler.java | 103 |
1 files changed, 76 insertions, 27 deletions
diff --git a/libjava/java/net/URLStreamHandler.java b/libjava/java/net/URLStreamHandler.java index ae364e4..ba2114c 100644 --- a/libjava/java/net/URLStreamHandler.java +++ b/libjava/java/net/URLStreamHandler.java @@ -28,29 +28,35 @@ public abstract class URLStreamHandler protected void parseURL(URL u, String spec, int start, int limit) { - String tmpStr; - String host = ""; // Initialize to null string. - String file; - int port = -1; - int colon; - + String host = u.getHost(); + int port = u.getPort(); + String file = u.getFile(); + /* TBD: The JDK 1.2 doc specifically says that limit is the position * to stop parsing at and that it will be either the end of the string * or the position of '#'; thus the doc infers that this method does * not set the ref. */ - tmpStr = spec.substring(start, limit); - int hostEnd = 0; - if (tmpStr.startsWith("//")) + if (spec.regionMatches (start, "//", 0, 2)) { - int slash = tmpStr.indexOf('/', 2); - hostEnd = tmpStr.length(); - if (slash >= 0) - hostEnd = slash; + int hostEnd; + int colon; - host = tmpStr.substring(2, hostEnd); - - // Look for optional port number. + start += 2; + int slash = spec.indexOf('/', start); + if (slash >= 0) + hostEnd = slash; + else + hostEnd = limit; + + host = spec.substring (start, hostEnd); + + // Look for optional port number. It is valid for the non-port + // part of the host name to be null (e.g. a URL "http://:80"). + // TBD: JDK 1.2 in this case sets host to null rather than ""; + // this is undocumented and likely an unintended side effect in 1.2 + // so we'll be simple here and stick with "". Note that + // "http://" or "http:///" produce a "" host in JDK 1.2. if ((colon = host.indexOf(':')) >= 0) { try @@ -59,17 +65,55 @@ public abstract class URLStreamHandler } catch (NumberFormatException e) { - ; // Ignore invalid port values; port is already set to -1. + ; // Ignore invalid port values; port is already set to u's + // port. } host = host.substring(0, colon); } + file = null; + start = hostEnd; + } + else if (host == null) + host = ""; + + if (start < limit && spec.charAt(start) == '/') + { + // This is an absolute path name; ignore any file context. + file = spec.substring(start, limit); + } + else if (file == null || file.length() <= 0) + { + // No file context available; just spec for file. + file = "/" + spec.substring(start, limit); + } + else if (start < limit) + { + // Context is available, but only override it if there is a new file. + // FIXME: unsure to what extent `/` and File.separatorChar + // can mix in URLs. Ignore File.separatorChar for now. + file = file.substring(0, file.lastIndexOf('/')) + + "/" + spec.substring(start, limit); } - if (hostEnd < tmpStr.length()) - file = ((tmpStr.startsWith("/")) ? "" : "/") + tmpStr.substring(hostEnd); - else - file = "/"; + int index; + // Replace "/./" with "/". This probably isn't very efficient in + // the general case, but it's probably not bad most of the time. + while ((index = file.indexOf("/./")) >= 0) + file = file.substring(0, index) + file.substring(index + 2); + + // Process "/../" correctly. This probably isn't very efficient in + // the general case, but it's probably not bad most of the time. + while ((index = file.indexOf("/../")) >= 0) + { + // Strip of the previous directory - if it exists. + int previous = file.lastIndexOf('/', index - 1); + if (previous >= 0) + file = file.substring(0, previous) + file.substring(index + 3); + else + file = file.substring(index + 3); + } + u.set(u.getProtocol(), host, port, file, u.getRef()); } @@ -90,12 +134,17 @@ public abstract class URLStreamHandler file = u.getFile(); ref = u.getRef(); - if (! host.equals("")) - { - resStr = resStr + "//" + host; - if (port >= 0) - resStr = resStr + ":" + port; - } + // JDK 1.2 online doc infers that host could be null because it + // explicitly states that file cannot be null, but is silent on host. + // + // Note that this produces different results from JDK 1.2 as JDK 1.2 + // ignores a non-default port if host is null or "". That is inconsistent + // with the spec since the result of this method is spec'ed so it can be + // used to construct a new URL that is equivalent to the original. + if (host == null) + host = ""; + if (port >= 0 || ! (host.length() == 0)) + resStr = resStr + "//" + host + (port < 0 ? "" : ":" + port); resStr = resStr + file; |