tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From p...@apache.org
Subject cvs commit: jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/http/mapper HostMap.java Mapper.java
Date Sat, 04 Jun 2005 12:32:53 GMT
pero        2005/06/04 05:32:53

  Modified:    util/java/org/apache/tomcat/util/http/mapper Mapper.java
  Added:       util/java/org/apache/tomcat/util/http/mapper HostMap.java
  Log:
  Support Host Alias matching with Connector attribute allowedAliasMatches
  Submitted by George Sexton
  
  Revision  Changes    Path
  1.45      +506 -308  jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/http/mapper/Mapper.java
  
  Index: Mapper.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/http/mapper/Mapper.java,v
  retrieving revision 1.44
  retrieving revision 1.45
  diff -u -r1.44 -r1.45
  --- Mapper.java	21 Mar 2005 15:37:10 -0000	1.44
  +++ Mapper.java	4 Jun 2005 12:32:53 -0000	1.45
  @@ -16,33 +16,38 @@
   
   package org.apache.tomcat.util.http.mapper;
   
  -import javax.naming.NamingException;
  +import java.util.List;
  +import java.util.ArrayList;
  +
   import javax.naming.directory.DirContext;
  +import javax.naming.NamingException;
   
  +import org.apache.tomcat.util.buf.Ascii;
   import org.apache.tomcat.util.buf.CharChunk;
   import org.apache.tomcat.util.buf.MessageBytes;
  -import org.apache.tomcat.util.buf.Ascii;
  -import java.util.List;
  -import java.util.ArrayList;
   
   /**
    * Mapper, which implements the servlet API mapping rules (which are derived
    * from the HTTP rules).
    *
    * @author Remy Maucherat
  + * @author George Sexton
  + * @author Peter Rossbach
    */
   public final class Mapper {
   
   
       private static org.apache.commons.logging.Log logger =
  -        org.apache.commons.logging.LogFactory.getLog(Mapper.class);
  +    org.apache.commons.logging.LogFactory.getLog(Mapper.class);
       // ----------------------------------------------------- Instance Variables
   
   
  +    HostMap hostMap=new HostMap();
  +
       /**
  -     * Array containing the virtual hosts definitions.
  +     * Default number of alias matches for each host.
        */
  -    protected Host[] hosts = new Host[0];
  +    private int defaultAliasMatches=0;
   
   
       /**
  @@ -51,6 +56,12 @@
       protected String defaultHostName = null;
   
       /**
  +     * Default host, already looked up cached to 
  +     * eliminate lookup.
  +     */
  +    protected Host defaultHost=null;
  +
  +    /**
        * Context associated with this wrapper, used for wrapper mapping.
        */
       protected Context context = new Context();
  @@ -58,6 +69,23 @@
   
       // --------------------------------------------------------- Public Methods
   
  +    /**
  +     * Set the number of allowed alias matches. If this number is
  +     * non-zero, then wild-card host matching is enabled. This 
  +     * number limits the number of wild-card host matches in
  +     * order to prevent a denial of service attack.
  +     */
  +    public void setAllowedAliasMatches(final int matches){
  +        defaultAliasMatches=matches;
  +        hostMap.setEnableWildCardMatching(matches>0);
  +    }
  +
  +    /**
  +     * 
  +     */
  +    public int getAllowedAliasMatches(){
  +        return defaultAliasMatches;
  +    }
   
       /**
        * Get default host.
  @@ -76,9 +104,21 @@
        */
       public void setDefaultHostName(String defaultHostName) {
           this.defaultHostName = defaultHostName;
  +        defaultHost=null;
       }
   
       /**
  +     * Return the default host, or null if the host
  +     * has not been set.
  +     */
  +    private Host getDefaultHost(){
  +        if (defaultHost==null && defaultHostName!=null) {
  +            defaultHost=hostMap.getHost(defaultHostName);
  +        }
  +        return defaultHost;
  +    }
  +    
  +    /**
        * Add a new host to the mapper.
        *
        * @param name Virtual host name
  @@ -86,25 +126,30 @@
        */
       public synchronized void addHost(String name, String[] aliases,
                                        Object host) {
  -        Host[] newHosts = new Host[hosts.length + 1];
  -        Host newHost = new Host();
  -        ContextList contextList = new ContextList();
  -        newHost.name = name;
  -        newHost.contextList = contextList;
  -        newHost.object = host;
  -        if (insertMap(hosts, newHosts, newHost)) {
  -            hosts = newHosts;
  -        }
  -        for (int i = 0; i < aliases.length; i++) {
  -            newHosts = new Host[hosts.length + 1];
  -            newHost = new Host();
  -            newHost.name = aliases[i];
  -            newHost.contextList = contextList;
  -            newHost.object = host;
  -            if (insertMap(hosts, newHosts, newHost)) {
  -                hosts = newHosts;
  +        HostMap hm=hostMap;
  +        if (hm.contains(name)) {
  +            return;
  +        }
  +        hm=new HostMap(hm);
  +        
  +        Host newHost=new Host();
  +        ContextList contextList=new ContextList();
  +        newHost.name=name;
  +        newHost.contextList=contextList;
  +        newHost.object=host;
  +        newHost.aliasMatchesRemaining=defaultAliasMatches;
  +        hm.addHost(newHost);
  +        for (int i=0; i < aliases.length; i++) {
  +            if (!hm.contains(aliases[i])) {
  +                newHost=new Host();
  +                newHost.aliasMatchesRemaining=defaultAliasMatches;
  +                newHost.name=aliases[i];
  +                newHost.contextList=contextList;
  +                newHost.object=host;
  +                hm.addHost(newHost);
               }
           }
  +        hostMap=hm;
       }
   
   
  @@ -114,33 +159,20 @@
        * @param name Virtual host name
        */
       public synchronized void removeHost(String name) {
  -        // Find and remove the old host
  -        int pos = find(hosts, name);
  -        if (pos < 0) {
  +
  +        if (!hostMap.contains(name)) {
               return;
           }
  -        Object host = hosts[pos].object;
  -        Host[] newHosts = new Host[hosts.length - 1];
  -        if (removeMap(hosts, newHosts, name)) {
  -            hosts = newHosts;
  -        }
  -        // Remove all aliases (they will map to the same host object)
  -        for (int i = 0; i < newHosts.length; i++) {
  -            if (newHosts[i].object == host) {
  -                Host[] newHosts2 = new Host[hosts.length - 1];
  -                if (removeMap(hosts, newHosts2, newHosts[i].name)) {
  -                    hosts = newHosts2;
  -                }
  -            }
  -        }
  +        HostMap hm=new HostMap(hostMap);
  +        hm.removeHost(name);
  +        hostMap=hm;
       }
  -
  + 
  +    /**
  +     * Get current host matching map
  +     */
       public String[] getHosts() {
  -        String hostN[] = new String[hosts.length];
  -        for( int i = 0; i < hosts.length; i++ ) {
  -            hostN[i] = hosts[i].name;
  -        }
  -        return hostN;
  +        return hostMap.getHosts();
       }
   
   
  @@ -168,40 +200,31 @@
        * @param resources Static resources of the context
        */
       public void addContext
  -        (String hostName, String path, Object context,
  -         String[] welcomeResources, javax.naming.Context resources) {
  +    (String hostName, String path, Object context,
  +     String[] welcomeResources, javax.naming.Context resources) {
   
  -        Host[] hosts = this.hosts;
  -        int pos = find(hosts, hostName);
  -        if( pos <0 ) {
  +        Host host=hostMap.getHost(hostName);
  +        if (host==null) {
               addHost(hostName, new String[0], "");
  -            hosts = this.hosts;
  -            pos = find(hosts, hostName);
  +            host=hostMap.getHost(hostName);
           }
  -        if (pos < 0) {
  -            logger.error("No host found: " + hostName);
  -        }
  -        Host host = hosts[pos];
  -        if (host.name.equals(hostName)) {
  -            int slashCount = slashCount(path);
  -            synchronized (host) {
  -                Context[] contexts = host.contextList.contexts;
  -                // Update nesting
  -                if (slashCount > host.contextList.nesting) {
  -                    host.contextList.nesting = slashCount;
  -                }
  -                Context[] newContexts = new Context[contexts.length + 1];
  -                Context newContext = new Context();
  -                newContext.name = path;
  -                newContext.object = context;
  -                newContext.welcomeResources = welcomeResources;
  -                newContext.resources = resources;
  -                if (insertMap(contexts, newContexts, newContext)) {
  -                    host.contextList.contexts = newContexts;
  -                }
  +        int slashCount = slashCount(path);
  +        synchronized (host) {
  +            Context[] contexts = host.contextList.contexts;
  +            // Update nesting
  +            if (slashCount > host.contextList.nesting) {
  +                host.contextList.nesting = slashCount;
  +            }
  +            Context[] newContexts = new Context[contexts.length + 1];
  +            Context newContext = new Context();
  +            newContext.name = path;
  +            newContext.object = context;
  +            newContext.welcomeResources = welcomeResources;
  +            newContext.resources = resources;
  +            if (insertMap(contexts, newContexts, newContext)) {
  +                host.contextList.contexts = newContexts;
               }
           }
  -
       }
   
   
  @@ -212,32 +235,29 @@
        * @param path Context path
        */
       public void removeContext(String hostName, String path) {
  -        Host[] hosts = this.hosts;
  -        int pos = find(hosts, hostName);
  -        if (pos < 0) {
  +        Host host=hostMap.getHost(hostName);
  +        if (host==null) {
               return;
           }
  -        Host host = hosts[pos];
  -        if (host.name.equals(hostName)) {
  -            synchronized (host) {
  -                Context[] contexts = host.contextList.contexts;
  -                if( contexts.length == 0 ){
  -                    return;
  -                }
  -                Context[] newContexts = new Context[contexts.length - 1];
  -                if (removeMap(contexts, newContexts, path)) {
  -                    host.contextList.contexts = newContexts;
  -                    // Recalculate nesting
  -                    host.contextList.nesting = 0;
  -                    for (int i = 0; i < newContexts.length; i++) {
  -                        int slashCount = slashCount(newContexts[i].name);
  -                        if (slashCount > host.contextList.nesting) {
  -                            host.contextList.nesting = slashCount;
  -                        }
  +        synchronized (host) {
  +            Context[] contexts = host.contextList.contexts;
  +            if ( contexts.length == 0 ) {
  +                return;
  +            }
  +            Context[] newContexts = new Context[contexts.length - 1];
  +            if (removeMap(contexts, newContexts, path)) {
  +                host.contextList.contexts = newContexts;
  +                // Recalculate nesting
  +                host.contextList.nesting = 0;
  +                for (int i = 0; i < newContexts.length; i++) {
  +                    int slashCount = slashCount(newContexts[i].name);
  +                    if (slashCount > host.contextList.nesting) {
  +                        host.contextList.nesting = slashCount;
                       }
                   }
               }
           }
  +
       }
   
   
  @@ -248,15 +268,16 @@
        */
       public String[] getContextNames() {
           List list=new ArrayList();
  -        for( int i=0; i<hosts.length; i++ ) {
  -            for( int j=0; j<hosts[i].contextList.contexts.length; j++ ) {
  +        Host[] hosts=hostMap.toHostArray();
  +        for ( int i=0; i<hosts.length; i++ ) {
  +            for ( int j=0; j<hosts[i].contextList.contexts.length; j++ ) {
                   String cname=hosts[i].contextList.contexts[j].name;
                   list.add("//" + hosts[i].name +
  -                        (cname.startsWith("/") ? cname : "/"));
  +                         (cname.startsWith("/") ? cname : "/"));
               }
           }
           String res[] = new String[list.size()];
  -        return (String[])list.toArray(res);
  +        return(String[])list.toArray(res);
       }
   
   
  @@ -276,23 +297,19 @@
   
       public void addWrapper(String hostName, String contextPath, String path,
                              Object wrapper, boolean jspWildCard) {
  -        Host[] hosts = this.hosts;
  -        int pos = find(hosts, hostName);
  -        if (pos < 0) {
  +        Host host=hostMap.getHost(hostName);
  +        if (host==null) {
               return;
           }
  -        Host host = hosts[pos];
  -        if (host.name.equals(hostName)) {
  -            Context[] contexts = host.contextList.contexts;
  -            int pos2 = find(contexts, contextPath);
  -            if( pos2<0 ) {
  -                logger.error("No context found: " + contextPath );
  -                return;
  -            }
  -            Context context = contexts[pos2];
  -            if (context.name.equals(contextPath)) {
  -                addWrapper(context, path, wrapper, jspWildCard);
  -            }
  +        Context[] contexts = host.contextList.contexts;
  +        int pos2 = find(contexts, contextPath);
  +        if ( pos2<0 ) {
  +            logger.error("No context found: " + contextPath );
  +            return;
  +        }
  +        Context context = contexts[pos2];
  +        if (context.name.equals(contextPath)) {
  +            addWrapper(context, path, wrapper, jspWildCard);
           }
       }
   
  @@ -339,7 +356,7 @@
                   newWrapper.name = path.substring(0, path.length() - 2);
                   Wrapper[] oldWrappers = context.wildcardWrappers;
                   Wrapper[] newWrappers =
  -                    new Wrapper[oldWrappers.length + 1];
  +                new Wrapper[oldWrappers.length + 1];
                   if (insertMap(oldWrappers, newWrappers, newWrapper)) {
                       context.wildcardWrappers = newWrappers;
                       int slashCount = slashCount(newWrapper.name);
  @@ -352,7 +369,7 @@
                   newWrapper.name = path.substring(2);
                   Wrapper[] oldWrappers = context.extensionWrappers;
                   Wrapper[] newWrappers =
  -                    new Wrapper[oldWrappers.length + 1];
  +                new Wrapper[oldWrappers.length + 1];
                   if (insertMap(oldWrappers, newWrappers, newWrapper)) {
                       context.extensionWrappers = newWrappers;
                   }
  @@ -365,7 +382,7 @@
                   newWrapper.name = path;
                   Wrapper[] oldWrappers = context.exactWrappers;
                   Wrapper[] newWrappers =
  -                    new Wrapper[oldWrappers.length + 1];
  +                new Wrapper[oldWrappers.length + 1];
                   if (insertMap(oldWrappers, newWrappers, newWrapper)) {
                       context.exactWrappers = newWrappers;
                   }
  @@ -392,23 +409,19 @@
        * @param path Wrapper mapping
        */
       public void removeWrapper
  -        (String hostName, String contextPath, String path) {
  -        Host[] hosts = this.hosts;
  -        int pos = find(hosts, hostName);
  -        if (pos < 0) {
  +    (String hostName, String contextPath, String path) {
  +        Host host=hostMap.getHost(hostName);
  +        if (host==null) {
               return;
           }
  -        Host host = hosts[pos];
  -        if (host.name.equals(hostName)) {
  -            Context[] contexts = host.contextList.contexts;
  -            int pos2 = find(contexts, contextPath);
  -            if (pos2 < 0) {
  -                return;
  -            }
  -            Context context = contexts[pos2];
  -            if (context.name.equals(contextPath)) {
  -                removeWrapper(context, path);
  -            }
  +        Context[] contexts = host.contextList.contexts;
  +        int pos2 = find(contexts, contextPath);
  +        if (pos2 < 0) {
  +            return;
  +        }
  +        Context context = contexts[pos2];
  +        if (context.name.equals(contextPath)) {
  +            removeWrapper(context, path);
           }
       }
   
  @@ -419,7 +432,7 @@
                   String name = path.substring(0, path.length() - 2);
                   Wrapper[] oldWrappers = context.wildcardWrappers;
                   Wrapper[] newWrappers =
  -                    new Wrapper[oldWrappers.length - 1];
  +                new Wrapper[oldWrappers.length - 1];
                   if (removeMap(oldWrappers, newWrappers, name)) {
                       // Recalculate nesting
                       context.nesting = 0;
  @@ -436,7 +449,7 @@
                   String name = path.substring(2);
                   Wrapper[] oldWrappers = context.extensionWrappers;
                   Wrapper[] newWrappers =
  -                    new Wrapper[oldWrappers.length - 1];
  +                new Wrapper[oldWrappers.length - 1];
                   if (removeMap(oldWrappers, newWrappers, name)) {
                       context.extensionWrappers = newWrappers;
                   }
  @@ -448,7 +461,7 @@
                   String name = path;
                   Wrapper[] oldWrappers = context.exactWrappers;
                   Wrapper[] newWrappers =
  -                    new Wrapper[oldWrappers.length - 1];
  +                new Wrapper[oldWrappers.length - 1];
                   if (removeMap(oldWrappers, newWrappers, name)) {
                       context.exactWrappers = newWrappers;
                   }
  @@ -459,38 +472,39 @@
       public String getWrappersString( String host, String context ) {
           String names[]=getWrapperNames(host, context);
           StringBuffer sb=new StringBuffer();
  -        for( int i=0; i<names.length; i++ ) {
  +        for ( int i=0; i<names.length; i++ ) {
               sb.append(names[i]).append(":");
           }
           return sb.toString();
       }
   
  -    public String[] getWrapperNames( String host, String context ) {
  +    public String[] getWrapperNames( String hostName, String context ) {
           List list=new ArrayList();
  -        if( host==null ) host="";
  -        if( context==null ) context="";
  -        for( int i=0; i<hosts.length; i++ ) {
  -            if( ! host.equals( hosts[i].name ))
  -                continue;
  -            for( int j=0; j<hosts[i].contextList.contexts.length; j++ ) {
  -                if( ! context.equals( hosts[i].contextList.contexts[j].name))
  +        if ( hostName==null ) hostName="";
  +        if ( context==null ) context="";
  +        Host host=hostMap.getHost(hostName);
  +        if (host!=null) {
  +
  +            for ( int j=0; j<host.contextList.contexts.length; j++ ) {
  +
  +                if ( ! context.equals( host.contextList.contexts[j].name))
                       continue;
                   // found the context
  -                Context ctx=hosts[i].contextList.contexts[j];
  +                Context ctx=host.contextList.contexts[j];
                   list.add( ctx.defaultWrapper.path);
  -                for( int k=0; k<ctx.exactWrappers.length; k++ ) {
  +                for ( int k=0; k<ctx.exactWrappers.length; k++ ) {
                       list.add( ctx.exactWrappers[k].path);
                   }
  -                for( int k=0; k<ctx.wildcardWrappers.length; k++ ) {
  +                for ( int k=0; k<ctx.wildcardWrappers.length; k++ ) {
                       list.add( ctx.wildcardWrappers[k].path + "*");
                   }
  -                for( int k=0; k<ctx.extensionWrappers.length; k++ ) {
  +                for ( int k=0; k<ctx.extensionWrappers.length; k++ ) {
                       list.add( "*." + ctx.extensionWrappers[k].path);
                   }
               }
           }
           String res[]=new String[list.size()];
  -        return (String[])list.toArray(res);
  +        return(String[])list.toArray(res);
       }
   
   
  @@ -505,7 +519,7 @@
        */
       public void map(MessageBytes host, MessageBytes uri,
                       MappingData mappingData)
  -        throws Exception {
  +    throws Exception {
   
           host.toChars();
           uri.toChars();
  @@ -523,7 +537,7 @@
        *                    operation
        */
       public void map(MessageBytes uri, MappingData mappingData)
  -        throws Exception {
  +    throws Exception {
   
           uri.toChars();
           CharChunk uricc = uri.getCharChunk();
  @@ -541,7 +555,7 @@
        */
       private final void internalMap(CharChunk host, CharChunk uri,
                                      MappingData mappingData)
  -        throws Exception {
  +    throws Exception {
   
           uri.setLimit(-1);
   
  @@ -551,25 +565,16 @@
   
           // Virtual host mapping
           if (mappingData.host == null) {
  -            Host[] hosts = this.hosts;
  -            int pos = findIgnoreCase(hosts, host);
  -            if ((pos != -1) && (host.equalsIgnoreCase(hosts[pos].name))) {
  -                mappingData.host = hosts[pos].object;
  -                contexts = hosts[pos].contextList.contexts;
  -                nesting = hosts[pos].contextList.nesting;
  -            } else {
  -                if (defaultHostName == null) {
  -                    return;
  -                }
  -                pos = find(hosts, defaultHostName);
  -                if ((pos != -1) && (defaultHostName.equals(hosts[pos].name))) {
  -                    mappingData.host = hosts[pos].object;
  -                    contexts = hosts[pos].contextList.contexts;
  -                    nesting = hosts[pos].contextList.nesting;
  -                } else {
  +            Host hFound=hostMap.getHost(host);
  +            if (hFound==null) {
  +                hFound=getDefaultHost();
  +                if (hFound==null) {
                       return;
                   }
               }
  +            mappingData.host=hFound.object;
  +            contexts = hFound.contextList.contexts;
  +            nesting = hFound.contextList.nesting;
           }
   
           // Context mapping
  @@ -630,7 +635,7 @@
        */
       private final void internalMapWrapper(Context context, CharChunk path,
                                             MappingData mappingData)
  -        throws Exception {
  +    throws Exception {
   
           int pathOffset = path.getOffset();
           int pathEnd = path.getEnd();
  @@ -682,10 +687,10 @@
               }
           }
   
  -        if(mappingData.wrapper == null && noServletPath) {
  +        if (mappingData.wrapper == null && noServletPath) {
               // The path is empty, redirect to "/"
               mappingData.redirectPath.setChars
  -                (path.getBuffer(), pathOffset, pathEnd);
  +            (path.getBuffer(), pathOffset, pathEnd);
               path.setEnd(pathEnd - 1);
               return;
           }
  @@ -705,7 +710,7 @@
               }
               if (checkWelcomeFiles) {
                   for (int i = 0; (i < context.welcomeResources.length)
  -                         && (mappingData.wrapper == null); i++) {
  +                    && (mappingData.wrapper == null); i++) {
                       path.setOffset(pathOffset);
                       path.setEnd(pathEnd);
                       path.append(context.welcomeResources[i], 0,
  @@ -718,8 +723,8 @@
                       // Rule 4b -- Welcome resources processing for prefix match
                       if (mappingData.wrapper == null) {
                           internalMapWildcardWrapper
  -                            (wildcardWrappers, context.nesting, 
  -                             path, mappingData);
  +                        (wildcardWrappers, context.nesting, 
  +                         path, mappingData);
                       }
   
                       // Rule 4c -- Welcome resources processing
  @@ -730,7 +735,7 @@
                           String pathStr = path.toString();
                           try {
                               file = context.resources.lookup(pathStr);
  -                        } catch(NamingException nex) {
  +                        } catch (NamingException nex) {
                               // Swallow not found, since this is normal
                           }
                           if (file != null && !(file instanceof DirContext) ) {
  @@ -739,13 +744,13 @@
                               if (mappingData.wrapper == null
                                   && context.defaultWrapper != null) {
                                   mappingData.wrapper =
  -                                    context.defaultWrapper.object;
  +                                context.defaultWrapper.object;
                                   mappingData.requestPath.setChars
  -                                    (path.getBuffer(), path.getStart(), 
  -                                     path.getLength());
  +                                (path.getBuffer(), path.getStart(), 
  +                                 path.getLength());
                                   mappingData.wrapperPath.setChars
  -                                    (path.getBuffer(), path.getStart(), 
  -                                     path.getLength());
  +                                (path.getBuffer(), path.getStart(), 
  +                                 path.getLength());
                                   mappingData.requestPath.setString(pathStr);
                                   mappingData.wrapperPath.setString(pathStr);
                               }
  @@ -756,7 +761,7 @@
                   path.setOffset(servletPath);
                   path.setEnd(pathEnd);
               }
  -                                        
  +
           }
   
   
  @@ -765,9 +770,9 @@
               if (context.defaultWrapper != null) {
                   mappingData.wrapper = context.defaultWrapper.object;
                   mappingData.requestPath.setChars
  -                    (path.getBuffer(), path.getStart(), path.getLength());
  +                (path.getBuffer(), path.getStart(), path.getLength());
                   mappingData.wrapperPath.setChars
  -                    (path.getBuffer(), path.getStart(), path.getLength());
  +                (path.getBuffer(), path.getStart(), path.getLength());
               }
               // Redirection to a folder
               char[] buf = path.getBuffer();
  @@ -776,7 +781,7 @@
                   String pathStr = path.toString();
                   try {
                       file = context.resources.lookup(pathStr);
  -                } catch(NamingException nex) {
  +                } catch (NamingException nex) {
                       // Swallow, since someone else handles the 404
                   }
                   if (file != null && file instanceof DirContext) {
  @@ -786,7 +791,7 @@
                       path.setOffset(pathOffset);
                       path.append('/');
                       mappingData.redirectPath.setChars
  -                        (path.getBuffer(), path.getStart(), path.getLength());
  +                    (path.getBuffer(), path.getStart(), path.getLength());
                   } else {
                       mappingData.requestPath.setString(pathStr);
                       mappingData.wrapperPath.setString(pathStr);
  @@ -804,7 +809,7 @@
        * Exact mapping.
        */
       private final void internalMapExactWrapper
  -        (Wrapper[] wrappers, CharChunk path, MappingData mappingData) {
  +    (Wrapper[] wrappers, CharChunk path, MappingData mappingData) {
           int pos = find(wrappers, path);
           if ((pos != -1) && (path.equals(wrappers[pos].name))) {
               mappingData.requestPath.setString(wrappers[pos].name);
  @@ -818,8 +823,8 @@
        * Wildcard mapping.
        */
       private final void internalMapWildcardWrapper
  -        (Wrapper[] wrappers, int nesting, CharChunk path, 
  -         MappingData mappingData) {
  +    (Wrapper[] wrappers, int nesting, CharChunk path, 
  +     MappingData mappingData) {
   
           int pathEnd = path.getEnd();
           int pathOffset = path.getOffset();
  @@ -853,12 +858,12 @@
                   mappingData.wrapperPath.setString(wrappers[pos].name);
                   if (path.getLength() > length) {
                       mappingData.pathInfo.setChars
  -                        (path.getBuffer(),
  -                         path.getOffset() + length,
  -                         path.getLength() - length);
  +                    (path.getBuffer(),
  +                     path.getOffset() + length,
  +                     path.getLength() - length);
                   }
                   mappingData.requestPath.setChars
  -                    (path.getBuffer(), path.getOffset(), path.getLength());
  +                (path.getBuffer(), path.getOffset(), path.getLength());
                   mappingData.wrapper = wrappers[pos].object;
                   mappingData.jspWildCard = wrappers[pos].jspWildCard;
               }
  @@ -870,7 +875,7 @@
        * Extension mappings.
        */
       private final void internalMapExtensionWrapper
  -        (Wrapper[] wrappers, CharChunk path, MappingData mappingData) {
  +    (Wrapper[] wrappers, CharChunk path, MappingData mappingData) {
           char[] buf = path.getBuffer();
           int pathEnd = path.getEnd();
           int servletPath = path.getOffset();
  @@ -896,9 +901,9 @@
                   if ((pos != -1)
                       && (path.equals(wrappers[pos].name))) {
                       mappingData.wrapperPath.setChars
  -                        (buf, servletPath, pathEnd - servletPath);
  +                    (buf, servletPath, pathEnd - servletPath);
                       mappingData.requestPath.setChars
  -                        (buf, servletPath, pathEnd - servletPath);
  +                    (buf, servletPath, pathEnd - servletPath);
                       mappingData.wrapper = wrappers[pos].object;
                   }
                   path.setOffset(servletPath);
  @@ -933,10 +938,10 @@
           if (b == -1) {
               return -1;
           }
  -        
  +
           if (compare(name, start, end, map[0].name) < 0 ) {
               return -1;
  -        }         
  +        }
           if (b == 0) {
               return 0;
           }
  @@ -980,7 +985,7 @@
        * given array.
        */
       private static final int findIgnoreCase(MapElement[] map, CharChunk name,
  -                                  int start, int end) {
  +                                            int start, int end) {
   
           int a = 0;
           int b = map.length - 1;
  @@ -991,7 +996,7 @@
           }
           if (compareIgnoreCase(name, start, end, map[0].name) < 0 ) {
               return -1;
  -        }         
  +        }
           if (b == 0) {
               return 0;
           }
  @@ -1034,10 +1039,10 @@
           if (b == -1) {
               return -1;
           }
  -        
  +
           if (name.compareTo(map[0].name) < 0) {
               return -1;
  -        } 
  +        }
           if (b == 0) {
               return 0;
           }
  @@ -1074,7 +1079,8 @@
                                        String compareTo) {
           int result = 0;
           char[] c = name.getBuffer();
  -        int len = compareTo.length();
  +        final int compareLen=compareTo.length();
  +        int len = compareLen;
           if ((end - start) < len) {
               len = end - start;
           }
  @@ -1086,9 +1092,9 @@
               }
           }
           if (result == 0) {
  -            if (compareTo.length() > (end - start)) {
  +            if (compareLen > (end - start)) {
                   result = -1;
  -            } else if (compareTo.length() < (end - start)) {
  +            } else if (compareLen < (end - start)) {
                   result = 1;
               }
           }
  @@ -1101,10 +1107,11 @@
        * Return -1, 0 or +1 if inferior, equal, or superior to the String.
        */
       private static final int compareIgnoreCase(CharChunk name, int start, int end,
  -                                     String compareTo) {
  +                                               String compareTo) {
           int result = 0;
           char[] c = name.getBuffer();
  -        int len = compareTo.length();
  +        final int compareLen=compareTo.length();
  +        int len = compareLen;
           if ((end - start) < len) {
               len = end - start;
           }
  @@ -1116,9 +1123,9 @@
               }
           }
           if (result == 0) {
  -            if (compareTo.length() > (end - start)) {
  +            if (compareLen > (end - start)) {
                   result = -1;
  -            } else if (compareTo.length() < (end - start)) {
  +            } else if (compareLen < (end - start)) {
                   result = 1;
               }
           }
  @@ -1142,7 +1149,7 @@
               }
           }
   
  -        return (pos);
  +        return(pos);
   
       }
   
  @@ -1165,7 +1172,7 @@
               }
           }
   
  -        return (pos);
  +        return(pos);
   
       }
   
  @@ -1188,7 +1195,7 @@
        * duplicates.
        */
       private static final boolean insertMap
  -        (MapElement[] oldMap, MapElement[] newMap, MapElement newElement) {
  +    (MapElement[] oldMap, MapElement[] newMap, MapElement newElement) {
           int pos = find(oldMap, newElement.name);
           if ((pos != -1) && (newElement.name.equals(oldMap[pos].name))) {
               return false;
  @@ -1196,7 +1203,7 @@
           System.arraycopy(oldMap, 0, newMap, 0, pos + 1);
           newMap[pos + 1] = newElement;
           System.arraycopy
  -            (oldMap, pos + 1, newMap, pos + 2, oldMap.length - pos - 1);
  +        (oldMap, pos + 1, newMap, pos + 2, oldMap.length - pos - 1);
           return true;
       }
   
  @@ -1205,7 +1212,7 @@
        * Insert into the right place in a sorted MapElement array.
        */
       private static final boolean removeMap
  -        (MapElement[] oldMap, MapElement[] newMap, String name) {
  +    (MapElement[] oldMap, MapElement[] newMap, String name) {
           int pos = find(oldMap, name);
           if ((pos != -1) && (name.equals(oldMap[pos].name))) {
               System.arraycopy(oldMap, 0, newMap, 0, pos);
  @@ -1232,9 +1239,32 @@
   
   
       protected static final class Host
  -        extends MapElement {
  +    extends MapElement implements Comparable {
   
           public ContextList contextList = null;
  +        public int hash;
  +        /** 
  +         * Limiter for host alias matching to prevent DOS. The default
  +         * of 0, disables alias matching.
  +         */
  +        public int aliasMatchesRemaining=0;
  +
  +        public int compareTo(Object o){
  +            int iResult=0;
  +            if (o==null) {
  +                iResult=1;
  +            } else {
  +                Host oCompare=(Host)o;
  +                if (this.hash>oCompare.hash) {
  +                    iResult=1;
  +                } else if (this.hash<oCompare.hash) {
  +                    iResult=-1;
  +                } else {
  +                    // iResult is already 0
  +                }
  +            }
  +            return iResult;
  +        }
   
       }
   
  @@ -1254,7 +1284,7 @@
   
   
       protected static final class Context
  -        extends MapElement {
  +    extends MapElement {
   
           public String path = null;
           public String[] welcomeResources = new String[0];
  @@ -1272,7 +1302,7 @@
   
   
       protected static class Wrapper
  -        extends MapElement {
  +    extends MapElement {
   
           public String path = null;
           public boolean jspWildCard = false;
  @@ -1282,112 +1312,280 @@
       // -------------------------------------------------------- Testing Methods
   
       // FIXME: Externalize this
  -    /*
  +
       public static void main(String args[]) {
   
           try {
   
  -        Mapper mapper = new Mapper();
  -        System.out.println("Start");
  +            Mapper mapper = new Mapper();
  +            System.out.println("Start");
   
  -        mapper.addHost("sjbjdvwsbvhrb", new String[0], "blah1");
  -        mapper.addHost("sjbjdvwsbvhr/", new String[0], "blah1");
  -        mapper.addHost("wekhfewuifweuibf", new String[0], "blah2");
  -        mapper.addHost("ylwrehirkuewh", new String[0], "blah3");
  -        mapper.addHost("iohgeoihro", new String[0], "blah4");
  -        mapper.addHost("fwehoihoihwfeo", new String[0], "blah5");
  -        mapper.addHost("owefojiwefoi", new String[0], "blah6");
  -        mapper.addHost("iowejoiejfoiew", new String[0], "blah7");
  -        mapper.addHost("iowejoiejfoiew", new String[0], "blah17");
  -        mapper.addHost("ohewoihfewoih", new String[0], "blah8");
  -        mapper.addHost("fewohfoweoih", new String[0], "blah9");
  -        mapper.addHost("ttthtiuhwoih", new String[0], "blah10");
  -        mapper.addHost("lkwefjwojweffewoih", new String[0], "blah11");
  -        mapper.addHost("zzzuyopjvewpovewjhfewoih", new String[0], "blah12");
  -        mapper.addHost("xxxxgqwiwoih", new String[0], "blah13");
  -        mapper.addHost("qwigqwiwoih", new String[0], "blah14");
  -
  -        System.out.println("Map:");
  -        for (int i = 0; i < mapper.hosts.length; i++) {
  -            System.out.println(mapper.hosts[i].name);
  -        }
  -
  -        mapper.setDefaultHostName("ylwrehirkuewh");
  -
  -        String[] welcomes = new String[2];
  -        welcomes[0] = "boo/baba";
  -        welcomes[1] = "bobou";
  -
  -        mapper.addContext("iowejoiejfoiew", "", "context0", new String[0], null);
  -        mapper.addContext("iowejoiejfoiew", "/foo", "context1", new String[0], null);
  -        mapper.addContext("iowejoiejfoiew", "/foo/bar", "context2", welcomes, null);
  -        mapper.addContext("iowejoiejfoiew", "/foo/bar/bla", "context3", new String[0], null);
  -
  -        mapper.addWrapper("iowejoiejfoiew", "/foo/bar", "/fo/*", "wrapper0");
  -        mapper.addWrapper("iowejoiejfoiew", "/foo/bar", "/", "wrapper1");
  -        mapper.addWrapper("iowejoiejfoiew", "/foo/bar", "/blh", "wrapper2");
  -        mapper.addWrapper("iowejoiejfoiew", "/foo/bar", "*.jsp", "wrapper3");
  -        mapper.addWrapper("iowejoiejfoiew", "/foo/bar", "/blah/bou/*", "wrapper4");
  -        mapper.addWrapper("iowejoiejfoiew", "/foo/bar", "/blah/bobou/*", "wrapper5");
  -        mapper.addWrapper("iowejoiejfoiew", "/foo/bar", "*.htm", "wrapper6");
  -
  -        MappingData mappingData = new MappingData();
  -        MessageBytes host = MessageBytes.newInstance();
  -        host.setString("iowejoiejfoiew");
  -        MessageBytes uri = MessageBytes.newInstance();
  -        uri.setString("/foo/bar/blah/bobou/foo");
  -        uri.toChars();
  -        uri.getCharChunk().setLimit(-1);
  +            final int TEST_HOST=3;
   
  -        mapper.map(host, uri, mappingData);
  -        System.out.println("MD Host:" + mappingData.host);
  -        System.out.println("MD Context:" + mappingData.context);
  -        System.out.println("MD Wrapper:" + mappingData.wrapper);
  -
  -        System.out.println("contextPath:" + mappingData.contextPath);
  -        System.out.println("wrapperPath:" + mappingData.wrapperPath);
  -        System.out.println("pathInfo:" + mappingData.pathInfo);
  -        System.out.println("redirectPath:" + mappingData.redirectPath);
  -
  -        mappingData.recycle();
  -        mapper.map(host, uri, mappingData);
  -        System.out.println("MD Host:" + mappingData.host);
  -        System.out.println("MD Context:" + mappingData.context);
  -        System.out.println("MD Wrapper:" + mappingData.wrapper);
  -
  -        System.out.println("contextPath:" + mappingData.contextPath);
  -        System.out.println("wrapperPath:" + mappingData.wrapperPath);
  -        System.out.println("pathInfo:" + mappingData.pathInfo);
  -        System.out.println("redirectPath:" + mappingData.redirectPath);
  +            String[][][] testHosts={
  +                {{"fewohfoweoih"},new String[0], {"blah9"}},
  +                {{"fwehoihoihwfeo"},new String[0], {"blah5"}},
  +                {{"iohgeoihro"},new String[0], {"blah4"}},
  +                {{"iowejoiejfoiew"},{"testalias","*.testdomain.com"}, {"blah7"}},
  +                {{"iowejoiejfoiew"},new String[0], {"blah17"}},
  +                {{"lkwefjwojweffewoih"},new String[0], {"blah11"}},
  +                {{"ohewoihfewoih"},new String[0], {"blah8"}},
  +                {{"owefojiwefoi"},new String[0], {"blah6"}},
  +                {{"qwigqwiwoih"},new String[0], {"blah14"}},
  +                {{"sjbjdvwsbvhr/"},new String[0], {"blah1"}},
  +                {{"sjbjdvwsbvhrb"},new String[0], {"blah1"}},
  +                {{"ttthtiuhwoih"},new String[0], {"blah10"}},
  +                {{"wekhfewuifweuibf"},new String[0], {"blah2"}},
  +                {{"xxxxgqwiwoih"},new String[0], {"blah13"}},
  +                {{"ylwrehirkuewh"},new String[0], {"blah3"}},
  +                {{"zzzuyopjvewpovewjhfewoih"},new String[0], {"blah12"}}
  +            };
  +
  +            for (int i=0; i < testHosts.length; i++) {
  +                mapper.addHost(testHosts[i][0][0],testHosts[i][1],testHosts[i][2][0]);
  +            }
  +
  +            System.out.println("Map:");
  +            String[] hNames=mapper.getHosts();
  +
  +            if (hNames.length!=(testHosts.length+1)) {
  +                // One of the entries was a duplicate, but it also has
  +                // two aliases, so the expected
  +                // count of hosts is +1
  +                System.out.println("***************** FAIL ********** hostCount="+hNames.length+" Expected="+(testHosts.length+1));
  +            }
  +
  +            for (int i=0; i < hNames.length; i++ ) {
  +                System.out.println(hNames[i]);
  +                if (!mapper.hostMap.contains(hNames[i])) {
  +                    System.out.println("BIG FAILURE!!!!! Host - "+hNames[i]+" doesnt appear in the hostMap!");
  +                }
  +            }
  +
  +            for (int i=0; i < testHosts.length; i++) {
  +                if (!mapper.hostMap.contains(testHosts[i][0][0])) {
  +                    System.out.println("BIG FAILURE!!!!! HostMapper doesnt appear to contain "+testHosts[i][0][0]+" in the hostMap!");
  +                }
  +            }
  +
  +            final String sDefault=testHosts[testHosts.length-2][0][0];
  +            mapper.setDefaultHostName(sDefault);
  +            if (!sDefault.equals(mapper.getDefaultHostName())) {
  +                System.out.println("***************** FAIL ********** getDefaultHostName() returned incorrect value");
  +            }
  +
  +            String[] welcomes = new String[2];
  +            welcomes[0] = "boo/baba";
  +            welcomes[1] = "bobou";
  +
  +
  +            /*
  +            Columns are
  +
  +            0   host name
  +            1   context path
  +            2   Context Name
  +            3   Welcome File List
  +            */
  +            final int CONTEXT_NAME_COL=2;
  +            final int CONTEXT_PATH_COL=1;
  +            String[][][] contextTestMap={
  +                {{testHosts[TEST_HOST][0][0]}, {""}, {"context0"}, new String[0]},
  +                {{testHosts[TEST_HOST][0][0]}, {"/foo"}, {"context1"}, new String[0]},
  +                {{testHosts[TEST_HOST][0][0]}, {"/foo/bar"}, {"context2"}, welcomes},
  +                {{testHosts[TEST_HOST][0][0]}, {"/foo/bar/ble"}, {"context3"}, new String[0]}
  +            };
  +
  +            for (int i=0; i < contextTestMap.length; i++) {
  +                mapper.addContext(contextTestMap[i][0][0],
  +                                  contextTestMap[i][1][0],
  +                                  contextTestMap[i][2][0],
  +                                  contextTestMap[i][3],
  +                                  null);
  +            }
  +
  +            /*
  +            Columns are
  +
  +                0   java.lang.Integer   Mapping into ContextTestMap
  +                1   java.lang.String    URL Mapping
  +                2   java.lang.String    Wrapper ID
  +                3   java.lang.String    Test URL
  +            */
  +
  +            final int TEST_URI_COL=3;
  +            final int WRAPPER_NAME_COL=2;
  +            final int WRAPPER_PATH_COL=1;
  +            Object[][] testWrappers={
  +                {new Integer(0),"","wrapper99","/index.html"},      
  +                {new Integer(2),"/fo/*","wrapper0","/foo/bar/fo/xxx.html"},
  +                {new Integer(2),"/fuzz/*","wrapper1","/foo/bar/fuzz/test.pdf"},
  +                {new Integer(2),"/blh","wrapper2","/foo/bar/blh"},
  +                {new Integer(2),"*.jsp","wrapper3","/foo/bar/baz.jsp"},
  +                {new Integer(2),"/blah/bou/*","wrapper4","/foo/bar/blah/bou/blech.html"},
  +                {new Integer(2),"/bla/blah/bou/*","wrapper4a","/foo/bar/bla/blah/bou/blech.html"},
  +                {new Integer(2),"/blah/bobou/*","wrapper5","/foo/bar/blah/bobou/banana.html"},
  +                {new Integer(2),"*.html","wrapper6","/foo/bar/farley.html"}
  +
  +            };
  +            for (int i=0; i < testWrappers.length; i++) {
  +                mapper.addWrapper(
  +                                 contextTestMap[((Integer)testWrappers[i][0]).intValue()][0][0],   // Server
  +                                 contextTestMap[((Integer)testWrappers[i][0]).intValue()][1][0],   // Context,
  +                                 (String)testWrappers[i][1],
  +                                 (String)testWrappers[i][2]
  +                                 );
  +            }
  +            String[] sHost=null;
  +            MappingData mappingData=new MappingData();
  +            MessageBytes uri=null ,host=null;
  +
  +            for (int iOuter=0; iOuter < 2; iOuter++) {
  +                if (iOuter==0) {
  +                    // First Pass is against the test host
  +                    sHost=testHosts[TEST_HOST][0];
  +                } else {
  +                    // 2nd pass is against an alias
  +                    sHost=testHosts[TEST_HOST][1];
  +                }
  +                host = MessageBytes.newInstance();
  +                host.setString(sHost[0]);
   
  -        for (int i = 0; i < 1000000; i++) {
  -            mappingData.recycle();
  -            mapper.map(host, uri, mappingData);
  -        }
  +                for (int iInner=0; iInner < testWrappers.length; iInner++) {
  +
  +                    uri = MessageBytes.newInstance();
  +
  +                    uri.setString((String)testWrappers[iInner][TEST_URI_COL]);
  +                    uri.toChars();
  +                    uri.getCharChunk().setLimit(-1);
  +
  +                    mapper.map(host, uri, mappingData);
  +                    //  OK, now let's check that the mapper worked.
  +                    System.out.println("Host = "+sHost[0]+" URI="+uri.toString());
  +                    System.out.println("MD Host:" + mappingData.host);
  +                    System.out.println("MD Context:" + mappingData.context);
  +                    System.out.println("MD Wrapper:" + mappingData.wrapper);
  +
  +                    System.out.println("contextPath:" + mappingData.contextPath);
  +                    System.out.println("wrapperPath:" + mappingData.wrapperPath);
  +                    System.out.println("pathInfo:" + mappingData.pathInfo);
  +                    System.out.println("redirectPath:" + mappingData.redirectPath);
  +
  +                    // Check the host name - Aliases will come back with the parent host
  +                    // name.
  +                    if (!testHosts[TEST_HOST][2][0].equals(mappingData.host)) {
  +                        System.out.println("******* FAIL host.name="+mappingData.host +" Expected="+testHosts[TEST_HOST][2][0]);
  +                    }
  +
  +                    // Check the context
  +                    if (mappingData.context!=null) {
  +                        if (!mappingData.context.equals(
  +                                                       contextTestMap[((Integer)testWrappers[iInner][0]).intValue()][CONTEXT_NAME_COL][0]
  +                                                       )
  +                           ) {
  +                        }
  +                    }
  +
  +                    if (mappingData.wrapper!=null) {
  +                        if (!mappingData.wrapper.equals(testWrappers[iInner][2])
  +                           ) {
  +                            System.out.println(" Wrappers not equal as expected - mappingData.wrapper="+mappingData.wrapper+" expected="+
  +                                               testWrappers[iInner][2]);
  +                        }
  +                    }
  +
  +                    if (mappingData.contextPath!=null) {
  +                        if (!contextTestMap[((Integer)testWrappers[iInner][0]).intValue()][CONTEXT_PATH_COL][0].equals(mappingData.contextPath.toString()
  +
  +                                                                                                                      )) {
  +                            System.out.println(" Context Path not as expected - mappingData.contextPath="+mappingData.contextPath.toString()+" expected="+
  +                                               contextTestMap[((Integer)testWrappers[iInner][0]).intValue()][CONTEXT_PATH_COL][0]);
  +                        }
  +                    }
  +
  +                    if (mappingData.wrapperPath.toString()!=null) {
  +                        if (!((String)testWrappers[iInner][WRAPPER_PATH_COL]).startsWith(mappingData.wrapperPath.toString())
  +                            && 
  +                            !((String)testWrappers[iInner][WRAPPER_PATH_COL]).startsWith("*")
  +                           ) {
  +                            System.out.println("Wrapper Path="+mappingData.wrapperPath + "  Expected="+testWrappers[iInner][WRAPPER_PATH_COL]);
  +                        }
  +                    }
  +
  +                    if (mappingData.pathInfo.toString()!=null) {
  +                        if (!
  +                            ((String)testWrappers[iInner][TEST_URI_COL]).endsWith(mappingData.pathInfo.toString())
  +                           ) {
  +                            System.out.println(" Mismatch between pathInfo ("+mappingData.pathInfo+" and Test URI ("+
  +                                               testWrappers[iInner][TEST_URI_COL]);
  +                        }
  +                    }
  +
  +                    // TODO: RedirectPath                           redirectPath:null
  +
  +                    mappingData.recycle();
  +
  +                }
  +            }
  +
  +            host = MessageBytes.newInstance();
  +            host.setString(testHosts[TEST_HOST][0][0]);
  +
  +            uri=MessageBytes.newInstance();
  +            uri.setString((String)testWrappers[6][TEST_URI_COL]);
  +            uri.toChars();
  +            uri.getCharChunk().setLimit(-1);
  +
  +
  +            for (int i = 0; i < 1000000; i++) {
  +                mappingData.recycle();
  +                mapper.map(host, uri, mappingData);
  +            }
  +
  +            long time = System.currentTimeMillis();
  +            for (int i = 0; i < 1000000; i++) {
  +                mappingData.recycle();
  +                mapper.map(host, uri, mappingData);
  +            }
  +
  +            System.out.println("Elapsed:" + (System.currentTimeMillis() - time));
  +            System.out.println("Host = "+host.toString()+" URI="+uri.toString());
  +            System.out.println("MD Host:" + mappingData.host);
  +            System.out.println("MD Context:" + mappingData.context);
  +            System.out.println("MD Wrapper:" + mappingData.wrapper);
  +
  +            System.out.println("contextPath:" + mappingData.contextPath);
  +            System.out.println("wrapperPath:" + mappingData.wrapperPath);
  +            System.out.println("pathInfo:" + mappingData.pathInfo);
  +            System.out.println("redirectPath:" + mappingData.redirectPath);
  +
  +            System.out.println("Testing virtual host name.");
  +
  +            host = MessageBytes.newInstance();
  +            host.setString("host99.testdomain.com");
  +
  +            uri=MessageBytes.newInstance();
  +            uri.setString((String)testWrappers[6][TEST_URI_COL]);
  +            uri.toChars();
  +            uri.getCharChunk().setLimit(-1);
  +
  +            System.out.println("Host = "+host.toString()+" URI="+uri.toString());
   
  -        long time = System.currentTimeMillis();
  -        for (int i = 0; i < 1000000; i++) {
               mappingData.recycle();
               mapper.map(host, uri, mappingData);
  -        }
  -        System.out.println("Elapsed:" + (System.currentTimeMillis() - time));
   
  -        System.out.println("MD Host:" + mappingData.host);
  -        System.out.println("MD Context:" + mappingData.context);
  -        System.out.println("MD Wrapper:" + mappingData.wrapper);
  -
  -        System.out.println("contextPath:" + mappingData.contextPath);
  -        System.out.println("wrapperPath:" + mappingData.wrapperPath);
  -        System.out.println("requestPath:" + mappingData.requestPath);
  -        System.out.println("pathInfo:" + mappingData.pathInfo);
  -        System.out.println("redirectPath:" + mappingData.redirectPath);
  +            System.out.println("MD Host:" + mappingData.host);
  +            System.out.println("MD Context:" + mappingData.context);
  +            System.out.println("MD Wrapper:" + mappingData.wrapper);
  +
  +            System.out.println("contextPath:" + mappingData.contextPath);
  +            System.out.println("wrapperPath:" + mappingData.wrapperPath);
  +            System.out.println("pathInfo:" + mappingData.pathInfo);
  +            System.out.println("redirectPath:" + mappingData.redirectPath);
   
           } catch (Exception e) {
               e.printStackTrace();
           }
   
       }
  -    */
  -
  -
   }
  
  
  
  1.1                  jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/http/mapper/HostMap.java
  
  Index: HostMap.java
  ===================================================================
  /*
   *  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.http.mapper;
  
  import java.util.Arrays;
  
  import org.apache.tomcat.util.http.mapper.Mapper.Host;
  import org.apache.tomcat.util.buf.CharChunk;
  
  /**
   * Map set for a collection of hosts.
   * 
   * @author George Sexton
   * @author Peter Rossbach
   */
  class HostMap {
  
      private Host[] hosts=new Host[0];
      private boolean enableWildCardMatching=false;
  
      public HostMap(){
      }
  
      /**
       * Copy an existing HostMap into a new one.
       */
      public HostMap(HostMap hmCurrent){
          hosts=hmCurrent.toHostArray();
          setEnableWildCardMatching(hmCurrent.getEnableWildCardMatching());
      }
  
      /**
       * Enable that host wildcards are match 
       * @param value
       */
      public void setEnableWildCardMatching(final boolean value){
          enableWildCardMatching=value;
      }
      
      public boolean getEnableWildCardMatching(){
          return enableWildCardMatching;
      }
  
      /**
       * Return the names of all mapped hosts as a string array.
       */
      public String[] getHosts(){
          Host[] h=hosts;
          String[] result=new String[h.length];
          for (int i=0; i < h.length; i++) {
              result[i]=h[i].name;
          }
          Arrays.sort(result);
          return result;
      }
  
      /**
       * return a count of mapped hosts.
       */
      public int getCount(){
          return hosts.length;
      }
  
      /**
       * Return the set of hosts this map contains as an array.
       */
      public Host[] toHostArray(){
          Host[] hCurrent=hosts;
          Host[] hResult=new Host[hCurrent.length];
          System.arraycopy(hCurrent,0,hResult,0,hCurrent.length);
          return hResult;
      }
  
      /**
       * Add a new host to the map.
       * 
       * @param h The new Host object to add.
       */
      public void addHost(Host h){
          CharChunk cc=new CharChunk();
          cc.setChars(h.name.toLowerCase().toCharArray(),0,h.name.length());
          h.hash=cc.hash();
          Host[] hosts=this.hosts;
          Host[] newHosts=new Host[hosts.length+1];
          System.arraycopy(hosts,0,newHosts,1,hosts.length);
          newHosts[0]=h;
          Arrays.sort(newHosts);
          this.hosts=newHosts;
      }
  
      /**
       * Remove a specified host (an all aliases).
       * @param name The name of the host to remove.
       */
      public void removeHost(String name){
          Host hFound=getHost(name);
          if (hFound!=null) {
              int iCurrent=0;
              Host[] hostsNew=new Host[hosts.length];
              for (int i=0; i < hosts.length; i++) {
                  if (hFound.object!=hosts[i].object) {
                      hostsNew[iCurrent++]=hosts[i];
                  }
              }
              Host[] hTemp=new Host[iCurrent];
              if (iCurrent>0) {
                  System.arraycopy(hostsNew,0,hTemp,0,iCurrent);
              }
              hosts=hTemp;
          }
      }
  
      /**
       * Return true if the specified host is contained
       * in the map.
       * 
       * @param hostName the host name to test.
       */
      public boolean contains(String hostName){
          return getHost(hostName)!=null;
      }
  
      /**
       * Return a host mapping record. 
       * @param hostName the name of the host to return.
       * @see getHost(CharChunk)
       * 
       */
      public Host getHost(String hostName){
          CharChunk cc=new CharChunk();
          char[] c=hostName.toCharArray();
          cc.setChars(c,0,c.length);
          return getHost(cc);
      }
  
      /**
       * Binary search algorithm used internally to quickly find
       * a host.
       */
      private static int findPos(Host[] hosts, final int iHash){
  
          int lo=0,hi=hosts.length-1,mid;
          while (lo<=hi) {
              mid=(lo+hi)/2;
              if (iHash==hosts[mid].hash) {
                  return mid;
              } else if (hosts[mid].hash>iHash) {
                  hi=mid-1;
              } else {
                  lo=mid+1;
              }
          }
          return -1;
      }
  
      /**
       * Find a specific host in the map.
       * 
       * This variant uses a CharChunk which the
       * Mapper uses internally for processing.
       * <BR><BR>
       * If a match is not found, and wild card matching is enabled, 
       * the function will attempt to find a wild-card match. I.E. 
       * a host record (possibly an alias) of *.domain.unit If a 
       * wild-card record is found, and the Host record 
       * hostMatchesRemaining property is non-zero,
       * then <B>hostName</B> will automatically be added to the map
       * using the hostRecord that was found.
       * 
       * @param hostName the (case insensitive)
       * name of the host to return.
       */
      public Host getHost(CharChunk hostName){
          Host[] h=hosts;
          final int iHash=hostName.hashIgnoreCase();
          int iPos=findPos(h,iHash);
          if (iPos>=0) {
              while (iPos>0 && hosts[iPos-1].hash==iHash) {
                  iPos--;
              }
              while (hosts[iPos].hash==iHash) {
                  if (hostName.equalsIgnoreCase(h[iPos].name)) {
                      return h[iPos];
                  }
                  iPos++;
              }
          }
          Host hResult=null;
          if (enableWildCardMatching) {
  
              /*
              Go over the host list, and look for wild card entries
              and if we find a wild-card entry that matches add it
              to the host map.
      
              Because this code adds the found host name to the
              host array, this lookup is only done once per 
              unresolved host name.
      
              The only area this may cause problems is where you
              are using the DefaultHost property to map lots of
              hosts. Since the code only looks at the first character
              of each mapped host, this should still be pretty 
              efficient. This minor inefficiency is probably more
              than made up by the caching of the default host object
              that I added above.
      
              */
              Host hFound=null;
              String sName=hostName.toString().toLowerCase();
              for (int i=0; i < hosts.length; i++) {
                  if (hosts[i].name.charAt(0)=='*') {
                      if (sName.endsWith(hosts[i].name.substring(1).toLowerCase())) {
                          // This is a match.
                          hFound=hosts[i];
                          break;
                      }
                  }
              }
              if (hFound!=null && (hFound.aliasMatchesRemaining>0)) {
                  //
                  //  We got a hit on the wild card. Copy the entry and
                  //  add the found name into the Host table as another
                  //  alias.
                  //
                  hFound.aliasMatchesRemaining--;
  
                  hResult=new Host();
                  hResult.name=sName;
                  hResult.contextList=hFound.contextList;
                  hResult.object=hFound.object;
                  addHost(hResult);
              }
          }
          return hResult;
  
      }
  
  }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-dev-help@jakarta.apache.org


Mime
View raw message