Added new assembly to hold utility classes related to Http protocol
authorGonzalo Paniagua Javier <gonzalo.mono@gmail.com>
Thu, 24 Jul 2003 17:02:52 +0000 (17:02 -0000)
committerGonzalo Paniagua Javier <gonzalo.mono@gmail.com>
Thu, 24 Jul 2003 17:02:52 +0000 (17:02 -0000)
svn path=/trunk/mcs/; revision=16613

mcs/class/Makefile
mcs/class/Mono.Http/ChangeLog [new file with mode: 0644]
mcs/class/Mono.Http/Makefile [new file with mode: 0644]
mcs/class/Mono.Http/Mono.Http.dll.sources [new file with mode: 0644]
mcs/class/Mono.Http/Mono.Http/AcceptEncodingConfig.cs [new file with mode: 0644]
mcs/class/Mono.Http/Mono.Http/AcceptEncodingModule.cs [new file with mode: 0644]
mcs/class/Mono.Http/Mono.Http/AcceptEncodingSectionHandler.cs [new file with mode: 0644]
mcs/class/Mono.Http/Mono.Http/ChangeLog [new file with mode: 0644]
mcs/class/Mono.Http/Mono.Http/GZipWriteFilter.cs [new file with mode: 0644]
mcs/class/Mono.Http/NEWS [new file with mode: 0644]
mcs/class/Mono.Http/README [new file with mode: 0644]

index 726e705df32c205b3c60e198defa85f3f37ba8cd..62aa1a55cb602c279bae520350646cab946548b3 100644 (file)
@@ -44,6 +44,7 @@ SUBDIRS = \
        System.Messaging        \
        System.ServiceProcess \
        System.Drawing.Design           \
+       Mono.Http                       \
        Microsoft.Vsa                   
 #      Microsoft.JScript               \
 
