I'm using Tomcat 3.2.2 (relase) and have configured static .html files as
error pages. We used JSP pages before, and everything was fine... However
since we're using static files, Tomcat will enter an infinite loop and
eventually crash with a stack overflow (with a good change of leaving Tomcat
in a defunct state). We traced down this problem and have found a way to fix
it, but I'm not sure if this is correct.
All this is related to the ContextManager class:
1) Both handleStatus and handleError will call 'getHandlerForPath' when an
error page was configured.
2) getHandlerForPath returns a the Handler for the error page. (since we're
using static files, this will be a FileHandler). So far, so good.
3) Eventually handleStatus and handleError will do a
'errorServlet.service( req, res )' to service the error. This is were things
go wrong.
The problem is, that 'req' passed to the 'errorServlet.service( req, res )'
call is the original request, while getHandlerForPath creates a new request
internally with the error's request URI. Since the handler (FileHandler) is
called with the original request URI, it will try to service a file matching
that request, not the static file we configured. This, in turn, will cause
and error and, in our case, an infinite loop.
This can lead to very strange situations. For example, if an .jsp page
generates an error and the error refers to an (existing) static file, it
will actually end up showing the .jsp source file contents!
The quick and dirty fix we use here is to simply add 'req.setRequestURI(
ctx.getPath() + errorPath);' after the 'getHandlerForPath' calls in both
handleError and handleStatus methods. I'm not really sure if we are allowed
to modify the request in such a way, but error attributes are also set in
this request and it seems to work fine for us. But this raises another
question: why construct a completely new request and response in
getHandlerForPath, and then throw it away?
Cheers,
Peer Heijnen