Link to home
Start Free TrialLog in
Avatar of xtremebytes2002
xtremebytes2002

asked on

No cache for specific content

I am generating some XHTML pages on-the-fly through a servlet that does XSL transformation on some XML data. The XHTML pages are served through Apache Tomcat 4.1.29. The servlet can serve other kinds of data including binary stream. I do not want the browser to cache the XHTML pages but it can cache binary content. I vaguely remember that there may be a pragma directive like "no-cache". Could anyone let me know how and when I can send this pragma directive to the browser to stop it from caching the XHTML content? If this directive does not actually solve the problem, then what may be the alternative? Thanks.
ASKER CERTIFIED SOLUTION
Avatar of kalosi
kalosi

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of xtremebytes2002
xtremebytes2002

ASKER

Thanks. How about sending the cache-control and pragma headers through the servlet using response.addHeader() method? I did it that way. It works fine for most cases, except at certain times when the content served by the servlet is binary. Even then, it is a bit unpredictable. It does not work only few times. Definitely, I cannot write meta tags in an HTTP output stream if it is binary stream?
Just to add more that contradicting to my initial query, I do need no-cache for some of the binary content I serve. The browser has to request a specific query string (like "cache=1") to avoid the HTTP no-cache headers sent by the servlet. Do you think this may work?
Something like this

        if(request.getParameter("cache")==null) {
          //use cache-control
          response.setHeader("Cache-Control",
                             "no-cache, no-store, must-revalidate");
          response.setHeader("Cache-Control",
                             "post-check=0, pre-check=0");
          response.setHeader("Pragma", "no-cache");
        }

If the "cache" parameter is present (irrespective of its value), it won't send these headers. Do I also need to sent "last-modified" and "expires" as headers?
Hi,

comment one:

response.addHeader() is exactly what I tougth, I do it both ways as I already wrote, I send the headers and write the meta too. It's just to go 100% sure ;-))

comment two:

I don't really know what are you trying to say with this one, could you please specify it ? What sort of binary content are you serving ??

david
Yes, that's completely OK. You can potentionally implement a BaseServlet which will handle the HTTP header stuff. All your other servlets will just extend your BaseServlet so all the code will be in one place and is easy to change.

david.
I am a bit rusty on the HTTP RFC 2068. Is there something like a "expires" and "last-modified" header? Thanks anyway.
Otherwise, how do I specify them for binary content?
yes, when you would check the response headers from the server you would see theese headers

Cache-Control: no-cache, must-revalidate
Pragma: no-cache
Last-Modified: Fri, 13 Feb 2004 09:49:40 GMT
Expires: Fri, 13 Feb 2004 09:49:40 GMT
............... //rest of the HTTP headers


david
I still don't know what "binary content" is - pictures/wavs/mp3/pdf ??

Thanks. Okay binary content is something unspecified in my context. It can be anything ranging from pictures, vrml, audio files, other formats and even text, unicode text, etc. All I need to do is open a FileInputStream and use the ServletOutputStream for output. I keep on reading the input file (I don't care what content it has) in chunks without any character conversion and output each chunk to the output stream till end of file is reached (<FileInputStream>.available() returns 0). Here's an example code.

private void SendFileToOutput(FileInputStream fInS,
                                OutputStream outS)
      throws Throwable {
    while (true) {
      int nReadSize = fInS.available();
      if (nReadSize <= 0) {
        break;
      }
      byte[] buffer = new byte[nReadSize];
      fInS.read(buffer);
      outS.write(buffer);
      outS.flush();
    }
  }

The only criteria about this binary content is that I cannot add meta tags because I don't explicity add things to the OutputStream. I just copy the content of the FileInputStream into the OutputStream. That's the only difference. In the other cases (when my servlet does not serve binary content but XHTML content), I can add whatever meta tags I need.
Section 14.21 of RFC 2068 (http://www.faqs.org/rfcs/rfc2068.html) states that the Expires header must contain a date time defined by HTTP-date as specified in RFC 1123 (http://www.faqs.org/rfcs/rfc1123.html), an example being

Expires: Thu, 01 Dec 1994 16:00:00 GMT

Is that format always like that or dependent on client or server locale settings? How do I get the current date time to be presented in the acceptable format for this? Thanks.
Ok I found it myself anyway. Thanks.