Added: tomcat/sandbox/java/org/apache/tomcat/util/net/SSLSupport.java
URL: 
http://svn.apache.org/viewcvs/tomcat/sandbox/java/org/apache/tomcat/util/net/SSLSupport.java?rev=345653&view=auto
==============================================================================
--- tomcat/sandbox/java/org/apache/tomcat/util/net/SSLSupport.java (added)
+++ tomcat/sandbox/java/org/apache/tomcat/util/net/SSLSupport.java Sat Nov 19 
08:50:47 2005
@@ -0,0 +1,127 @@
+/*
+ *  Copyright 1999-2004 The Apache Software Foundation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.apache.tomcat.util.net;
+
+import java.io.IOException;
+
+/* SSLSupport
+
+   Interface for SSL-specific functions
+
+   @author EKR
+*/
+
+public interface SSLSupport {
+    /**
+     * The Request attribute key for the cipher suite.
+     */
+    public static final String CIPHER_SUITE_KEY = 
"javax.servlet.request.cipher_suite";
+
+    /**
+     * The Request attribute key for the key size.
+     */
+    public static final String KEY_SIZE_KEY = "javax.servlet.request.key_size";
+
+    /**
+     * The Request attribute key for the client certificate chain.
+     */
+    public static final String CERTIFICATE_KEY = 
"javax.servlet.request.X509Certificate";
+
+    /**
+     * The Request attribute key for the session id.
+     * This one is a Tomcat extension to the Servlet spec.
+     */
+    public static final String SESSION_ID_KEY = 
"javax.servlet.request.ssl_session";
+
+    /**
+     * A mapping table to determine the number of effective bits in the key
+     * when using a cipher suite containing the specified cipher name.  The
+     * underlying data came from the TLS Specification (RFC 2246), Appendix C.
+     */
+     static final CipherData ciphers[] = {
+        new CipherData("_WITH_NULL_", 0),
+        new CipherData("_WITH_IDEA_CBC_", 128),
+        new CipherData("_WITH_RC2_CBC_40_", 40),
+        new CipherData("_WITH_RC4_40_", 40),
+        new CipherData("_WITH_RC4_128_", 128),
+        new CipherData("_WITH_DES40_CBC_", 40),
+        new CipherData("_WITH_DES_CBC_", 56),
+        new CipherData("_WITH_3DES_EDE_CBC_", 168)
+    };
+
+    /**
+     * The cipher suite being used on this connection.
+     */
+    public String getCipherSuite() throws IOException;
+
+    /**
+     * The client certificate chain (if any).
+     */
+    public Object[] getPeerCertificateChain()
+        throws IOException;
+
+    /**
+     * The client certificate chain (if any).
+     * @param force If <code>true</code>, then re-negotiate the 
+     *              connection if necessary.
+     */
+    public Object[] getPeerCertificateChain(boolean force)
+        throws IOException;
+
+    /**
+     * Get the keysize.
+     *
+     * What we're supposed to put here is ill-defined by the
+     * Servlet spec (S 4.7 again). There are at least 4 potential
+     * values that might go here:
+     *
+     * (a) The size of the encryption key
+     * (b) The size of the MAC key
+     * (c) The size of the key-exchange key
+     * (d) The size of the signature key used by the server
+     *
+     * Unfortunately, all of these values are nonsensical.
+     **/
+    public Integer getKeySize()
+        throws IOException;
+
+    /**
+     * The current session Id.
+     */
+    public String getSessionId()
+        throws IOException;
+    /**
+     * Simple data class that represents the cipher being used, along with the
+     * corresponding effective key size.  The specified phrase must appear in 
the
+     * name of the cipher suite to be recognized.
+     */
+    
+    final class CipherData {
+    
+        public String phrase = null;
+    
+        public int keySize = 0;
+    
+        public CipherData(String phrase, int keySize) {
+            this.phrase = phrase;
+            this.keySize = keySize;
+        }
+    
+    }
+    
+}
+

