Bug 49914 - Filter on url-pattern of "/" is not invoked
Filter on url-pattern of "/" is not invoked
Status: RESOLVED WONTFIX
Product: Tomcat 7
Classification: Unclassified
Component: Catalina
7.0.2
PC Windows XP
: P2 normal (vote)
: ---
Assigned To: Tomcat Developers Mailing List
:
Depends on:
Blocks:
  Show dependency tree
 
Reported: 2010-09-10 14:30 UTC by balusc
Modified: 2010-09-21 09:40 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description balusc 2010-09-10 14:30:59 UTC
A filter on an url-pattern of "/" is not invoked when requesting the context root URL like http://localhost:8080/contextname/. This is regardless where the url-pattern is definied. In web.xml as <url-pattern>/</url-pattern> or in filter class as @WebFilter(urlPatterns={"/"})

This works fine on Tomcat 6.x and Glassfish v3.0.1.
Comment 1 Martin Gainty 2010-09-12 09:03:17 UTC
  /* same as TC 6 up until checkUnusualURLPattern  */
    /**
     * Validate the syntax of a proposed <code>&lt;url-pattern&gt;</code>
     * for conformance with specification requirements.
     *
     * @param urlPattern URL pattern to be validated
     */
    private boolean validateURLPattern(String urlPattern) {
        if (urlPattern == null)
            return (false);
        if (urlPattern.indexOf('\n') >= 0 || urlPattern.indexOf('\r') >= 0) {
            return (false);
        }
        if (urlPattern.startsWith("*.")) {
            if (urlPattern.indexOf('/') < 0) {
                checkUnusualURLPattern(urlPattern);
                return (true);
            } else
                return (false);
        }
        if ( (urlPattern.startsWith("/")) &&
                (urlPattern.indexOf("*.") < 0)) {
            checkUnusualURLPattern(urlPattern);
            return (true);
        } else
            return (false);
    }

    /**
     * Check for unusual but valid <code>&lt;url-pattern&gt;</code>s.
     * See Bugzilla 34805, 43079 & 43080
     */
    private void checkUnusualURLPattern(String urlPattern) {
        if (log.isInfoEnabled()) {
            if(urlPattern.endsWith("*") && (urlPattern.length() < 2 ||
                    urlPattern.charAt(urlPattern.length()-2) != '/')) {
                log.info("Suspicious url pattern: \"" + urlPattern + "\"" +
                        " in context [" + getName() + "] - see" +
                        " section SRV.11.2 of the Servlet specification" );
            }
        }
    }

/*TESTCASE: if the url-pattern is / then urlPattern.length() =1 and the
  urlPattern.charAt(urlPattern.length()-2) is urlPattern.charAt(-1)
  would throw NPE
  fix would be to have checkUnusualURLPattern throw NPE as here */
    private boolean validateURLPattern(String urlPattern) {
        if (urlPattern == null)
            return (false);
        if (urlPattern.indexOf('\n') >= 0 || urlPattern.indexOf('\r') >= 0) {
            return (false);
        }
        if (urlPattern.startsWith("*.")) {
            if (urlPattern.indexOf('/') < 0) {
                checkUnusualURLPattern(urlPattern);
                return (true);
            } else
                return (false);
        }
        if ( (urlPattern.startsWith("/")) &&
                (urlPattern.indexOf("*.") < 0)) 
        {
          try
          {
            checkUnusualURLPattern(urlPattern);
          }
          catch(NullPointerException npe)
          {
           System.err.println("checkUnusualURLPattern has thrown NPE for urlPattern="+urlPattern+" message="+npe.getMessage());
          }
          return (true);
        } else
            return (false);
    }
/*change checkUnusualURLPattern method to throw NPE */
    private void checkUnusualURLPattern(String urlPattern) throws NullPointerException {
        if (log.isInfoEnabled()) 
        {
         try
         {
            if(urlPattern.endsWith("*") && (urlPattern.length() < 2 ||
                    urlPattern.charAt(urlPattern.length()-2) != '/')) 
            {
                log.info("Suspicious url pattern: \"" + urlPattern + "\"" +
                        " in context [" + getName() + "] - see" +
                        " section SRV.11.2 of the Servlet specification" );
            }
        }
        catch(NullPointerException npe)
        { //re throw NPE
          throw NullPointerException(npe.getMessage());
        }
    }
Comment 2 Wesley 2010-09-14 07:09:40 UTC
Okay what I'm seeing with a simple application with an index.jsp and a filter.

In o.a.c.c.ApplicationFilterFactory#createFilterChain, requestPath is being set to request.getAttribute(DISPATCHER_REQUEST_PATH_ATTR); It is this attribute that is matched against the filter; Which is "/index.jsp" (in my case) rather than the URI requested by the browser. 

Now I'm not sure if this is correct behaviour or not. I'd need to confirm with the specs but it sounds wrong.

My test application run against tc6.0.18 didn't match the root node either however. I haven't run that in debug to see if its the same reason.
Comment 3 Mark Thomas 2010-09-21 09:40:33 UTC
Managed to speak to the spec lead and a couple of EG members about this. The intention (although only implied rather than explicitly stated) of the Servlet spec is that the welcome file mapping (if required) is applied before matching with any filter URL patterns.

Hopefully the next maintenance release will have some clarifications in this area.

I am therefore closing this as won't fix. If the spec had been clearer, I probably would have closed it as invalid.