using System; using System.IO; using System.Text.RegularExpressions; using System.Web; using ChadSoft.Web.ResponseFilters; namespace ChadSoft.Web.Modules { public class CdnRewriteModule : IHttpModule { public void Init(HttpApplication context) { context.PostReleaseRequestState += context_PostReleaseRequestState; } static void context_PostReleaseRequestState(object sender, EventArgs e) { var response = ((HttpApplication)sender).Response; response.Filter = new CdnPathRewriterFilter(response.Filter); } public void Dispose() { } public class CdnPathRewriterFilter : TextProcessingResponseFilter { const string TAG_EXPR = "(?<=<(?:script|img|link)[^>]*(?:src|href)=)['\"](?!http)/?(?[^'\"]*)['\"]"; const string TAG_REPLACE_EXPR = "'{0}/${{url}}'"; static readonly Regex ResourceRegex = new Regex(TAG_EXPR, RegexOptions.IgnoreCase); private string _cdnBasePath = "http://static.jesschadwick.com"; public string CdnBasePath { get { return _cdnBasePath; } set { _cdnBasePath = value; // Invalidate the replacement text so it // is rebuilt on the next request to it. _replacementText = null; } } private string _replacementText; protected string ReplacementText { get { if(string.IsNullOrEmpty(_replacementText)) _replacementText = string.Format(TAG_REPLACE_EXPR, CdnBasePath); return _replacementText; } } public CdnPathRewriterFilter(Stream stream) : base(stream) { } protected override string ProcessResponseText(string responseText) { return ResourceRegex.Replace(responseText, ReplacementText); } } } }