Added: tomcat/sandbox/java/org/apache/tomcat/util/net/ServerSocketFactory.java
URL: 
http://svn.apache.org/viewcvs/tomcat/sandbox/java/org/apache/tomcat/util/net/ServerSocketFactory.java?rev=345653&view=auto
==============================================================================
--- tomcat/sandbox/java/org/apache/tomcat/util/net/ServerSocketFactory.java 
(added)
+++ tomcat/sandbox/java/org/apache/tomcat/util/net/ServerSocketFactory.java Sat 
Nov 19 08:50:47 2005
@@ -0,0 +1,172 @@
+/*
+ *  Copyright 1999-2004 The Apache Software Foundation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.apache.tomcat.util.net;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.Hashtable;
+
+/**
+ * This class creates server sockets.  It may be subclassed by other
+ * factories, which create particular types of server sockets.  This
+ * provides a general framework for the addition of public socket-level
+ * functionality.  It it is the server side analogue of a socket factory,
+ * and similarly provides a way to capture a variety of policies related
+ * to the sockets being constructed.
+ *
+ * <P> Like socket factories, Server Socket factory instances have two
+ * categories of methods.  First are methods used to create sockets.
+ * Second are methods which set properties used in the production of
+ * sockets, such as networking options.  There is also an environment
+ * specific default server socket factory; frameworks will often use
+ * their own customized factory.
+ * 
+ * <P><hr><em> It may be desirable to move this interface into the
+ * <b>java.net</b> package, so that is not an extension but the preferred
+ * interface.  Should this be serializable, making it a JavaBean which can
+ * be saved along with its networking configuration?
+ * </em>   
+ *
+ * @author [EMAIL PROTECTED]
+ * @author Harish Prabandham
+ */
+public abstract class ServerSocketFactory implements Cloneable {
+
+    //
+    // NOTE:  JDK 1.1 bug in class GC, this can get collected
+    // even though it's always accessible via getDefault().
+    //
+
+    private static ServerSocketFactory theFactory;
+    protected Hashtable attributes=new Hashtable();
+
+    /**
+     * Constructor is used only by subclasses.
+     */
+
+    protected ServerSocketFactory () {
+        /* NOTHING */
+    }
+
+    /** General mechanism to pass attributes from the
+     *  ServerConnector to the socket factory.
+     *
+     *  Note that the "prefered" mechanism is to
+     *  use bean setters and explicit methods, but
+     *  this allows easy configuration via server.xml
+     *  or simple Properties
+     */
+    public void setAttribute( String name, Object value ) {
+       if( name!=null && value !=null)
+           attributes.put( name, value );
+    }
+    
+    /**
+     * Returns a copy of the environment's default socket factory.
+     */
+    public static synchronized ServerSocketFactory getDefault () {
+        //
+        // optimize typical case:  no synch needed
+        //
+
+        if (theFactory == null) {
+            //
+            // Different implementations of this method could
+            // work rather differently.  For example, driving
+            // this from a system property, or using a different
+            // implementation than JavaSoft's.
+            //
+
+            theFactory = new DefaultServerSocketFactory ();
+        }
+
+        try {
+            return (ServerSocketFactory) theFactory.clone ();
+        } catch (CloneNotSupportedException e) {
+            throw new RuntimeException (e.getMessage ());
+        }
+    }
+
+    /**
+     * Returns a server socket which uses all network interfaces on
+     * the host, and is bound to a the specified port.  The socket is
+     * configured with the socket options (such as accept timeout)
+     * given to this factory.
+     *
+     * @param port the port to listen to
+     * @exception IOException for networking errors
+     * @exception InstantiationException for construction errors
+     */
+    public abstract ServerSocket createSocket (int port)
+    throws IOException, InstantiationException;
+
+    /**
+     * Returns a server socket which uses all network interfaces on
+     * the host, is bound to a the specified port, and uses the 
+     * specified connection backlog.  The socket is configured with
+     * the socket options (such as accept timeout) given to this factory.
+     *
+     * @param port the port to listen to
+     * @param backlog how many connections are queued
+     * @exception IOException for networking errors
+     * @exception InstantiationException for construction errors
+     */
+
+    public abstract ServerSocket createSocket (int port, int backlog)
+    throws IOException, InstantiationException;
+
+    /**
+     * Returns a server socket which uses only the specified network
+     * interface on the local host, is bound to a the specified port,
+     * and uses the specified connection backlog.  The socket is configured
+     * with the socket options (such as accept timeout) given to this factory.
+     *
+     * @param port the port to listen to
+     * @param backlog how many connections are queued
+     * @param ifAddress the network interface address to use
+     * @exception IOException for networking errors
+     * @exception InstantiationException for construction errors
+     */
+
+    public abstract ServerSocket createSocket (int port,
+        int backlog, InetAddress ifAddress)
+    throws IOException, InstantiationException;
+
+    public void initSocket( Socket s ) {
+    }
+ 
+     /**
+       Wrapper function for accept(). This allows us to trap and
+       translate exceptions if necessary
+ 
+       @exception IOException;
+     */ 
+     public abstract Socket acceptSocket(ServerSocket socket)
+       throws IOException;
+ 
+     /**
+       Extra function to initiate the handshake. Sometimes necessary
+       for SSL
+ 
+       @exception IOException;
+     */ 
+     public abstract void handshake(Socket sock)
+       throws IOException;
+}
+

