tomcattomcat-valve

Why is my tomcat valve not being invoked?


I try to implement a Tomcat valve (currently using 7.0.55) that should intercept every request that reaches the Tomcat serivce, regardless of Connector and whatnot, regardless of wether there's a Host with matching name or a servlet context or whatever.

The invoke-method of the valve looks like this:

public class MyValve extends ValveBase {
    public void invoke(Request request, Response response) throws IOException,
            ServletException {
        LOG.trace("Valve is being invoked");
        getNext().invoke(request, response);
    }
}

On the dev system, testing locally, everything's working as excepted. A request to any URI path on my "localhost" tomcat writes that log line. In the sever.xml, the valve is configured outside of any Host element:

<Server port="8005" shutdown="SHUTDOWN">
  ...
  <Service name="Catalina">
    ...
    <Engine defaultHost="localhost" name="Catalina">
      ...
      <Realm ... />
      <Valve className="a.b.c.MyValve" />
      ...
      <Host ...>
      </Host>
    </Engine>
  </Service>
</Server>

Now say in my system's hosts file, the domain test.domain.com is mapped to 127.0.0.1, and there's one context deployed named some-webapp.

As said above the log line gets printet when I call http://localhost:8080/some-webapp/, which is as expected, and it gets also printed when I call http://localhost:8080/non-existing-webapp/, which is also as expected.
The same goes for the domain (that is not configured in server.xml) test.domain.com, thus http://test.domain.com/some-webapp/ prints the log line as well as http://test.domain.com/non-existing-webapp.

But this is not true for the server we're testing on. Here the Valve is only invoked if the context name of the URI is "known" to tomcat, i.e. a call to .../some-webapp/ would print the log line while a call to .../non-existing-webapp/ would simply do nothing - the valve is not invoked at all.
Still, tomcat handles that request as the 404 that gets sent to the client in this case contains "Apache-Coyote something" as a response header.

I'm out of ideas of how to debug this further, especially the process of tomcat's "selection" of a Pipeline or whatever - any thoughts out there?

Thanks!


Solution

  • Turns out it is caused by a missing ROOT-directory in Tomcat's webapps-dir. I think that Tomcat does filter incoming requests rather rigorously at a very early point in time, even before any valves can handle and mess with the request.
    And if there's no default context (i.e. no ROOT-dir) then Tomcat (thinks to) know(s) that a request to non-existing-webapp cannot succeed and thus does not even call the valve(s). With a default context Tomcat cannot know what will happen to the request and thus the valve gets its chance to intercept the request.