aboutsummaryrefslogtreecommitdiff
path: root/libjava/java
diff options
context:
space:
mode:
authorWarren Levy <warrenl@gcc.gnu.org>1999-06-03 22:29:12 +0000
committerWarren Levy <warrenl@gcc.gnu.org>1999-06-03 22:29:12 +0000
commita259a24846c8f0e0a9f494af773acff7fa1dcaaf (patch)
tree6cc7b3c8a9f79ac770d95f7a313ebfed94ca7de5 /libjava/java
parent4d070fd3cd90ca25dd13e3dc5f2777d478930631 (diff)
downloadgcc-a259a24846c8f0e0a9f494af773acff7fa1dcaaf.zip
gcc-a259a24846c8f0e0a9f494af773acff7fa1dcaaf.tar.gz
gcc-a259a24846c8f0e0a9f494af773acff7fa1dcaaf.tar.bz2
[multiple changes]
1999-06-02 Warren Levy <warrenl@cygnus.com> * java/net/URL.java (URL(URL,String)): Initialize port to -1. Ignore context if spec is an absolute URL. Fix braindead string comparison. (hashCode): Use JDK 1.2 style algorithm. * java/net/URLStreamHandler.java (parseURL): Reimplement to handle context URL properly. 1999-05-30 Anthony Green <green@cygnus.com> * java/net/URLStreamHandler.java (parseURL): Parse relative URLs correctly. Clean up "/../" and "/./" path fragments. From-SVN: r27334
Diffstat (limited to 'libjava/java')
-rw-r--r--libjava/java/net/URL.java28
-rw-r--r--libjava/java/net/URLStreamHandler.java103
2 files changed, 100 insertions, 31 deletions
diff --git a/libjava/java/net/URL.java b/libjava/java/net/URL.java
index da56f49..b6dc13d 100644
--- a/libjava/java/net/URL.java
+++ b/libjava/java/net/URL.java
@@ -29,7 +29,7 @@ public final class URL implements Serializable
{
private String protocol;
private String host;
- private int port;
+ private int port = -1; // Initialize for constructor using context.
private String file;
private String ref;
private URLStreamHandler handler;
@@ -117,14 +117,22 @@ public final class URL implements Serializable
* to the context's file. The optional anchor is not inherited.
*/
+ // If this is an absolute URL, then ignore context completely.
+ // An absolute URL must have chars prior to "://" but cannot have a colon
+ // right after the "://". The second colon is for an optional port value
+ // and implies that the host from the context is used if available.
int colon;
+ if ((colon = spec.indexOf("://", 1)) > 0 &&
+ ! spec.regionMatches(colon, "://:", 0, 4))
+ context = null;
+
int slash;
if ((colon = spec.indexOf(':')) > 0 &&
(colon < (slash = spec.indexOf('/')) || slash < 0))
{
// Protocol specified in spec string.
protocol = spec.substring(0, colon);
- if (context != null && context.protocol == protocol)
+ if (context != null && context.protocol.equals(protocol))
{
// The 1.2 doc specifically says these are copied to the new URL.
host = context.host;
@@ -222,8 +230,20 @@ public final class URL implements Serializable
{
// JCL book says this is computed using (only) the hashcodes of the
// protocol, host and file fields. Empirical evidence indicates this
- // is probably XOR.
- return (protocol.hashCode() ^ host.hashCode() ^ file.hashCode());
+ // is probably XOR in JDK 1.1. In JDK 1.2 it seems to be a sum including
+ // the 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.
+ // A simple example with protocol "http" (hashcode 3213448), host null,
+ // file "/" (hashcode 47) produced a hashcode (3213494) which appeared
+ // to be the sum of the two hashcodes plus the port. Another example
+ // using "/index.html" for file bore this out; as well as "#" for file
+ // (which was reduced to "" with a hashcode of zero). A "" host also
+ // causes the port number and the two hashcodes to be summed.
+
+ return (protocol.hashCode() + ((host == null) ? 0 : host.hashCode()) +
+ port + file.hashCode());
}
public URLConnection openConnection() throws IOException
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;