Thursday, May 10, 2012

Change Image Url in ASP.Net using HttpModule to point to some CDN

This is something i have created to change the image urls at runtime to point those url at some CDN server instead of my own server.
What i have done is simply intercept the a page if it ends with .aspx and them apply filter using my own created stream that will check the html markup and replace image url to CDN url.


ASPX Code:
 
 or even you can use 
 
 
HttpModule Code: 
  
public class CDNImageModule : IHttpModule
    {
        public void Dispose()
        {

        }
        public void Init(HttpApplication context)
        {
                context.BeginRequest += (o, e) =>
                {
                    if (context.Request.RawUrl.EndsWith(".aspx"))
                    {
                        var _watcher = new StreamWatcher(context.Response.Filter);
                        context.Response.Filter = _watcher;
                    }
                };
        }
    }

    public class StreamWatcher : Stream
    {

        public StreamWatcher(Stream sink)
        {
            _sink = sink;
        }

        private Stream _sink;

        #region Properites

        public override bool CanRead
        {
            get { return true; }
        }

        public override bool CanSeek
        {
            get { return true; }
        }

        public override bool CanWrite
        {
            get { return true; }
        }

        public override void Flush()
        {
            _sink.Flush();
        }

        public override long Length
        {
            get { return 0; }
        }

        private long _position;
        public override long Position
        {
            get { return _position; }
            set { _position = value; }
        }

        #endregion

        #region Methods

        public override int Read(byte[] buffer, int offset, int count)
        {
            return _sink.Read(buffer, offset, count);
        }

        public override long Seek(long offset, SeekOrigin origin)
        {
            return _sink.Seek(offset, origin);
        }

        public override void SetLength(long value)
        {
            _sink.SetLength(value);
        }

        public override void Close()
        {
            _sink.Close();
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            byte[] data = new byte[count];
            Buffer.BlockCopy(buffer, offset, data, 0, count);
            string html = System.Text.Encoding.Default.GetString(buffer);

            TransformString(ref html);

            byte[] outdata = System.Text.Encoding.Default.GetBytes(html);
            _sink.Write(outdata, 0, outdata.GetLength(0));
        }

        #endregion


        void TransformString(ref string input)
        {

            string regExPatternForImgTags = "]* src=\\\"([^\\\"]*)\\\"[^>]*>"; //this will match all the  tags with src attribute, you may need to extend this. 

            MatchEvaluator evaluator = new MatchEvaluator(RewriteImageSrc);


            input = Regex.Replace(input, regExPatternForImgTags, evaluator);


        }

        public static string RewriteImageSrc(Match match)
        {
            return match.Value.Replace("src=\"", "src=\"http://img.mydomain.com/");

        }
} 

1 comment:

Unknown said...

Thanks a lot.... this is what i was looking for. You saved me