javatomcatno-cacheconfidential

How do I keep Tomcat deployed files in a context from caching in a browser?


I am working on a Java/Struts application that uses Tomcat 6.0.10. It's a typical web application that allows users to edit some forms, and streams PDFs. Way back, we added:

<security-constraint>
    <web-resource-collection>
        <web-resource-name>GeneralRequests</web-resource-name>
        <url-pattern>/WR1/*</url-pattern>
    </web-resource-collection>
    <user-data-constraint>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
</security-constraint>

So that any of the non-streaming pages are forced into https AND not cached (we thought). There is a separate constraint entry for the streaming pages in the system.

In recent tests on an IE6, we're finding that "sometimes" the pages are caching, although we've not fully determined when. As well as the CONFIDENTIAL flag, we also used to have:

        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache,no-store,max-age=0");
        response.setDateHeader("Expires", 1);

But we removed these because it seemed to be causing ugly re-posting warnings in IE6 and we thought that the CONFIDENTIAL transport-guarantee also included all of the proper mechanics to prevent browser caching of the page. We'd rather leave the issue up to Tomcat to do properly.

What is the "right" way to do this stuff, so we won't have (as many) problems in the future?

Are our caching problems being caused by a specific bug in IE6? Or just a specific set of releases? Does this allow happen in 7 and/or 8?

UPDATE: We checked, and Tomcat is correctly sending the Pragma, Cache-Control and Expires params, so that is not the problem (well, the no-string and max-age values are not being sent, but still is not the problem).

The problem turned out to be the Apache Portable Runtime (APR) 1.1.8. Somehow, although we are not entirely sure why, it is creating duplicate browser actions from a single request. To us, it looked as if the page was cached because it contained an invalid Struts Transaction Token, but in actuality a second executing version of the same request (with the wrong session id) was overwriting the original request's token in the session. Upgrading to 1.1.16 fixed the problem.

Why some requests were getting duplicated (but with different sessions ids) is still a mystery ...

Paul.


Solution

  • No browser should cache any items it receives over SSL, so I would lean toward a bug in IE6. You could try 0 or -1 as the value for Expires instead of 1, but everything else you're doing looks okay to me.

    response.setHeader("Expires", 0);