If you enable rewrites, and put a rewrite.config in, where the source location does not match a valid context, the server issues a 404. The server then logs a 404 in the access log for the target location. I would argue that the server should perform the rewrite and return the target's content. However, if that is not what is meant to happen, then the logged 404 should be for the source URL, not the target. In "Bonus Step 8." below, you can see that the server _thinks_ the rewrite rule is present and that it has rewritten the request. Step 1. Enable Rewrite valve via <Valve className="org.apache.catalina.valves.rewrite.RewriteValve" /> Step 2. Add a rewrite.config to conf/Catalina/localhost containing: RewriteRule ^/source/(.*)$ /target/$1 [L] Step 3. Delete all webapps rm -rf webapps/* Step 4. Create webapps/target/index.html Step 5. Start server Step 6. Test Rewrite curl -I http://localhost:8080/source/index.html HTTP/1.1 404 Step 7. Observe rewritten path in logs: 0:0:0:0:0:0:0:1 - - [10/Jul/2020:18:44:06 +0100] "HEAD /target/index.html HTTP/1.1" 404 - Bonus Step 8. Enable FINE logging, and we get the following lines: 10-Jul-2020 19:27:36.803 FINE [Catalina-startStop-1] org.apache.catalina.valves.rewrite.RewriteValve.parse Add rule with pattern ^/source/(.*)$ and substitution /target/$1 org.apache.catalina.valves.rewrite.RewriteValve.invoke Rewrote /source/index.html as /target/index.html with rule pattern ^/source/(.*)$
I am able to reproduce this using the steps provided. Thank you for providing a simple test case for this issue. It saves a considerable amount of time. I'll note at this point that creating webapps/ROOT is sufficient to resolve the issue. Generally, running without a ROOT web application is not recommended. However, unless the fix complex, I still think this should be fixed.
Yes, Catalina never likes unmapped requests, it's kind of a lost cause and an empty "ROOT" folder will usually solve all the problems at no cost. Mark, I can look at this issue if you don't have time [I was planning to try later today].
Thanks for the offer. I've tracked down the root cause. The missing ROOT context puts the response into the error state which then doesn't get cleared in the RewriteValve. What I haven't figured out is the best way to handle this. Suggestions welcome.
It could be possible to remove the sendError(404) here: https://github.com/apache/tomcat/blob/master/java/org/apache/catalina/connector/CoyoteAdapter.java#L696 And move it to StandardHostValve (if request.getContext() == null) and StandardEngineValve (if request.getHost() == null).
I think that could be a better option that the one I was looking at. Undoing the effects of calling sendError() gets messy rather quickly. I'll experiment.
(In reply to Mark Thomas from comment #5) > I think that could be a better option that the one I was looking at. Undoing > the effects of calling sendError() gets messy rather quickly. I'll > experiment. I agree reverting the error is a problem, since it could be set for another legitimate reason (although since there is also context == null this is less likely).
I've fixed this using Rémy's suggested fix. I also back-ported the fix for bug 53411 to 8.5.x. Fixed in: - master for 10.0.0-M8 onwards - 9.0.x for 9.0.38 onwards - 8.5.x for 8.5.58 onwards 7.0.x is not affected.