diff --git a/mcs/class/Mono.Http/ChangeLog b/mcs/class/Mono.Http/ChangeLog
new file mode 100644 (file)
index 0000000..217619b
--- /dev/null
@@ -0,0 +1,4 @@
+2003-07-24  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       Initial check-in.
+
diff --git a/mcs/class/Mono.Http/Makefile b/mcs/class/Mono.Http/Makefile
new file mode 100644 (file)
index 0000000..fa52b9d
--- /dev/null
@@ -0,0 +1,11 @@
+thisdir = class/Mono.Http
+SUBDIRS = 
+include ../../build/rules.make
+
+LIBRARY = Mono.Http.dll
+LIB_MCS_FLAGS = -r:$(corlib) -r:System.dll -r:System.Xml.dll \
+               -r:System.Web.dll -r:ICSharpCode.SharpZipLib.dll
+
+NO_TEST = yes
+
+include ../../build/library.make
diff --git a/mcs/class/Mono.Http/Mono.Http.dll.sources b/mcs/class/Mono.Http/Mono.Http.dll.sources
new file mode 100644 (file)
index 0000000..467235e
--- /dev/null
@@ -0,0 +1,4 @@
+Mono.Http/AcceptEncodingConfig.cs
+Mono.Http/AcceptEncodingModule.cs
+Mono.Http/AcceptEncodingSectionHandler.cs
+Mono.Http/GZipWriteFilter.cs
diff --git a/mcs/class/Mono.Http/Mono.Http/AcceptEncodingConfig.cs b/mcs/class/Mono.Http/Mono.Http/AcceptEncodingConfig.cs
new file mode 100644 (file)
index 0000000..051909d
--- /dev/null
@@ -0,0 +1,107 @@
+//
+// AcceptEncodingConfig.cs
+//
+// Authors:
+//     Gonzalo Paniagua Javier (gonzalo@ximian.com)
+//
+// (c) 2003 Ximian, Inc (http://www.ximian.com)
+//
+
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Web;
+
+namespace Mono.Http
+{
+       public class AcceptEncodingConfig
+       {
+               Hashtable tbl = CollectionsUtil.CreateCaseInsensitiveHashtable ();
+
+               public AcceptEncodingConfig () : this (null)
+               {
+               }
+               
+               public AcceptEncodingConfig (AcceptEncodingConfig parent)
+               {
+                       if (parent == null)
+                               return;
+
+                       // FIXME: copy parent's config
+               }
+
+               public void Add (string encoding, string type)
+               {
+                       tbl [encoding] = Type.GetType (type);
+               }
+
+               public bool SetFilter (HttpResponse response, string acceptEncoding)
+               {
+                       if (acceptEncoding == null)
+                               return false;
+
+                       acceptEncoding = acceptEncoding.Trim ();
+                       if (acceptEncoding == "")
+                               return false;
+                               
+                       string [] parts = null;
+                       if (acceptEncoding.IndexOf (';') != -1)
+                               parts = acceptEncoding.Split (';');
+                       else
+                               parts = acceptEncoding.Split (',');
+
+                       string encoding;
+                       float weight = 0.0f;
+                       float current = 0.0f;
+                       Type type = null;
+                       string name = null;
+                       int i = 0;
+                       foreach (string s in parts) {
+                               encoding = null;
+                               ParseValue (s, ref encoding, ref weight);
+                               if (encoding != null && weight > current && tbl.Contains (encoding)) {
+                                       type = tbl [encoding] as Type;
+                                       current = weight;
+                                       name = encoding;
+                               }
+                               i++;
+                       }
+
+                       if (type == null)
+                               return false;
+
+                       Stream filter = response.Filter;
+                       response.Filter = (Stream) Activator.CreateInstance (type, new object [] {filter});
+                       response.AppendHeader ("Content-Encoding", name);
+                       return true;
+               }
+
+               public void Clear ()
+               {
+                       tbl.Clear ();
+               }
+               
+               static void ParseValue (string s, ref string encoding, ref float weight)
+               {
+                       //FIXME: make it more spec compliant
+                       string [] parts = s.Trim ().Split (',');
+                       if (parts.Length == 1) {
+                               encoding = parts [0].Trim ();
+                               weight = 1.0f;
+                       } else if (parts.Length == 2) {
+                               encoding = parts [0].Trim ();
+                               try {
+                                       int i = parts [1].IndexOf ('=');
+                                       if (i != -1)
+                                               weight = Convert.ToSingle (parts [1].Substring (i + 1));
+                               } catch {
+                                       weight = 0.0f;
+                               }
+                       } else {
+                               //ignore
+                       }
+               }
+       }
+}
+
diff --git a/mcs/class/Mono.Http/Mono.Http/AcceptEncodingModule.cs b/mcs/class/Mono.Http/Mono.Http/AcceptEncodingModule.cs
new file mode 100644 (file)
index 0000000..a46e9b7
--- /dev/null
@@ -0,0 +1,46 @@
+//
+// AcceptEncodingModule.cs
+//
+// Authors:
+//     Gonzalo Paniagua Javier (gonzalo@ximian.com)
+//
+// (c) 2003 Ximian, Inc (http://www.ximian.com)
+//
+
+using System;
+using System.Configuration;
+using System.IO;
+using System.Web;
+
+namespace Mono.Http
+{
+       public class AcceptEncodingModule : IHttpModule
+       {
+               static readonly string configSection = "mono.aspnet/acceptEncoding";
+               AcceptEncodingConfig config;
+
+               public void Init (HttpApplication app)
+               {
+                       app.BeginRequest += new EventHandler (CheckIfAddFilter);
+               }
+
+               public void Dispose ()
+               {
+               }
+
+               void CheckIfAddFilter (object sender, EventArgs args)
+               {
+                       HttpApplication app = (HttpApplication) sender;
+                       HttpRequest request = app.Request;
+                       HttpResponse response = app.Response;
+
+                       //FIXME: fix this when config is cached
+                       if (config == null)
+                               //config = (AcceptEncodingConfig) app.Context.GetConfig (configSection);
+                               config = (AcceptEncodingConfig) ConfigurationSettings.GetConfig (configSection);
+
+                       config.SetFilter (response, request.Headers ["Accept-Encoding"]);
+               }
+       }
+}
+
diff --git a/mcs/class/Mono.Http/Mono.Http/AcceptEncodingSectionHandler.cs b/mcs/class/Mono.Http/Mono.Http/AcceptEncodingSectionHandler.cs
new file mode 100644 (file)
index 0000000..86e5dac
--- /dev/null
@@ -0,0 +1,96 @@
+//
+// AcceptEncodingSectionHandler.cs
+//
+// Authors:
+//     Gonzalo Paniagua Javier (gonzalo@ximian.com)
+//
+// (c) 2003 Ximian, Inc (http://www.ximian.com)
+//
+
+using System;
+using System.Configuration;
+using System.IO;
+using System.Xml;
+
+namespace Mono.Http
+{
+       public class AcceptEncodingSectionHandler : IConfigurationSectionHandler
+       {
+               public object Create (object parent, object configContext, XmlNode section)
+               {
+                       AcceptEncodingConfig cfg = new AcceptEncodingConfig (parent as AcceptEncodingConfig);
+                       
+                       if (section.Attributes != null && section.Attributes.Count != 0)
+                               ThrowException ("Unrecognized attribute", section);
+
+                       XmlNodeList nodes = section.ChildNodes;
+                       foreach (XmlNode child in nodes) {
+                               XmlNodeType ntype = child.NodeType;
+                               if (ntype == XmlNodeType.Whitespace || ntype == XmlNodeType.Comment)
+                                       continue;
+
+                               if (ntype != XmlNodeType.Element)
+                                       ThrowException ("Only elements allowed", child);
+                               
+                               string name = child.Name;
+                               if (name == "clear") {
+                                       if (child.Attributes != null && child.Attributes.Count != 0)
+                                               ThrowException ("Unrecognized attribute", child);
+
+                                       cfg.Clear ();
+                                       continue;
+                               }
+                                       
+                               if (name != "add")
+                                       ThrowException ("Unexpected element", child);
+
+                               string encoding = ExtractAttributeValue ("encoding", child, false);
+                               string type = ExtractAttributeValue ("type", child, false);
+                               string disabled = ExtractAttributeValue ("disabled", child, true);
+                               if (disabled != null && disabled == "yes")
+                                       continue;
+
+                               if (child.Attributes != null && child.Attributes.Count != 0)
+                                       ThrowException ("Unrecognized attribute", child);
+
+                               cfg.Add (encoding, type);
+                       }
+
+                       return cfg;
+               }
+
+               static void ThrowException (string msg, XmlNode node)
+               {
+                       if (node != null && node.Name != String.Empty)
+                               msg = msg + " (node name: " + node.Name + ") ";
+
+                       throw new ConfigurationException (msg, node);
+               }
+
+               static string ExtractAttributeValue (string attKey, XmlNode node, bool optional)
+               {
+                       if (node.Attributes == null) {
+                               if (optional)
+                                       return null;
+
+                               ThrowException ("Required attribute not found: " + attKey, node);
+                       }
+
+                       XmlNode att = node.Attributes.RemoveNamedItem (attKey);
+                       if (att == null) {
+                               if (optional)
+                                       return null;
+                               ThrowException ("Required attribute not found: " + attKey, node);
+                       }
+
+                       string value = att.Value;
+                       if (value == String.Empty) {
+                               string opt = optional ? "Optional" : "Required";
+                               ThrowException (opt + " attribute is empty: " + attKey, node);
+                       }
+
+                       return value;
+               }
+       }
+}
+
diff --git a/mcs/class/Mono.Http/Mono.Http/ChangeLog b/mcs/class/Mono.Http/Mono.Http/ChangeLog
new file mode 100644 (file)
index 0000000..217619b
--- /dev/null
@@ -0,0 +1,4 @@
+2003-07-24  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       Initial check-in.
+
diff --git a/mcs/class/Mono.Http/Mono.Http/GZipWriteFilter.cs b/mcs/class/Mono.Http/Mono.Http/GZipWriteFilter.cs
new file mode 100644 (file)
index 0000000..8231e5b
--- /dev/null
@@ -0,0 +1,91 @@
+//
+// GZipFilter.cs
+//
+// Authors:
+//     Gonzalo Paniagua Javier (gonzalo@ximian.com)
+//
+// (c) 2003 Ximian, Inc (http://www.ximian.com)
+//
+
+using System;
+using System.IO;
+using ICSharpCode.SharpZipLib.GZip;
+
+namespace Mono.Http
+{
+       public class GZipWriteFilter : Stream
+       {
+               Stream baseStream;
+               GZipOutputStream st;
+
+               public GZipWriteFilter (Stream baseStream)
+               {
+                       // baseStream is not ready yet for filtering and any attemp to write
+                       // the gzip header will throw.
+                       this.baseStream = baseStream;
+               }
+
+               public override bool CanRead {
+                       get { return false; }
+               }
+
+               public override bool CanSeek {
+                        get { return false; }
+                }
+
+                public override bool CanWrite {
+                        get {
+                               if (st == null)
+                                       return false;
+
+                               return st.CanWrite;
+                       }
+                }
+
+               public override long Length {
+                       get { return 0; }
+               }
+
+               public override long Position {
+                       get { return 0; }
+                       set { }
+               }
+
+               public override void Flush ()
+               {
+               }
+
+               public override int Read (byte [] buffer, int offset, int count)
+               {
+                       return 0;
+               }
+
+               public override long Seek (long offset, SeekOrigin origin)
+               {
+                       return 0;
+               }
+
+               public override void SetLength (long value)
+               {
+               }
+
+               public override void Write (byte [] buffer, int offset, int count)
+               {
+                       if (st == null)
+                               st = new GZipOutputStream (baseStream);
+
+                       st.Write (buffer, offset, count);
+               }
+
+               public override void Close ()
+               {
+                       if (st == null)
+                               return;
+                               
+                       st.Finish ();
+                       st = null;
+                       base.Close ();
+               }
+       }
+}
+
diff --git a/mcs/class/Mono.Http/NEWS b/mcs/class/Mono.Http/NEWS
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/mcs/class/Mono.Http/README b/mcs/class/Mono.Http/README
new file mode 100644 (file)
index 0000000..90c36b3
--- /dev/null
@@ -0,0 +1,10 @@
+Mono.Http assembly
+--------------------
+This assembly holds a number of classes that provide additional features to
+existing Http protocol related ones, such as support for gzip compression of
+pages when hosting ASP.NET pages (xsp uses it) and others.
+
+Watch out the NEWS file.
+
+-Gonzalo
+