I have been looking into the Servlet 2.4 section 9.10 Welcome files
stuff.  In a nutshell, the spec now allows servlets to be welcome
files.  The can either be an 'exact match' or a 'prefix match.'

I implemented changes to StandardContextWrapper to bring Tomcat into
compliance.  I think it is pretty messy, but then again Welcome Files
are messy (per earlier posts.)

What do you think?   (The patch is for discussion purposes and contains
a lot of logging)

Cheers,
-bob



Index: core/StandardContextMapper.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/core/StandardContextMapper.java,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 StandardContextMapper.java
--- core/StandardContextMapper.java	18 Jul 2002 16:48:11 -0000	1.1.1.1
+++ core/StandardContextMapper.java	21 Aug 2002 22:45:02 -0000
@@ -65,15 +65,20 @@
 package org.apache.catalina.core;
 
 
+import javax.naming.directory.DirContext;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
 import javax.servlet.http.HttpServletRequest;
 import org.apache.catalina.Container;
 import org.apache.catalina.Context;
+import org.apache.catalina.Globals;
 import org.apache.catalina.HttpRequest;
 import org.apache.catalina.Mapper;
 import org.apache.catalina.Request;
 import org.apache.catalina.Wrapper;
 import org.apache.catalina.util.RequestUtil;
 import org.apache.catalina.util.StringManager;
+import org.apache.naming.resources.Resource;
 
 
 /**
@@ -272,6 +277,15 @@
             if (wrapper != null) {
                 servletPath = relativeURI;
                 pathInfo = null;
+		
+                if ( relativeURI.endsWith("/") ) {
+                    WelcomeURIProcessing wfp = new WelcomeURIProcessing( relativeURI );
+                    if ( wfp.mapsToServlet ){
+                        wrapper = wfp.wrapper;
+                        servletPath = wfp.servletPath;
+                        pathInfo = wfp.pathInfo;
+                    }
+                }
             }
         }
 
@@ -290,5 +304,126 @@
 
     }
 
+
+    // -------------------------------------------------------- Private Methods
+
+
+    /**
+     * This helper class is used as part of an attempt to satisfy
+     * Servlet 2.4 spec, section 9.10.  Section 9.10 now allows a
+     * welcome file to map to a servlet
+     **/
+    private class WelcomeURIProcessing {
+        boolean mapsToServlet = false;
+
+        Wrapper wrapper = null;
+        String  servletPath = null;
+        String  pathInfo = null;
+
+        WelcomeURIProcessing (String relativeURI ) {
+            mapsToServlet = search(relativeURI);
+        }
+
+        boolean search(String relativeURI) {
+            DirContext resources = getResources();
+
+            String[] welcomes = context.findWelcomeFiles();
+
+            for(int i=0;i<welcomes.length;i++){
+                String newRelativeURI = relativeURI+welcomes[i];
+                context.log( "##### search() checking "+newRelativeURI);
+
+                try {
+                    Object obj =  resources.lookup(newRelativeURI);
+                    if ( obj != null && obj instanceof Resource ){
+                        context.log( "##### search() resource present "+newRelativeURI);
+                        return false;
+                    }
+                } catch (NamingException e){
+                    // These happen everytime a resource is not found, which is like very often.
+                }
+
+                // exact match
+                context.log( "##### search() exact match "+newRelativeURI);
+                String name = context.findServletMapping(newRelativeURI);
+                if ( name != null){
+                    // set wrapper...
+                    wrapper = (Wrapper) context.findChild(name);
+                    if ( wrapper != null ){
+                        servletPath = newRelativeURI;
+                        pathInfo = null;
+                        context.log( "##### search() exact match to servlet: "+name+" fromURI "+newRelativeURI);
+                        return true;
+                    }
+                }
+
+                // prefix match
+                servletPath = newRelativeURI;
+                while (true) {
+                    context.log( "##### search() prefix match trying: "+servletPath + "/*");
+                    name = context.findServletMapping(servletPath + "/*");
+                    if (name != null) {
+                        wrapper = (Wrapper) context.findChild(name);
+                    }
+                    if (wrapper != null) {
+                        pathInfo = newRelativeURI.substring(servletPath.length());
+                        if (pathInfo.length() == 0)
+                            pathInfo = null;
+                        servletPath = newRelativeURI;
+                        context.log( "##### search() prefix match to servlet: "+name+" fromURI "+newRelativeURI);
+                        return true;
+                    }
+                    int slash = servletPath.lastIndexOf('/');
+                    if (slash < 0)
+                        break;
+                    servletPath = servletPath.substring(0, slash);
+                }
+
+            }
+            context.log( "##### search() no matches found." );
+            return false;
+        }
+
+        /**
+         * JNDI resources name.
+         */
+        protected static final String RESOURCES_JNDI_NAME = "java:/comp/Resources";
+
+        /**
+         * Get resources. This method will try to retrieve the resources through
+         * JNDI first, then in the servlet context if JNDI has failed (it could be
+         * disabled). It will return null.
+         *
+         * @return A JNDI DirContext, or null.
+         */
+        protected DirContext getResources() {
+
+            DirContext result = null;
+
+            // Try the servlet context
+            try {
+                result = (DirContext) context.getServletContext()
+                    .getAttribute(Globals.RESOURCES_ATTR);
+            } catch (ClassCastException e) {
+                // Failed : Not the right type
+            }
+
+            if (result != null)
+                return result;
+
+            // Try JNDI
+            try {
+                result =
+                    (DirContext) new InitialContext().lookup(RESOURCES_JNDI_NAME);
+            } catch (NamingException e) {
+                // Failed
+            } catch (ClassCastException e) {
+                // Failed : Not the right type
+            }
+
+            return result;
+
+        }
+    }
 
 }

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

Reply via email to