|
#undef IIS6
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
namespace WcfService1
{
public sealed class JavascriptProxyCacheModule : IHttpModule
{
private HttpApplication app;
public void Init(HttpApplication context)
{
app = context;
app.EndRequest += new EventHandler(app_EndRequest);
app.BeginRequest += new EventHandler(app_BeginRequest);
}
void app_BeginRequest(object sender, EventArgs e)
{
var path = app.Context.Request.Path.ToLower().Replace('\\', '/');
if (IsWcfJavacsriptProxy(path))
{
// versioning is used by using (xxx) in the path of the script
// reference. for ex, /(v2)/Service.svc/js
// In this case, remove the (v2)/
int pos = path.IndexOf('(');
if (pos > 0)
{
int endPos = path.IndexOf(')');
path = path.Substring(0, pos) + path.Substring(endPos + 2);
app.Context.RewritePath(path);
string ifModifiedSince = app.Context.Request.Headers["If-Modified-Since"];
if (!string.IsNullOrEmpty(ifModifiedSince))
{
string filePath = app.Context.Request.PhysicalPath;
DateTime fileLastModifyDateTime = File.GetLastWriteTime(filePath);
DateTime browserLastModifyDateTime;
if (DateTime.TryParse(ifModifiedSince, out browserLastModifyDateTime))
{
if ((browserLastModifyDateTime - fileLastModifyDateTime).Seconds > 5)
{
app.Context.Response.StatusCode = 304;
app.Context.Response.End();
}
}
}
}
}
}
private void app_EndRequest(object sender, EventArgs e)
{
var path = app.Context.Request.Path.ToLower().Replace('\\', '/');
if (app.Context.Response.StatusCode == 200
|| app.Context.Response.StatusCode == 202)
{
if (IsWcfJavacsriptProxy(path) && IsVersioned())
{
var lastModified = DateTime.UtcNow;
// Expire by tomorrow 7 AM always.
var expires = lastModified.AddDays(1).Subtract(lastModified.TimeOfDay).AddHours(7);
HttpCachePolicy cache = app.Context.Response.Cache;
cache.SetLastModified(lastModified);
cache.SetExpires(expires);
cache.SetCacheability(HttpCacheability.Public);
}
}
}
private bool IsWcfJavacsriptProxy(string path)
{
// It has to be a .svc extension hit
// And it must have the version number on the URL. Don't want to accidentally
// cache non versioned WCF proxies.
// Then it must have a /js or /jsdebug hit
return path.Contains(".svc/")
&& (path.EndsWith("/js") || path.EndsWith("/jsdebug"));
}
private bool IsVersioned()
{
return app.Context.Request.RawUrl.IndexOf('(') > 0;
}
public void Dispose()
{
#if IIS6
app.EndRequest -= app_EndRequest;
app.BeginRequest -= app_BeginRequest;
#endif
app = null;
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.