https://issues.apache.org/bugzilla/show_bug.cgi?id=57216

            Bug ID: 57216
           Summary: Servlet mapping not found when creating
                    RequestDispatcher for forward()
           Product: Tomcat 8
           Version: 8.0.14
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: regression
          Priority: P2
         Component: Catalina
          Assignee: dev@tomcat.apache.org
          Reporter: tomcatuser2...@gmail.com

We have a servlet filter which creates a RequestDispatcher used to forward the
request to a servlet:

  String processingPath = processPath(req.getServletPath());
  RequestDispatcher dispatch = request.getRequestDispatcher(processingPath);
  dispatch.forward(request, response);

In Tomcat 8 the forward() fails because the servlet path doesn't match the
servlet mapping definition.  This only occurs when the context path is "/".

We configure our Context in server.xml:

<Host name="localhost"  appBase="" createDirs="false" unpackWARs="false"
autoDeploy="false" deployOnStartup="false">
  <Context path="/" ...>
    ...
  </Context>
</Host>

In ApplicationContext.getRequestDispatcher(String path) the context path is
prepended to the resource uri:

  uriCC.append(context.getPath(), 0, context.getPath().length());

Then in Mapper.map() a ContextVersion is retrieved from
contextObjectToContextVersionMap and passed to internalMapWrapper(), which
tries to remove the context path:

  int length = contextVersion.path.length();
    ...
  servletPath = pathOffset + length;
    ...
  path.setOffset(servletPath);

But the path is empty, so the offset is zero, and we end up with an extra "/"
at the start of the servlet path. This causes the servlet mapping to not be
matched.

This is ultimately due to these lines in MapperListener.registerContext():

        String contextPath = context.getPath();
        if ("/".equals(contextPath)) {
            contextPath = "";
        }

        mapper.addContextVersion(host.getName(), host, contextPath,
                context.getWebappVersion(), context, welcomeFiles, resources,
                wrappers);

In earlier Tomcat versions, the same context object was used to get the context
path in both ApplicationContext.getRequestDispatcher() and Mapper.map().  In
Tomcat 8 ApplicationContext.getRequestDispatcher() uses a StandardContext
object (with path="/"), while Mapper.map() uses a ContextVersion object (with
path="").

-- 
You are receiving this mail because:
You are the assignee for the bug.

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

Reply via email to