Author: markt
Date: Wed Jan 6 13:36:56 2016
New Revision: 1723316
URL: http://svn.apache.org/viewvc?rev=1723316&view=rev
Log:
Create a new UriUtil class that contains only those parts of
o.a.tomcat.util.URI that a) are required by Tomcat and b) aren't provided by
the JRE.
Added:
tomcat/trunk/java/org/apache/catalina/util/UriUtil.java
- copied, changed from r1723308,
tomcat/trunk/java/org/apache/tomcat/util/net/URL.java
Copied: tomcat/trunk/java/org/apache/catalina/util/UriUtil.java (from r1723308,
tomcat/trunk/java/org/apache/tomcat/util/net/URL.java)
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/util/UriUtil.java?p2=tomcat/trunk/java/org/apache/catalina/util/UriUtil.java&p1=tomcat/trunk/java/org/apache/tomcat/util/net/URL.java&r1=1723308&r2=1723316&rev=1723316&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/URL.java (original)
+++ tomcat/trunk/java/org/apache/catalina/util/UriUtil.java Wed Jan 6 13:36:56
2016
@@ -14,638 +14,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-package org.apache.tomcat.util.net;
-
-
-import java.io.Serializable;
-import java.net.MalformedURLException;
-import java.util.Locale;
-
+package org.apache.catalina.util;
/**
- * <p><strong>URL</strong> is designed to provide public APIs for parsing
- * and synthesizing Uniform Resource Locators as similar as possible to the
- * APIs of <code>java.net.URL</code>, but without the ability to open a
- * stream or connection. One of the consequences of this is that you can
- * construct URLs for protocols for which a URLStreamHandler is not
- * available (such as an "https" URL when JSSE is not installed).</p>
- *
- * <p><strong>WARNING</strong> - This class assumes that the string
- * representation of a URL conforms to the <code>spec</code> argument
- * as described in RFC 2396 "Uniform Resource Identifiers: Generic Syntax":</p>
- * <pre>
- *
<scheme>//<authority><path>?<query>#<fragment>
- * </pre>
- *
- * <p><strong>FIXME</strong> - This class really ought to end up in a Commons
- * package someplace.</p>
- *
- * @author Craig R. McClanahan
+ * Utility class for working with URIs and URLs.
*/
-public final class URL implements Serializable {
-
- private static final long serialVersionUID = 1L;
-
-
- // ----------------------------------------------------------- Constructors
-
- /**
- * Create a URL object from the specified String representation.
- *
- * @param spec String representation of the URL
- *
- * @exception MalformedURLException if the string representation
- * cannot be parsed successfully
- */
- public URL(String spec) throws MalformedURLException {
-
- this(null, spec);
-
- }
-
-
- /**
- * Create a URL object by parsing a string representation relative
- * to a specified context. Based on logic from JDK 1.3.1's
- * <code>java.net.URL</code>.
- *
- * @param context URL against which the relative representation
- * is resolved
- * @param spec String representation of the URL (usually relative)
- *
- * @exception MalformedURLException if the string representation
- * cannot be parsed successfully
- */
- public URL(URL context, String spec) throws MalformedURLException {
-
- String original = spec;
- int i, limit, c;
- int start = 0;
- String newProtocol = null;
- boolean aRef = false;
-
- try {
-
- // Eliminate leading and trailing whitespace
- limit = spec.length();
- while ((limit > 0) && (spec.charAt(limit - 1) <= ' ')) {
- limit--;
- }
- while ((start < limit) && (spec.charAt(start) <= ' ')) {
- start++;
- }
-
- // If the string representation starts with "url:", skip it
- if (spec.regionMatches(true, start, "url:", 0, 4)) {
- start += 4;
- }
-
- // Is this a ref relative to the context URL?
- if ((start < spec.length()) && (spec.charAt(start) == '#')) {
- aRef = true;
- }
-
- // Parse out the new protocol
- for (i = start; !aRef && (i < limit) ; i++) {
- c = spec.charAt(i);
- if (c == ':') {
- String s = spec.substring(start,
i).toLowerCase(Locale.ENGLISH);
- // Assume all protocols are valid
- newProtocol = s;
- start = i + 1;
- break;
- } else if( c == '#' ) {
- aRef = true;
- } else if( !isSchemeChar((char)c) ) {
- break;
- }
- }
-
- // Only use our context if the protocols match
- protocol = newProtocol;
- if ((context != null) && ((newProtocol == null) ||
- newProtocol.equalsIgnoreCase(context.getProtocol()))) {
- // If the context is a hierarchical URL scheme and the spec
- // contains a matching scheme then maintain backwards
- // compatibility and treat it as if the spec didn't contain
- // the scheme; see 5.2.3 of RFC2396
- if ((context.getPath() != null) &&
- (context.getPath().startsWith("/")))
- newProtocol = null;
- if (newProtocol == null) {
- protocol = context.getProtocol();
- authority = context.getAuthority();
- userInfo = context.getUserInfo();
- host = context.getHost();
- port = context.getPort();
- file = context.getFile();
- int question = file.lastIndexOf('?');
- if (question < 0)
- path = file;
- else
- path = file.substring(0, question);
- }
- }
-
- if (protocol == null)
- throw new MalformedURLException("no protocol: " + original);
-
- // Parse out any ref portion of the spec
- i = spec.indexOf('#', start);
- if (i >= 0) {
- ref = spec.substring(i + 1, limit);
- limit = i;
- }
-
- // Parse the remainder of the spec in a protocol-specific fashion
- parse(spec, start, limit);
- if (context != null)
- normalize();
-
-
- } catch (MalformedURLException e) {
- throw e;
- } catch (Exception e) {
- throw new MalformedURLException(e.toString());
- }
-
- }
-
-
- // ----------------------------------------------------- Instance Variables
-
-
- /**
- * The authority part of the URL.
- */
- private String authority = null;
-
-
- /**
- * The filename part of the URL.
- */
- private String file = null;
-
-
- /**
- * The host name part of the URL.
- */
- private String host = null;
-
-
- /**
- * The path part of the URL.
- */
- private String path = null;
-
-
- /**
- * The port number part of the URL.
- */
- private int port = -1;
-
-
- /**
- * The protocol name part of the URL.
- */
- private String protocol = null;
-
-
- /**
- * The query part of the URL.
- */
- private String query = null;
-
-
- /**
- * The reference part of the URL.
- */
- private String ref = null;
-
-
- /**
- * The user info part of the URL.
- */
- private String userInfo = null;
-
-
- // --------------------------------------------------------- Public Methods
-
-
- /**
- * Compare two URLs for equality. The result is <code>true</code> if and
- * only if the argument is not null, and is a <code>URL</code> object
- * that represents the same <code>URL</code> as this object. Two
- * <code>URLs</code> are equal if they have the same protocol and
- * reference the same host, the same port number on the host,
- * and the same file and anchor on the host.
- *
- * @param obj The URL to compare against
- */
- @Override
- public boolean equals(Object obj) {
-
- if (!(obj instanceof URL))
- return false;
- URL other = (URL) obj;
- if (!sameFile(other))
- return false;
- return (compare(ref, other.getRef()));
-
- }
-
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((file == null) ? 0 : file.hashCode());
- result = prime * result + ((host == null) ? 0 : host.hashCode());
- result = prime * result + port;
- result = prime * result +
- ((protocol == null) ? 0 : protocol.hashCode());
- result = prime * result + ((ref == null) ? 0 : ref.hashCode());
- return result;
- }
-
-
- /**
- * Return the authority part of the URL.
- */
- public String getAuthority() {
-
- return (this.authority);
-
- }
-
-
- /**
- * Return the filename part of the URL. <strong>NOTE</strong> - For
- * compatibility with <code>java.net.URL</code>, this value includes
- * the query string if there was one. For just the path portion,
- * call <code>getPath()</code> instead.
- */
- public String getFile() {
-
- if (file == null)
- return ("");
- return (this.file);
-
- }
-
-
- /**
- * Return the host name part of the URL.
- */
- public String getHost() {
-
- return (this.host);
-
- }
-
-
- /**
- * Return the path part of the URL.
- */
- public String getPath() {
-
- if (this.path == null)
- return ("");
- return (this.path);
-
- }
-
-
- /**
- * Return the port number part of the URL.
- */
- public int getPort() {
-
- return (this.port);
-
- }
-
-
- /**
- * Return the protocol name part of the URL.
- */
- public String getProtocol() {
-
- return (this.protocol);
-
- }
-
-
- /**
- * Return the query part of the URL.
- */
- public String getQuery() {
-
- return (this.query);
-
- }
-
-
- /**
- * Return the reference part of the URL.
- */
- public String getRef() {
-
- return (this.ref);
-
- }
-
-
- /**
- * Return the user info part of the URL.
- */
- public String getUserInfo() {
-
- return (this.userInfo);
-
- }
-
-
- /**
- * Normalize the <code>path</code> (and therefore <code>file</code>)
- * portions of this URL.
- * <p>
- * <strong>NOTE</strong> - This method is not part of the public API
- * of <code>java.net.URL</code>, but is provided as a value added
- * service of this implementation.
- *
- * @exception MalformedURLException if a normalization error occurs,
- * such as trying to move about the hierarchical root
- */
- public void normalize() throws MalformedURLException {
-
- // Special case for null path
- if (path == null) {
- if (query != null)
- file = "?" + query;
- else
- file = "";
- return;
- }
-
- // Create a place for the normalized path
- String normalized = path;
- if (normalized.equals("/.")) {
- path = "/";
- if (query != null)
- file = path + "?" + query;
- else
- file = path;
- return;
- }
-
- // Normalize the slashes and add leading slash if necessary
- if (normalized.indexOf('\\') >= 0)
- normalized = normalized.replace('\\', '/');
- if (!normalized.startsWith("/"))
- normalized = "/" + normalized;
-
- // Resolve occurrences of "//" in the normalized path
- while (true) {
- int index = normalized.indexOf("//");
- if (index < 0)
- break;
- normalized = normalized.substring(0, index) +
- normalized.substring(index + 1);
- }
-
- // Resolve occurrences of "/./" in the normalized path
- while (true) {
- int index = normalized.indexOf("/./");
- if (index < 0)
- break;
- normalized = normalized.substring(0, index) +
- normalized.substring(index + 2);
- }
-
- // Resolve occurrences of "/../" in the normalized path
- while (true) {
- int index = normalized.indexOf("/../");
- if (index < 0)
- break;
- if (index == 0)
- throw new MalformedURLException
- ("Invalid relative URL reference");
- int index2 = normalized.lastIndexOf('/', index - 1);
- normalized = normalized.substring(0, index2) +
- normalized.substring(index + 3);
- }
-
- // Resolve occurrences of "/." at the end of the normalized path
- if (normalized.endsWith("/."))
- normalized = normalized.substring(0, normalized.length() - 1);
-
- // Resolve occurrences of "/.." at the end of the normalized path
- if (normalized.endsWith("/..")) {
- int index = normalized.length() - 3;
- int index2 = normalized.lastIndexOf('/', index - 1);
- if (index2 < 0)
- throw new MalformedURLException
- ("Invalid relative URL reference");
- normalized = normalized.substring(0, index2 + 1);
- }
-
- // Return the normalized path that we have completed
- path = normalized;
- if (query != null)
- file = path + "?" + query;
- else
- file = path;
-
- }
-
-
- /**
- * Compare two URLs, excluding the "ref" fields. Returns <code>true</code>
- * if this <code>URL</code> and the <code>other</code> argument both refer
- * to the same resource. The two <code>URLs</code> might not both contain
- * the same anchor.
- */
- public boolean sameFile(URL other) {
-
- if (!compare(protocol, other.getProtocol()))
- return false;
- if (!compare(host, other.getHost()))
- return false;
- if (port != other.getPort())
- return false;
- if (!compare(file, other.getFile()))
- return false;
- return true;
-
- }
-
-
- /**
- * Return a string representation of this object.
- */
- @Override
- public String toString() {
-
- StringBuilder sb = new StringBuilder("URL[");
- sb.append("authority=");
- sb.append(authority);
- sb.append(", file=");
- sb.append(file);
- sb.append(", host=");
- sb.append(host);
- sb.append(", port=");
- sb.append(port);
- sb.append(", protocol=");
- sb.append(protocol);
- sb.append(", query=");
- sb.append(query);
- sb.append(", ref=");
- sb.append(ref);
- sb.append(", userInfo=");
- sb.append(userInfo);
- sb.append("]");
- return (sb.toString());
-
- // return (toExternalForm());
-
- }
-
-
- // -------------------------------------------------------- Private Methods
-
-
- /**
- * Compare to String values for equality, taking appropriate care if one
- * or both of the values are <code>null</code>.
- *
- * @param first First string
- * @param second Second string
- */
- private boolean compare(String first, String second) {
-
- if (first == null) {
- if (second == null)
- return true;
- else
- return false;
- } else {
- if (second == null)
- return false;
- else
- return (first.equals(second));
- }
+public final class UriUtil {
+ private UriUtil() {
+ // Utility class. Hide default constructor
}
/**
- * Parse the specified portion of the string representation of a URL,
- * assuming that it has a format similar to that for <code>http</code>.
- *
- * <p><strong>FIXME</strong> - This algorithm can undoubtedly be optimized
- * for performance. However, that needs to wait until after sufficient
- * unit tests are implemented to guarantee correct behavior with no
- * regressions.</p>
- *
- * @param spec String representation being parsed
- * @param start Starting offset, which will be just after the ':' (if
- * there is one) that determined the protocol name
- * @param limit Ending position, which will be the position of the '#'
- * (if there is one) that delimited the anchor
- *
- * @exception MalformedURLException if a parsing error occurs
- */
- private void parse(String spec, int start, int limit)
- throws MalformedURLException {
-
- // Trim the query string (if any) off the tail end
- int question = spec.lastIndexOf('?', limit - 1);
- if ((question >= 0) && (question < limit)) {
- query = spec.substring(question + 1, limit);
- limit = question;
- } else {
- query = null;
- }
-
- // Parse the authority section
- if (spec.indexOf("//", start) == start) {
- int pathStart = spec.indexOf('/', start + 2);
- if ((pathStart >= 0) && (pathStart < limit)) {
- authority = spec.substring(start + 2, pathStart);
- start = pathStart;
- } else {
- authority = spec.substring(start + 2, limit);
- start = limit;
- }
- if (authority.length() > 0) {
- int at = authority.indexOf('@');
- if( at >= 0 ) {
- userInfo = authority.substring(0,at);
- }
- int ipv6 = authority.indexOf('[',at+1);
- int hStart = at+1;
- if( ipv6 >= 0 ) {
- hStart = ipv6;
- ipv6 = authority.indexOf(']', ipv6);
- if( ipv6 < 0 ) {
- throw new MalformedURLException(
- "Closing ']' not found
in IPV6 address: " + authority);
- } else {
- at = ipv6-1;
- }
- }
-
- int colon = authority.indexOf(':', at+1);
- if (colon >= 0) {
- try {
- port =
- Integer.parseInt(authority.substring(colon + 1));
- } catch (NumberFormatException e) {
- throw new MalformedURLException(e.toString());
- }
- host = authority.substring(hStart, colon);
- } else {
- host = authority.substring(hStart);
- port = -1;
- }
- }
- }
-
- // Parse the path section
- if (spec.indexOf('/', start) == start) { // Absolute path
- path = spec.substring(start, limit);
- if (query != null)
- file = path + "?" + query;
- else
- file = path;
- return;
- }
-
- // Resolve relative path against our context's file
- if (path == null) {
- if (query != null)
- file = "?" + query;
- else
- file = null;
- return;
- }
- if (!path.startsWith("/"))
- throw new MalformedURLException
- ("Base path does not start with '/'");
- if (!path.endsWith("/"))
- path += "/../";
- path += spec.substring(start, limit);
- if (query != null)
- file = path + "?" + query;
- else
- file = path;
- return;
-
- }
-
- /**
* Determine if the character is allowed in the scheme of a URI.
* See RFC 2396, Section 3.1
*
@@ -655,8 +36,7 @@ public final class URL implements Serial
* @false}
*/
private static boolean isSchemeChar(char c) {
- return Character.isLetterOrDigit(c) ||
- c == '+' || c == '-' || c == '.';
+ return Character.isLetterOrDigit(c) || c == '+' || c == '-' || c ==
'.';
}
@@ -673,7 +53,7 @@ public final class URL implements Serial
char c = uri.charAt(i);
if(c == ':') {
return i > 0;
- } else if(!URL.isSchemeChar(c)) {
+ } else if(!UriUtil.isSchemeChar(c)) {
return false;
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]