Added: tomcat/sandbox/java/org/apache/tomcat/util/net/TcpConnection.java
URL: 
http://svn.apache.org/viewcvs/tomcat/sandbox/java/org/apache/tomcat/util/net/TcpConnection.java?rev=345653&view=auto
==============================================================================
--- tomcat/sandbox/java/org/apache/tomcat/util/net/TcpConnection.java (added)
+++ tomcat/sandbox/java/org/apache/tomcat/util/net/TcpConnection.java Sat Nov 
19 08:50:47 2005
@@ -0,0 +1,109 @@
+/*
+ *  Copyright 1999-2004 The Apache Software Foundation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.apache.tomcat.util.net;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.Socket;
+
+/**
+ *
+ */
+public class TcpConnection  { // implements Endpoint {
+    /**
+     * Maxium number of times to clear the socket input buffer.
+     */
+    static  int MAX_SHUTDOWN_TRIES=20;
+
+    public TcpConnection() {
+    }
+
+    // -------------------- Properties --------------------
+
+    PoolTcpEndpoint endpoint;
+    Socket socket;
+
+    public static void setMaxShutdownTries(int mst) {
+       MAX_SHUTDOWN_TRIES = mst;
+    }
+    public void setEndpoint(PoolTcpEndpoint endpoint) {
+       this.endpoint = endpoint;
+    }
+
+    public PoolTcpEndpoint getEndpoint() {
+       return endpoint;
+    }
+
+    public void setSocket(Socket socket) {
+       this.socket=socket;
+    }
+
+    public Socket getSocket() {
+       return socket;
+    }
+
+    public void recycle() {
+        endpoint = null;
+        socket = null;
+    }
+
+    // Another frequent repetition
+    public static int readLine(InputStream in, byte[] b, int off, int len)
+       throws IOException
+    {
+       if (len <= 0) {
+           return 0;
+       }
+       int count = 0, c;
+
+       while ((c = in.read()) != -1) {
+           b[off++] = (byte)c;
+           count++;
+           if (c == '\n' || count == len) {
+               break;
+           }
+       }
+       return count > 0 ? count : -1;
+    }
+
+    
+    // Usefull stuff - avoid having it replicated everywhere
+    public static void shutdownInput(Socket socket)
+       throws IOException
+    {
+       try {
+           InputStream is = socket.getInputStream();
+           int available = is.available ();
+           int count=0;
+           
+           // XXX on JDK 1.3 just socket.shutdownInput () which
+           // was added just to deal with such issues.
+           
+           // skip any unread (bogus) bytes
+           while (available > 0 && count++ < MAX_SHUTDOWN_TRIES) {
+               is.skip (available);
+               available = is.available();
+           }
+       }catch(NullPointerException npe) {
+           // do nothing - we are just cleaning up, this is
+           // a workaround for Netscape \n\r in POST - it is supposed
+           // to be ignored
+       }
+    }
+}
+
+

