Some people like to have a compressed output of there WebForms or MVC-Pages in .NET. The following snippet shows such a compressor. It is not optimized for performance but you should see the principle behind. The compressor takes care of <pre><code>. You may also use this compressor to remove unwanted html snippets from your MVC or WebForm pages.
using System.Linq;
namespace ProCompressor
{
using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
public sealed class CompressionModule : IHttpModule
{
#region non public members
private static void ContextBeginRequest(object sender, EventArgs e)
{
var app = sender as HttpApplication;
if (app != null) if (app.Request.AcceptTypes != null && app.Request.AcceptTypes.Contains("text/html") && !app.Request.RawUrl.Contains("/Admin/")) app.Response.Filter = new CompressorBuffered(app.Response.Filter);
}
#endregion
#region IHttpModule Members
void IHttpModule.Dispose() { }
void IHttpModule.Init(HttpApplication context) { context.BeginRequest += ContextBeginRequest; }
#endregion
#region Non Public Nested type: CompressorBuffered
private class CompressorBuffered : Stream
{
#region fields
private readonly MemoryStream memoryStream;
private readonly Stream stream;
#endregion
#region constructors
public CompressorBuffered(Stream stream)
{
this.stream = stream;
this.memoryStream = new MemoryStream();
}
#endregion
#region public properties
public override bool CanRead { get { return this.stream.CanRead; } }
public override bool CanSeek { get { return this.stream.CanSeek; } }
public override bool CanWrite { get { return this.stream.CanWrite; } }
public override long Length { get { return this.stream.Length; } }
public override long Position { get; set; }
#endregion
#region public members
public override void Close()
{
var data = this.memoryStream.ToArray();
var content = Encoding.UTF8.GetString(data);
content = CompressHtml(content);
var output = Encoding.UTF8.GetBytes(content);
this.stream.Write(output, 0, output.GetLength(0));
this.stream.Close();
}
public override void Flush() { this.stream.Flush(); }
public override int Read(byte[] buffer, int offset, int count) { return this.stream.Read(buffer, offset, count); }
public override long Seek(long offset, SeekOrigin origin) { return this.stream.Seek(offset, origin); }
public override void SetLength(long value) { this.stream.SetLength(value); }
public override void Write(byte[] buffer, int offset, int count) { this.memoryStream.Write(buffer, offset, count); }
#endregion
#region non public members
private static string CompressHtml(string content)
{
var matches = Regex.Matches(content, "<pre>.*</pre>", RegexOptions.Singleline).Cast<Match>().ToList();
content = Regex.Replace(content, "^\\s*", string.Empty, RegexOptions.Compiled | RegexOptions.Multiline);
content = Regex.Replace(content, "\\r\\n", string.Empty, RegexOptions.Compiled | RegexOptions.Multiline);
content = Regex.Replace(content, "\\n", string.Empty, RegexOptions.Compiled | RegexOptions.Multiline);
content = Regex.Replace(content, "<!--*.*?-->", string.Empty, RegexOptions.Compiled | RegexOptions.Multiline);
content = content.Replace("<![CDATA[", "<![CDATA[" + Environment.NewLine);
content = content.Replace("//]]>", Environment.NewLine + "//]]>");
content = content.Replace("\t", " ");
var i = 0;
content = Regex.Replace(
content,
"<pre>.*</pre>",
(match) =>
{
try
{
return matches[i].Value;
}
finally
{
i += 1;
}
},
RegexOptions.Singleline);
foreach (var match in matches)
{
}
return content;
}
#endregion
}
#endregion
}
}
<system.webServer>
<modules runAllManagedModulesForAllRequests="false">
<remove name="CompressionModule" />
<add name="CompressionModule" type="ProCompressor.CompressionModule" />
</modules>