1. Patrick Mézard
  2. httpcompress

Commits

Patrick Mézard  committed 8ca9d6b

Add optional rule annotation for user-agents.

For instance:

<add type="image/bar" ua="msie[0-6]"/>

includes or exludes only if user agent is MSIE5 and type is image/bar
but not if user agent is MSIE7 with the same type. "ua" is a regular
expression matching the user-agent. By default, all are matched.

  • Participants
  • Parent commits e52aba9
  • Branches default

Comments (0)

Files changed (4)

File HttpCompress/HttpModule.cs

View file
           return;
         }
 
-        if(settings.IsExcludedMimeType(app.Response.ContentType)){
+        if(settings.IsExcludedMimeType(app.Response.ContentType, app.Request.UserAgent)){
           // skip if the MimeType excludes compression
           return;
         }

File HttpCompress/Settings.cs

View file
 using System.Collections;
 using System.Collections.Generic;
 using System.Collections.Specialized;
+using System.Text.RegularExpressions;
 using System.Xml;
 
 namespace blowery.Web.HttpCompress {
 
     private Algorithms _preferredAlgorithm;
     private CompressionLevels _compressionLevel;
-    private Dictionary<string, bool> _includedTypes;
-    private Dictionary<string, bool> _excludedTypes;
+    private Dictionary<string, Regex> _includedTypes;
+    private Dictionary<string, Regex> _excludedTypes;
     private StringCollection _excludedPaths;
 
     /// <summary>
     private Settings() {
       _preferredAlgorithm = Algorithms.Default;
       _compressionLevel = CompressionLevels.Default;
-      _excludedTypes = new Dictionary<string, bool>();
-      _includedTypes = new Dictionary<string, bool>();
+      _excludedTypes = new Dictionary<string, Regex>();
+      _includedTypes = new Dictionary<string, Regex>();
       _excludedPaths = new StringCollection();
       _excludedPaths.Add(".axd");
     }
       get { return _compressionLevel; }
     }
     
-
     /// <summary>
     /// Checks a given mime type to determine if it has been excluded from compression
     /// </summary>
     /// <param name="mimetype">The MimeType to check.  Can include wildcards like image/* or */xml.</param>
     /// <returns>true if the mime type passed in is excluded from compression, false otherwise</returns>
     public bool IsExcludedMimeType(string mimetype) {
+      return IsExcludedMimeType(mimetype, "");
+    }
+
+    /// <summary>
+    /// Checks a given mime type to determine if it has been excluded from compression
+    /// </summary>
+    /// <param name="mimetype">The MimeType to check.  Can include wildcards like image/* or */xml.</param>
+    /// <param name="ua">Caller user-agent or null</param>
+    /// <returns>true if the mime type passed in is excluded from compression, false otherwise</returns>
+    public bool IsExcludedMimeType(string mimetype, string ua) {
       if(mimetype == null)
         return true;
+      if(ua == null)
+        ua = "";
       mimetype = mimetype.ToLower();
-      if(_includedTypes.Count > 0 && !_includedTypes.ContainsKey(mimetype))
+      if(_includedTypes.Count > 0) {
+        Regex reinc = null;
+        if(!_includedTypes.TryGetValue(mimetype, out reinc))
+          return true;
+        if(reinc != null && !reinc.IsMatch(ua))
+          return true;
+      }
+      if(_excludedTypes.Count <= 0)
+        return false;
+      Regex reexc = null;
+      if(!_excludedTypes.TryGetValue(mimetype, out reexc))
+        return false;
+      if(reexc == null || reexc.IsMatch(ua))
         return true;
-      return _excludedTypes.ContainsKey(mimetype);
+      return false;
     }
 
     /// <summary>
       return _excludedPaths.Contains(relUrl.ToLower());
     }
 
-    private void ParseTypes(XmlNode node, Dictionary<string, bool> types) {
+    private void ParseTypes(XmlNode node, Dictionary<string, Regex> types) {
       if(node == null) return;
 
       for(int i = 0; i < node.ChildNodes.Count; ++i) {
         switch(node.ChildNodes[i].LocalName) {
           case "add":
-            if(node.ChildNodes[i].Attributes["type"] != null)
-              types[node.ChildNodes[i].Attributes["type"].Value.ToLower()] = true;
+            if(node.ChildNodes[i].Attributes["type"] != null) {
+              Regex re = null;
+              if(node.ChildNodes[i].Attributes["ua"] != null) {
+                String ua = node.ChildNodes[i].Attributes["ua"].Value;
+                re = new Regex(ua, RegexOptions.IgnoreCase | RegexOptions.Compiled);
+              }
+              types[node.ChildNodes[i].Attributes["type"].Value.ToLower()] = re;
+            }
             break;
           case "delete":
             if(node.ChildNodes[i].Attributes["type"] != null) {

File Tests/SettingsTests.cs

View file
       Assert.That(setting.IsExcludedMimeType("image/baz"));
     }
 
+    [Test] public void UserAgentTypes() {
+      Settings setting = new Settings(MakeNode(rman.GetString("UserAgentTypes")));
+      Assert.That(!setting.IsExcludedMimeType("image/foo"));
+      Assert.That(!setting.IsExcludedMimeType("image/foo", null));
+      Assert.That(setting.IsExcludedMimeType("image/bar"));
+      Assert.That(!setting.IsExcludedMimeType("image/bar", "MSIE6"));
+      Assert.That(!setting.IsExcludedMimeType("image/baz"));
+      Assert.That(setting.IsExcludedMimeType("image/baz", "MSIE6"));
+      Assert.That(!setting.IsExcludedMimeType("image/baz", "MSIE7"));
+    }
+
     private System.Xml.XmlNode MakeNode(string xml) {
       System.Xml.XmlDocument dom = new System.Xml.XmlDocument();
       dom.LoadXml(xml);

File Tests/XmlTestDocuments.resx

View file
       &lt;/httpCompressionModule&gt;
       </value>
     </data>
+    <data name="UserAgentTypes">
+      <value>
+        &lt;httpCompressionModule&gt;
+        &lt;includedMimeTypes&gt;
+        &lt;add type="image/foo"/&gt;
+        &lt;add type="image/bar" ua="msie[0-6]"/&gt;
+        &lt;add type="image/baz"/&gt;
+        &lt;/includedMimeTypes&gt;
+        &lt;excludedMimeTypes&gt;
+        &lt;add type="image/baz" ua="msie[0-6]"/&gt;
+        &lt;/excludedMimeTypes&gt;
+        &lt;/httpCompressionModule&gt;
+      </value>
+  </data>
 </root>