Added: tomcat/sandbox/java/org/apache/tomcat/util/net/TcpConnectionHandler.java
URL: 
http://svn.apache.org/viewcvs/tomcat/sandbox/java/org/apache/tomcat/util/net/TcpConnectionHandler.java?rev=345653&view=auto
==============================================================================
--- tomcat/sandbox/java/org/apache/tomcat/util/net/TcpConnectionHandler.java 
(added)
+++ tomcat/sandbox/java/org/apache/tomcat/util/net/TcpConnectionHandler.java 
Sat Nov 19 08:50:47 2005
@@ -0,0 +1,65 @@
+/*
+ *  Copyright 1999-2004 The Apache Software Foundation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.apache.tomcat.util.net;
+
+
+/**
+ * This interface will be implemented by any object that
+ * uses TcpConnections. It is supported by the pool tcp
+ * connection manager and should be supported by future
+ * managers.
+ * The goal is to decouple the connection handler from
+ * the thread, socket and pooling complexity.
+ */
+public interface TcpConnectionHandler {
+    
+    /** Add informations about the a "controler" object
+     *  specific to the server. In tomcat it will be a
+     *  ContextManager.
+     *  @deprecated This has nothing to do with TcpHandling,
+     *  was used as a workaround
+     */
+    public void setServer(Object manager);
+
+    
+    /** Used to pass config informations to the handler.
+     *
+     *  @deprecated This has nothing to do with Tcp,
+     *    was used as a workaround.
+     */
+    public void setAttribute(String name, Object value );
+    
+    /** Called before the call to processConnection.
+     *  If the thread is reused, init() should be called once per thread.
+     *
+     *  It may look strange, but it's a _very_ good way to avoid synchronized
+     *  methods and keep per thread data.
+     *
+     *  Assert: the object returned from init() will be passed to
+     *  all processConnection() methods happening in the same thread.
+     * 
+     */
+    public Object[] init( );
+
+    /**
+     *  Assert: connection!=null
+     *  Assert: connection.getSocket() != null
+     *  Assert: thData != null and is the result of calling init()
+     *  Assert: thData is preserved per Thread.
+     */
+    public void processConnection(TcpConnection connection, Object thData[]);  
  
+}

