Reputation: 7421
I'm taking over a project which uses a handler.ashx to auto-generate different sized versions of an image if they don't already exist. Additionally it should serve existing images and cache them in the clients browser. however all requests to the image return a 200 thus not caching.
When I use fiddler to see the requests the initial response of the image shows
after receiving the image the second request
<%@ WebHandler Language="VB" CodeBehind="GenericHandler.ashx.vb" Class=".GenericHandler" %>
Imports System.IO
Imports System.Web
Imports System.Web.Services
Imports System.Web.Script.Serialization
Imports System.Globalization
Public Class GenericHandler
Implements System.Web.IHttpHandler, System.Web.SessionState.IRequiresSessionState
Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
RequestHandler(context)
End Sub
Private Sub RequestHandler(ByVal context As HttpContext)
Select Case context.Request.HttpMethod
Case "GET"
GetFile(context)
Case Else
context.Response.ClearHeaders()
context.Response.StatusCode = 405
End Select
End Sub
Private Sub GetFile(ByVal context As HttpContext)
Dim strAssetId As String = context.Request("asset")
Dim strSize As String = context.Request("size")
Dim fileName As String = getAssetName(strAssetId)
Dim internalFile As String = CalculateFileName(context, fileName)
Dim refresh As TimeSpan = New TimeSpan(1, 0, 0, 0) '1 day cache
Dim encode As Boolean = context.Request("encode") = "1"
'we have already created the file
If File.Exists(internalFile) Then
'has the browser already recieved a cached version
If Not String.IsNullOrEmpty(context.Request.Headers("If-Modified-Since")) Then
Dim provider As CultureInfo = CultureInfo.InvariantCulture
Dim lastMod As DateTime = DateTime.ParseExact(context.Request.Headers("If-Modified-Since"), "r", provider).ToLocalTime()
'cached but is it within the expiry range
If lastMod < DateTime.Now.Add(refresh) Then
context.Response.StatusCode = 304
Return
End If
End If
Else
'this size of image didn't exist so create it.
GenerateFile(context, internalFile)
End If
context.Response.ClearContent()
context.Response.AddHeader("Content-Disposition", "attachment; filename=""" + fileName + """")
context.Response.Cache.SetExpires(DateTime.Now.Add(refresh))
context.Response.Cache.SetMaxAge(refresh)
context.Response.Cache.SetCacheability(HttpCacheability.Public)
context.Response.Cache.SetValidUntilExpires(True)
context.Response.ContentType = "image/png"
If encode Then
context.Response.Write(ImageBase64Encoder.Encode(internalFile))
Else
context.Response.WriteFile(internalFile)
End If
End Sub
Private Function CalculateFileName(ByVal context As HttpContext, fileName)
'calculates the filename of the requestedfilesize
End Function
Private Sub GenerateFile(ByVal context As HttpContext, internalFile As String)
'generates the correct sized version of the original image
End Sub
ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
Get
Return False
End Get
End Property
End Class
Upvotes: 0
Views: 1140
Reputation: 56496
The request headers of your second request do not contain the If-Modified-Since
header you're checking in your code.
Why not?
Because the first response does not contain a Last-Modified
header.
How to set the
Last-Modified
header ?
You can use: context.Response.Cache.SetLastModified(myfile.LastWriteTime);
Upvotes: 1