Sunday, March 6, 2011

Problem with caching

I have an a aspx page, but all content is generated by hands(yes I know that I need to make a handler, I have another question)

I want to cache output in client browser. Problem is that it's cached only for one query.

        public static void ProceedCaching(string etag, string lastModify, string response, HttpResponse Response,
                                      HttpRequest Request)
    {
        Response.AddHeader("ETag", "\"" + etag + "\"");
        Response.AddHeader("Last-Modified", lastModify);
        Response.AppendHeader("Cache-Control", "Public");
        Response.AppendHeader("Expires",
                              DateTime.Now.AddMinutes(1).ToUniversalTime().ToString("r",DateTimeFormatInfo.InvariantInfo));

        string ifModified = Request.Headers["If-Modified-Since"];

        if (!string.IsNullOrEmpty(ifModified))
        {
            if (ifModified.Contains(";"))
                ifModified = ifModified.Remove(ifModified.IndexOf(';'));
        }

        string incomingEtag = Request.Headers["If-None-Match"];

        if (String.Compare(incomingEtag, etag) == 0 || string.Compare(ifModified, lastModify) == 0)
        {
            Response.StatusCode = 304;
            Response.End();
        }

        Response.Write(response);
        Response.End();
    }

it's become preaty messy. As I said it's cached only once. After recevieng HTTP 304 browser will send clean request without caching information(etag, lastmodified). Have any ideas?

From stackoverflow
  • Your code-snippet works fine for me if i remove the quotes you are adding around the etag at first line. But im guessing thats just a mistake in the snippet, and not the real problem you are facing.

    Firefox 3 dosnt even bother to hit the server after it has received the first 304. IE7 keeps going, but it sends lastmod/etag headers correctly and receives a 304 each time.

    Are you sure its not because you have changed caching settings in your browser? I would try it out in another browser to make sure.

    To make it a bit cleaner you could use the methods on Response.Caching instead of setting headers directly.

    AlfeG : sorry for my absence(i am on vacation) I think you right. problem in quotes
  • Found this answer here

    Generally speaking, these are the most common rules that are followed (don’t worry if you don’t understand the details, it will be explained below):

    1. If the response’s headers tell the cache not to keep it, it won’t.
    2. If the request is authenticated or secure, it won’t be cached.
    3. If no validator (an ETag or Last-Modified header) is present on a response, and it doesn't have any explicit freshness information, it will be considered uncacheable.
    4. A cached representation is considered fresh (that is, able to be sent to a client without checking with the origin server) if:
      • It has an expiry time or other age-controlling header set, and is still within the fresh period.
      • If a browser cache has already seen the representation, and has been set to check once a session.
      • If a proxy cache has seen the representation recently, and it was modified relatively long ago. Fresh representations are served directly from the cache, without checking with the origin server.
    5. If an representation is stale, the origin server will be asked to validate it, or tell the cache whether the copy that it has is still good.

    And Microsoft has a good article if you don't want it to cache.

0 comments:

Post a Comment