Added: tomcat/sandbox/java/org/apache/tomcat/util/net/URL.java
URL: 
http://svn.apache.org/viewcvs/tomcat/sandbox/java/org/apache/tomcat/util/net/URL.java?rev=345653&view=auto
==============================================================================
--- tomcat/sandbox/java/org/apache/tomcat/util/net/URL.java (added)
+++ tomcat/sandbox/java/org/apache/tomcat/util/net/URL.java Sat Nov 19 08:50:47 
2005
@@ -0,0 +1,731 @@
+/*
+ *  Copyright 1999-2004 The Apache Software Foundation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  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;
+
+
+/**
+ * <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":
+ * <pre>
+ *   
&lt;scheme&gt;//&lt;authority&gt;&lt;path&gt;?&lt;query&gt;#&lt;fragment&gt;
+ * </pre></p>
+ *
+ * <p><strong>FIXME</strong> - This class really ought to end up in a Commons
+ * package someplace.</p>
+ *
+ * @author Craig R. McClanahan
+ * @version $Revision: 299472 $ $Date: 2004-06-19 17:08:15 -0700 (Sat, 19 Jun 
2004) $
+ */
+
+public final class URL implements Serializable {
+
+
+    // ----------------------------------------------------------- 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();
+                    // 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());
+        }
+
+    }
+
+
+
+
+
+    /**
+     * Create a URL object from the specified components.  The default port
+     * number for the specified protocol will be used.
+     *
+     * @param protocol Name of the protocol to use
+     * @param host Name of the host addressed by this protocol
+     * @param file Filename on the specified host
+     *
+     * @exception MalformedURLException is never thrown, but present for
+     *  compatible APIs
+     */
+    public URL(String protocol, String host, String file)
+        throws MalformedURLException {
+
+        this(protocol, host, -1, file);
+
+    }
+
+
+    /**
+     * Create a URL object from the specified components.  Specifying a port
+     * number of -1 indicates that the URL should use the default port for
+     * that protocol.  Based on logic from JDK 1.3.1's
+     * <code>java.net.URL</code>.
+     *
+     * @param protocol Name of the protocol to use
+     * @param host Name of the host addressed by this protocol
+     * @param port Port number, or -1 for the default port for this protocol
+     * @param file Filename on the specified host
+     *
+     * @exception MalformedURLException is never thrown, but present for
+     *  compatible APIs
+     */
+    public URL(String protocol, String host, int port, String file)
+        throws MalformedURLException {
+
+        this.protocol = protocol;
+        this.host = host;
+        this.port = port;
+
+        int hash = file.indexOf('#');
+        this.file = hash < 0 ? file : file.substring(0, hash);
+        this.ref = hash < 0 ? null : file.substring(hash + 1);
+        int question = file.lastIndexOf('?');
+        if (question >= 0) {
+            query = file.substring(question + 1);
+            path = file.substring(0, question);
+        } else
+            path = file;
+
+        if ((host != null) && (host.length() > 0))
+            authority = (port == -1) ? host : host + ":" + port;
+
+    }
+
+
+    // ----------------------------------------------------- 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
+     */
+    public boolean equals(Object obj) {
+
+        if (obj == null)
+            return (false);
+        if (!(obj instanceof URL))
+            return (false);
+        URL other = (URL) obj;
+        if (!sameFile(other))
+            return (false);
+        return (compare(ref, other.getRef()));
+
+    }
+
+
+    /**
+     * 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 URL.  This follow the rules in
+     * RFC 2396, Section 5.2, Step 7.
+     */
+    public String toExternalForm() {
+
+        StringBuffer sb = new StringBuffer();
+        if (protocol != null) {
+            sb.append(protocol);
+            sb.append(":");
+        }
+        if (authority != null) {
+            sb.append("//");
+            sb.append(authority);
+        }
+        if (path != null)
+            sb.append(path);
+        if (query != null) {
+            sb.append('?');
+            sb.append(query);
+        }
+        if (ref != null) {
+            sb.append('#');
+            sb.append(ref);
+        }
+        return (sb.toString());
+
+    }
+
+
+    /**
+     * Return a string representation of this object.
+     */
+    public String toString() {
+
+        StringBuffer sb = new StringBuffer("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));
+        }
+
+    }
+
+
+    /**
+     * 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
+     */
+    public static boolean isSchemeChar(char c) {
+        return Character.isLetterOrDigit(c) ||
+            c == '+' || c == '-' || c == '.';
+    }
+
+}

Added: 
tomcat/sandbox/java/org/apache/tomcat/util/net/res/LocalStrings.properties
URL: 
http://svn.apache.org/viewcvs/tomcat/sandbox/java/org/apache/tomcat/util/net/res/LocalStrings.properties?rev=345653&view=auto
==============================================================================
--- tomcat/sandbox/java/org/apache/tomcat/util/net/res/LocalStrings.properties 
(added)
+++ tomcat/sandbox/java/org/apache/tomcat/util/net/res/LocalStrings.properties 
Sat Nov 19 08:50:47 2005
@@ -0,0 +1,24 @@
+# net resources
+endpoint.err.fatal=Endpoint {0} shutdown due to exception: {1}
+endpoint.err.nonfatal=Endpoint {0} ignored exception: {1}
+endpoint.warn.reinit=Reinitializing ServerSocket
+endpoint.warn.restart=Restarting endpoint
+endpoint.warn.security=Endpoint {0} security exception: {1}
+endpoint.err.socket=Socket error caused by remote host {0}
+endpoint.err.handshake=Handshake failed
+endpoint.err.unexpected=Unexpected error processing socket
+endpoint.warn.nullSocket=Null socket returned by accept
+endpoint.debug.unlock=Caught exception trying to unlock accept on port {0}
+endpoint.err.close=Caught exception trying to close socket
+endpoint.noProcessor=No Processors - worker thread dead!
+endpoint.init.bind=Socket bind failed: {0}
+endpoint.init.listen=Socket listen failed: {0}
+
+endpoint.accept.fail=Socket accept failed
+endpoint.poll.limitedpollsize=Failed to create poller with specified size, 
uses 62 instead
+endpoint.poll.initfail=Poller creation failed
+endpoint.poll.fail=Critical poller failure ({0}), restarting poller
+endpoint.poll.error=Unexpected poller error
+endpoint.sendfile.error=Unexpected sendfile error
+endpoint.sendfile.addfail=Sednfile failure with status {0}
+endpoint.sendfile.nosupport=Disabling sendfile, since either the APR version 
or the system doesn't support it

