When using a static html file for 404 errors and the client sends a request to a file whoch doesn't exist, and adds a "If-Modified-Since" header with a date that is newer than the modification date of the static error file, then Tomcat returns "302 Not Modofied" instead of "404 Not Found". Steps to reproduce: 1) Make a simple webapp that uses a static html file as custom error page for 404 errors, like this (web.xml): <error-page> <error-code>404</error-code> <location>/errorpages/404.html</location> </error-page> 2) Do a GET request to a URL which points to a file that doesn't exist, and add a "If-Modified-Since" header with a date that is newer than the modification date of the 404 error file (the date may also be in the future), e.g. GET /MyWebApp/AUrlToAFileWhichDoesNotExist.gif HTTP/1.1 Host: localhost Keep-Alive: 115 Connection: keep-alive If-Modified-Since: Tue, 08 Nov 2015 15:07:52 GMT (replace "MyWebApp" with your webapp's name) 3) Tomcat returns "HTTP/1.1 302 Not Modified" instead of "HTTP/1.1 404 Not Found". Actual Results: Tomcat returns a "302 Not Modified" response, because it seems to compare the date of the "If-Modified-Header" with the date of the static 404 error file. Expected Results: Tomcat returns a "404 Not Found" response, because the requested file does not exist. If you omit the "If-Modified-Since" header or use a date that is older than the date of the error file, Tomcat correctly returns "404 Not Found", but adds an "Last-Modified" header with the modification date of the 404 file. This behavior caused invalid 302 responses to be sent over the ISAPI redirector (bug 50363, with enabled chunked encoding support) when I was viewing my site in Firefox and pressed F5 to refresh it, because I think as of bug 49591, Tomcat uses chunked encoding for this response, which the ISAPI redirector didn't check. I tested on Tomcat 7.0.5 on 32-Bit Windows XP, with Tomcat Native 1.1.20, on Java 1.6.0_22.
Sorry, when I wrote "302 Not Modified" I actually ment "304 Not Modified".
Thanks for the report. This has been fixed in 7.0.x and will be included in 7.0.6 onwards.
(In reply to comment #2) > Thanks for the report. This has been fixed in 7.0.x and will be included in > 7.0.6 onwards. Thanks :) I would like to note that the same behavior/bug exists in Tomcat 6.0.29 and 5.5.31 as well (I just tested it on these versions). Sorry I didn't that before. Maybe the fix needs to be backported? Cheers Konstantin
Re-open against 5.5.x so it gets fixed in 5.5.x and 6.0.x
Fixed in 6.0.x and will be included in 6.0.30 onwards.
One minor glitch with the current fix for this issue: (regards 7.0, 6.0 and proposed patch for 5.5) In DefaultServlet#serveResource(..) there is the following condition: if ( (cacheEntry.context != null) || ( ((ranges == null) || (ranges.isEmpty())) && (request.getHeader("Range") == null) ) || (ranges == FULL) ) { Note the following part of it: (ranges == null || ranges.isEmpty()) && (request.getHeader("Range") == null) With the current fix for this issue a "parseRange(request, response, cacheEntry.attributes)" call is skipped and thus "ranges" remains to be null, but request.getHeader("Range") still returns the original header. ============================================================================== Using MyWebApp with a custom 404.html page, as described by OP, I now get: In current 7.0.x (at rev.1056780) -- Request: GET /MyWebApp/AUrlToAFileWhichDoesNotExist.gif HTTP/1.1 Host: localhost Keep-Alive: 115 Connection: keep-alive Range: bytes=0-499 -- Response: HTTP/1.1 404 Not Found Server: Apache-Coyote/1.1 Transfer-Encoding: chunked Date: Sat, 08 Jan 2011 20:49:46 GMT 0 -- Request: (without the "Range" header) GET /MyWebApp/AUrlToAFileWhichDoesNotExist.gif HTTP/1.1 Host: localhost Keep-Alive: 115 Connection: keep-alive -- HTTP/1.1 404 Not Found Server: Apache-Coyote/1.1 Content-Type: text/html Content-Length: 17 Date: Sat, 08 Jan 2011 20:51:02 GMT Error 404.html! -- I.e., if "Range" header was specified, the custom error page is not used at all. It is not a show stopper, as it is still better than it was before, because e.g. in 5.5.31 the response is the following: -- Request: GET /MyWebApp/AUrlToAFileWhichDoesNotExist.gif HTTP/1.1 Host: localhost Keep-Alive: 115 Connection: keep-alive Range: bytes=0-499 -- Response: HTTP/1.1 206 Partial Content Server: Apache-Coyote/1.1 Accept-Ranges: bytes ETag: W/"17-1294518367875" Last-Modified: Sat, 08 Jan 2011 20:26:07 GMT Content-Range: bytes 0-16/17 Content-Type: text/html Content-Length: 17 Date: Sat, 08 Jan 2011 21:01:35 GMT Error 404.html! -- which is wrong, because it is successful "206 Partial Content", while "404 Not Found" was expected instead.
(In reply to comment #6) This is fixed by r1056889 in 7.0 - will be in 7.0.6. Proposed as an additional patch for this issue for 6.0 and 5.5.
fixed in 6.0.x and will be in 6.0.31 onwards
Will be in 5.5.32