I'm working on a web app in ASP.NET 2.0 that involves serving images via a resource handler (.ashx). I've just implemented handling cache headers and conditional GET requests, so that I don't have to serve all the images for every request. But I'm not sure I'm completely understanding what's happening with the browser's cache.
Images are fetched via urls like http://www.mysite.com/image.ashx?imageID=3
. My code in the handler looks something like this:
int imageID = -1;
try
{
imageID = Int32.Parse(context.Request["imageID"]);
}
catch (Exception) {}
MyImageClass image = DataLayer.GetImage(imageID);
if (image != null)
{
DateTime requestedDate = DateTime.MinValue;
if (context.Request.Headers["If-Modified-Since"] != null)
{
requestedDate = DateTime.Parse(context.Request.Headers["If-Modified-Since"])
.ToLocalTime();
}
if (requestedDate < image.ModifiedDate)
{
context.Response.AddHeader("content-type", image.ContentType);
context.Response.CacheControl = HttpCacheability.Private.ToString();
context.Response.Cache.SetLastModified(image.ModifiedDate.ToUniversalTime());
context.Response.Cache.SetMaxAge(TimeSpan.FromDays(1));
//write image to output stream
}
else
{
context.Response.StatusDescription = "Not Modified";
context.Response.StatusCode = 304;
}
}
This is what the response header looks like the first time an image is requested:
HTTP/1.1 200 OK
Cache-Control: private, max-age=86400
Content-Length: 1048576
Content-Type: image/jpeg
Expires: Sat, 28 Jan 2012 17:17:11 GMT
Last-Modified: Fri, 27 Jan 2012 16:50:27 GMT
Server: Microsoft-IIS/7.5
X-AspNet-Version: 2.0.50727
X-Powered-By: ASP.NET
Date: Fri, 27 Jan 2012 17:17:10 GMT
And this is a response to a subsequent request:
HTTP/1.1 304 Not Modified
Cache-Control: private
Server: Microsoft-IIS/7.5
X-AspNet-Version: 2.0.50727
X-Powered-By: ASP.NET
Date: Fri, 27 Jan 2012 17:17:30 GMT
Connection: close
Watching the requests in Fiddler, I'm noticing that the browser (Firefox 9) always makes a conditional GET request for the image after the first request. It gets the 304 Not Modified
response and pulls the image from cache, which is great. But isn't there a way to make it always pull from the cache, without even asking the server, until after the header's max-age (or expiry date) is past? I've tried using context.Response.Cache.SetExpires()
with a future date, and the browser still makes the conditional GET request.