Added: 
tomcat/sandbox/java/org/apache/tomcat/util/net/res/LocalStrings_es.properties
URL: 
http://svn.apache.org/viewcvs/tomcat/sandbox/java/org/apache/tomcat/util/net/res/LocalStrings_es.properties?rev=345653&view=auto
==============================================================================
--- 
tomcat/sandbox/java/org/apache/tomcat/util/net/res/LocalStrings_es.properties 
(added)
+++ 
tomcat/sandbox/java/org/apache/tomcat/util/net/res/LocalStrings_es.properties 
Sat Nov 19 08:50:47 2005
@@ -0,0 +1,6 @@
+# net resources
+endpoint.err.fatal=Punto Final (Endpoint) {0} parado debido a excepción: {1}
+endpoint.err.nonfatal=El Punto Final (Endpoint) {0} ignoró excepción: {1}
+endpoint.warn.reinit=Reinicializando ServerSocket
+endpoint.warn.restart=Rearrancando punto final (endpoint)
+endpoint.warn.security=Punto Final (Endpoint) {0} con excepción de seguridad: 
{1}

Added: 
tomcat/sandbox/java/org/apache/tomcat/util/net/res/LocalStrings_fr.properties
URL: 
http://svn.apache.org/viewcvs/tomcat/sandbox/java/org/apache/tomcat/util/net/res/LocalStrings_fr.properties?rev=345653&view=auto
==============================================================================
--- 
tomcat/sandbox/java/org/apache/tomcat/util/net/res/LocalStrings_fr.properties 
(added)
+++ 
tomcat/sandbox/java/org/apache/tomcat/util/net/res/LocalStrings_fr.properties 
Sat Nov 19 08:50:47 2005
@@ -0,0 +1,6 @@
+# net resources
+endpoint.err.fatal=Le point de contact {0} a été éteint suite à l''exception{1}
+endpoint.err.nonfatal=Le point de contact {0} a ignoré l''exception: {1}
+endpoint.warn.reinit=Réinitialisation du ServerSocket
+endpoint.warn.restart=Redémarrage du point de contact
+

Added: 
tomcat/sandbox/java/org/apache/tomcat/util/net/res/LocalStrings_ja.properties
URL: 
http://svn.apache.org/viewcvs/tomcat/sandbox/java/org/apache/tomcat/util/net/res/LocalStrings_ja.properties?rev=345653&view=auto
==============================================================================
--- 
tomcat/sandbox/java/org/apache/tomcat/util/net/res/LocalStrings_ja.properties 
(added)
+++ 
tomcat/sandbox/java/org/apache/tomcat/util/net/res/LocalStrings_ja.properties 
Sat Nov 19 08:50:47 2005
@@ -0,0 +1,6 @@
+# net resources
+endpoint.err.fatal=\u4f8b\u5916\u306e\u305f\u3081\u306b\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8
 {0} \u306f\u30b7\u30e3\u30c3\u30c8\u30c0\u30a6\u30f3\u3057\u307e\u3059: {1}
+endpoint.err.nonfatal=\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8 {0} 
\u306f\u4f8b\u5916\u3092\u7121\u8996\u3057\u307e\u3057\u305f: {1}
+endpoint.warn.reinit=ServerSocket\u3092\u518d\u521d\u671f\u5316\u3057\u307e\u3059
+endpoint.warn.restart=\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\u3092\u518d\u8d77\u52d5\u3057\u307e\u3059
+endpoint.warn.security=\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8 {0} 
\u306e\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u4f8b\u5916\u3067\u3059: {1}



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to