I need to use CDN for all images on my site. So, Ive decided to use IIS Url-rewriting module, because edit manually all my site views - its impossible for me.
So Ive made rules for IIS, eg:
<rule name="cdn1" stopProcessing="true">
<match url="^Content/Images.*/(.*\.(png|jpeg|jpg|gif))$" />
<action
type="Redirect"
url="http://c200001.r9.cf1.rackcdn.com/{ToLower:{R:1}}"
redirectType="Permanent" />
</rule>
Its worked, but as you can see there is redirect type is used (301 Permanent). And I think its affects site performance. Maybe it is possible to edit Request.Output to replace image URL?
Please advice, how can I use CDN for images, do not edit my views and avoid redirects?
Any help will be appreciated
I agree with Steve. You have the URL rewriter doing 301 redirects, but for every image the page needs, the browser still makes a request to the server first to discover that it's 301 redirected to a CDN Url. The only thing you're saving at this point is the downloading of the content.
Instead of doing that, you can just put a response filter in place that will modify the URLs of the assets before the Response is sent to the client browser. That way, the client browser never has to make any calls to your server for static assets:
protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
filterContext.RequestContext.HttpContext.Response.Filter = new CdnResponseFilter(filterContext.RequestContext.HttpContext.Response.Filter);
}
And then the CdnResponseFilter:
public class CdnResponseFilter : MemoryStream
{
private Stream Stream { get; set; }
public CdnResponseFilter(Stream stream)
{
Stream = stream;
}
public override void Write(byte[] buffer, int offset, int count)
{
var data = new byte[count];
Buffer.BlockCopy(buffer, offset, data, 0, count);
string html = Encoding.Default.GetString(buffer);
html = Regex.Replace(html, "src=\"/Content/([^\"]+)\"", FixUrl, RegexOptions.IgnoreCase);
html = Regex.Replace(html, "href=\"/Content/([^\"]+)\"", FixUrl, RegexOptions.IgnoreCase);
byte[] outData = Encoding.Default.GetBytes(html);
Stream.Write(outData, 0, outData.GetLength(0));
}
private static string FixUrl(Match match)
{
//However the Url should be replaced
}
}
The result of this is that all content assets that look like <img src="\Content\whatever.jpg" />
will be converted to <img src="cdn-url.com\Content\whatever.jpg" />
Given that the original URLs are coming from your content and not, for example, from bookmarks, I think you'll have trouble avoiding a request to your site and a redirect; a potentially significant performance impact that could negate the benefits of using a CDN.
It would be better if your could apply URL rewriting to the HTML that is transmitted to the browser, rather than when a request comes in.
Trouble is, I don't know how (unless you're using ISA server, in which case I could tell you, but I suspect you're not)!
You could create a custom ActionFilter and override OnResultExecuted, but you'd need to annotate your controller with the filter attribute.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With