Tomcat 7.0.20 Windows XP JDK 1.6.0_20 I think there is a bug in Tomcat's handling of the Date HTTP header. I'm mailing this list because there is a minor suggested code change at the bottom to fix.
When the system clock time is advanced and then put back, with an HTTP request being handled in between those two actions, Tomcat will send the later of the two times in the response headers until the later time is reached. I think the problem is in the following code: package org.apache.tomcat.util.http; ... public final class FastHttpDateFormat { ... /** * Get the current date in HTTP format. */ public static final String getCurrentDate() { long now = System.currentTimeMillis(); if ((now - currentDateGenerated) > 1000) { synchronized (format) { if ((now - currentDateGenerated) > 1000) { currentDate = format.format(new Date(now)); currentDateGenerated = now; } } } return currentDate; } So, when the clock is advanced, currentDateGenerated becomes 'now'. However, when it is retarded, now-currentDateGenerated will typically be a negative number, and so the current date is never updated. This is causing us a problem since we have systems that sync off the date header. I have tried to work around the problem with a ServletFilter: HttpServletResponse httpResp = (HttpServletResponse) resp; DateFormat df = new SimpleDateFormat(HTTP_RESPONSE_DATE_HEADER, Locale.US); df.setTimeZone(GMT_ZONE); httpResp.setHeader("Date", df.format(new Date(System.currentTimeMillis()))); However, it looks like Tomcat is overriding the Date header later in the request lifecycle than a ServetFilter can intercept. I understand that the 'getCurrentDate()' method in the code above means that Tomcat only needs to do a DateFormat.format() on a long value once every second at most and so was clearly introduced to improve performance, but this makes Tomcat susceptible to incorrect system dates and will also be returning an invalid time for (typically) one hour when clocks go back in the autumn / fall. It would be better to check for a negative number in this method and regenerate 'currentDateGenerated' if this is the case: ... if ((now - currentDateGenerated) > 1000 || (now - currentDateGenerated) < 0) { synchronized (format) { if ((now - currentDateGenerated) > 1000) { currentDate = format.format(new Date(now)); currentDateGenerated = now; } } } return currentDate; ... Please let me know if there is a workaround or if I'm wrong in my reading of the situation. Thanks, Mick Sear --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org