Merge pull request #2087 from joelmartinez/mdoc-membername-fixup
[mono.git] / mcs / class / System.Web / System.Web / HttpCookie.cs
index c121772be1b1ff510550e4645140f8a256fd62e5..2b4e68cf8ed8d8ad018ea72686d0fa9134cabaa0 100644 (file)
@@ -1,10 +1,12 @@
-// 
-// System.Web.HttpCookie
+//
+// System.Web.HttpCookie.cs 
 //
 // Author:
-//   Patrik Torstensson (Patrik.Torstensson@labs2.com)
+//     Chris Toshok (toshok@novell.com)
 //
 
+//
+// Copyright (C) 2005-2009 Novell, Inc (http://www.novell.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
-using System;
-using System.Globalization;
+
 using System.Text;
-using System.Web;
 using System.Collections.Specialized;
+using System.Security.Permissions;
 
 namespace System.Web
 {
-       public sealed class HttpCookie
-       {
-               string _Name;
-               string _Value;
-               string _Domain;
-               DateTime _Expires;
-               bool _ExpiresSet;
-               string _Path;  
-               bool _Secure = false;
-
-               HttpValueCollection _Values;
-
-               internal HttpCookie ()
+       [Flags]
+       internal enum CookieFlags : byte {
+               Secure = 1,
+                       HttpOnly = 2
+                       }
+       
+       // CAS - no InheritanceDemand here as the class is sealed
+       [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
+       public sealed class HttpCookie {
+
+               string path = "/";
+               string domain;
+               DateTime expires = DateTime.MinValue;
+               string name;
+               CookieFlags flags = 0;
+               NameValueCollection values;
+
+               [Obsolete]
+               internal HttpCookie (string name, string value, string path, DateTime expires)
                {
-                       _Path = "/";
+                       this.name = name;
+                       this.values = new CookieNVC();
+                       this.Value = value;
+                       this.path = path;
+                       this.expires = expires;
                }
 
                public HttpCookie (string name)
                {
-                       _Path = "/";
-                       _Name = name;
+                       this.name = name;
+                       values = new CookieNVC();
+                       Value = "";
                }
 
                public HttpCookie (string name, string value)
+               : this (name)
                {
-                       _Name = name;
-                       _Value = value;
-                       _Path = "/";
+                       Value = value;
                }
 
-               internal HttpCookie (string name, string value, string path, DateTime expires)
+               internal string GetCookieHeaderValue ()
                {
-                       _Name = name;
-                       _Value = value;
-                       _Path = path;
-                       if (expires != DateTime.MinValue)
-                               Expires = expires;
-               }
-               
-               internal HttpResponseHeader GetCookieHeader ()
-               {
-                       StringBuilder oSetCookie = new StringBuilder ();
+                       StringBuilder builder = new StringBuilder ();
 
-                       if (null != _Name && _Name.Length > 0) {
-                               oSetCookie.Append (_Name);
-                               oSetCookie.Append ("=");
-                       }
+                       builder.Append (name);
+                       builder.Append ("=");
+                       builder.Append (Value);
 
-                       if (null != _Values) {
-                               oSetCookie.Append (_Values.ToString (false));
-                       } else if (null != _Value) {
-                               oSetCookie.Append (_Value);
+                       if (domain != null) {
+                               builder.Append ("; domain=");
+                               builder.Append (domain);
                        }
-
-                       if (null != _Domain && _Domain.Length > 0) {
-                               oSetCookie.Append ("; domain=");
-                               oSetCookie.Append (_Domain);
+              
+                       if (path != null) {
+                               builder.Append ("; path=");
+                               builder.Append (path);
                        }
 
-                       if (null != _Path && Path.Length > 0) {
-                               oSetCookie.Append ("; path=");
-                               oSetCookie.Append (_Path);
+                       if (expires != DateTime.MinValue) {
+                               builder.Append ("; expires=");
+                               builder.Append (expires.ToUniversalTime().ToString("r"));
                        }
 
-                       if (_ExpiresSet && _Expires != DateTime.MinValue) {
-                               oSetCookie.Append ("; expires=");
-                               DateTime ut = _Expires.ToUniversalTime ();
-                               oSetCookie.Append (ut.ToString ("ddd, dd-MMM-yyyy HH':'mm':'ss 'GMT'",
-                                                               DateTimeFormatInfo.InvariantInfo));
+                       if ((flags & CookieFlags.Secure) != 0) {
+                               builder.Append ("; secure");
                        }
 
-                       if (_Secure)
-                               oSetCookie.Append ("; secure");
+                       if ((flags & CookieFlags.HttpOnly) != 0){
+                               builder.Append ("; HttpOnly");
+                       }
 
-                       return new HttpResponseHeader (HttpWorkerRequest.HeaderSetCookie, oSetCookie.ToString());
+                       return builder.ToString ();
                }
 
-               public string Domain
-               {
-                       get { return _Domain; }
-                       set { _Domain = value; }
+               public string Domain {
+                       get {
+                               return domain;
+                       }
+                       set {
+                               domain = value;
+                       }
                }
 
-               public DateTime Expires
-               {
+               public DateTime Expires {
                        get {
-                               if (!_ExpiresSet)
-                                       return DateTime.MinValue;
+                               return expires;
+                       }
+                       set {
+                               expires = value;
+                       }
+               }
 
-                               return _Expires;
+               public bool HasKeys {
+                       get {
+                               return values.HasKeys();
                        }
+               }
+
 
+               public string this [ string key ] {
+                       get {
+                               return values [ key ];
+                       }
                        set {
-                               _ExpiresSet = true;
-                               _Expires = value;
+                               values [ key ] = value;
                        }
                }
 
-               public bool HasKeys
-               {
+               public string Name {
                        get {
-                               return Values.HasKeys ();
+                               return name;
+                       }
+                       set {
+                               name = value;
                        }
                }
 
-               public string this [string key]
-               {
-                       get { return Values [key]; }
-                       set { Values [key] = value; }
+               public string Path {
+                       get {
+                               return path;
+                       }
+                       set {
+                               path = value;
+                       }
                }
 
-               public string Name
-               {
-                       get { return _Name; }
-                       set { _Name = value; }
+               public bool Secure {
+                       get {
+                               return (flags & CookieFlags.Secure) == CookieFlags.Secure;
+                       }
+                       set {
+                               if (value)
+                                       flags |= CookieFlags.Secure;
+                               else
+                                       flags &= ~CookieFlags.Secure;
+                       }
                }
 
-               public string Path
-               {
-                       get { return _Path; }
-                       set { _Path = value; }
+               public string Value {
+                       get {
+                               return HttpUtility.UrlDecode(values.ToString ());
+                       }
+                       set {
+                               values.Clear ();
+                               
+                               if (value != null && value != "") {
+                                       string [] components = value.Split ('&');
+                                       foreach (string kv in components){
+                                               int pos = kv.IndexOf ('=');
+                                               if (pos == -1){
+                                                       values.Add (null, kv);
+                                               } else {
+                                                       string key = kv.Substring (0, pos);
+                                                       string val = kv.Substring (pos+1);
+                                                       
+                                                       values.Add (key, val);
+                                               }
+                                       }
+                               }
+                       }
                }
 
-               public bool Secure
-               {
-                       get { return _Secure; }
-                       set { _Secure = value; }
+               public NameValueCollection Values {
+                       get {
+                               return values;
+                       }
                }
 
-               public string Value
-               {
+               public bool HttpOnly {
                        get {
-                               if (null != _Values)
-                                       return _Values.ToString (false);
-
-                               return _Value;
+                               return (flags & CookieFlags.HttpOnly) == CookieFlags.HttpOnly;
                        }
 
                        set {
-                               if (null != _Values) {
-                                       _Values.Reset ();
-                                       _Values.Add (null, value);
-                                       return;
-                               }
-
-                               _Value = value;
+                               if (value)
+                                       flags |= CookieFlags.HttpOnly;
+                               else
+                                       flags &= ~CookieFlags.HttpOnly;
                        }
                }
 
-               public NameValueCollection Values
+               /*
+                * simple utility class that just overrides ToString
+                * to get the desired behavior for
+                * HttpCookie.Values
+                */
+               [Serializable]
+               sealed class CookieNVC : NameValueCollection
                {
-                       get {
-                               if (null == _Values) {
-                                       _Values = new HttpValueCollection ();
-                                       if (null != _Value) {
-                                               // Do we have multiple keys
-                                               if (_Value.IndexOf ("&") >= 0 || _Value.IndexOf ("=") >= 0) {
-                                                       _Values.FillFromCookieString (_Value);
-                                               } else {
-                                                       _Values.Add (null, _Value);
-                                               }
+                       public CookieNVC ()
+                               : base (StringComparer.OrdinalIgnoreCase)
+                       {
+                       }
+
+                       public override string ToString ()
+                       {
+                               StringBuilder builder = new StringBuilder ("");
 
-                                               _Value = null;
+                               bool first_key = true;
+                               foreach (string key in Keys) {
+                                       if (!first_key)
+                                               builder.Append ("&");
+
+                                       string[] vals = GetValues (key);
+                                       if(vals == null)
+                                               vals = new string[1] {String.Empty};
+
+                                      bool first_val = true;
+                                       foreach (string v in vals) {
+                                              if (!first_val)
+                                                      builder.Append ("&");
+                                              
+                                              if (key != null && key.Length > 0) {
+                                                       builder.Append (HttpUtility.UrlEncode(key));
+                                                      builder.Append ("=");
+                                              }
+                                               if(v != null && v.Length > 0)
+                                                       builder.Append (HttpUtility.UrlEncode(v));
+                                              
+                                              first_val = false;
                                        }
+                                       first_key = false;
+                               }
+
+                               return builder.ToString();
+                       }
+
+                       /* MS's implementation has the interesting quirk that if you do:
+                        * cookie.Values[null] = "foo"
+                        * it clears out the rest of the values.
+                        */
+                       public override void Set (string name, string value)
+                       {
+                               if (this.IsReadOnly)
+                                       throw new NotSupportedException ("Collection is read-only");
+
+                               if (name == null) {
+                                       Clear();
+                                       name = string.Empty;
                                }
+//                             if (value == null)
+//                                     value = string.Empty;
 
-                               return _Values;
+                               base.Set (name, value);
                        }
                }
        }
 }
-