[System]: WebRequest.GetSystemProxy(): Return custom proxy for monodroid.
[mono.git] / mcs / class / System / System.Net / Cookie.cs
index dcc56400a75b9ae4057a554af34c40006557b964..b5abe6e097d77499c4f73fb2a95bcf0a7d477d20 100644 (file)
@@ -4,8 +4,10 @@
 // Authors:
 //     Lawrence Pit (loz@cable.a2000.nl)
 //     Gonzalo Paniagua Javier (gonzalo@ximian.com)
+//      Daniel Nauck    (dna(at)mono-project(dot)de)
+//     Sebastien Pouliot  <sebastien@ximian.com>
 //
-// (c) Copyright 2004 Novell, Inc. (http://www.ximian.com)
+// Copyright (C) 2004,2009 Novell, Inc (http://www.novell.com)
 //
 
 //
@@ -32,6 +34,7 @@
 using System;
 using System.Text;
 using System.Globalization;
+using System.Collections;
 
 namespace System.Net {
 
@@ -46,8 +49,8 @@ namespace System.Net {
                Uri commentUri;
                bool discard;
                string domain;
-               bool expired;
                DateTime expires;
+               bool httpOnly;
                string name;
                string path;
                string port;
@@ -65,12 +68,11 @@ namespace System.Net {
                {
                        expires = DateTime.MinValue;
                        timestamp = DateTime.Now;
-                       domain = "";
-                       name = "";
-                       val = "";
-                       comment = "";
-                       domain = "";
-                       port = "";
+                       domain = String.Empty;
+                       name = String.Empty;
+                       val = String.Empty;
+                       comment = String.Empty;
+                       port = String.Empty;
                }
 
                public Cookie (string name, string value)
@@ -109,7 +111,30 @@ namespace System.Net {
 
                public string Domain {
                        get { return domain; }
-                       set { domain = value == null ? String.Empty : value; }
+                       set {
+                               if (String.IsNullOrEmpty (value)) {
+                                       domain = String.Empty;
+                                       HasDomain = false;
+                               } else {
+                                       domain = value;
+                                       IPAddress test;
+                                       if (IPAddress.TryParse (value, out test))
+                                               HasDomain = false;
+                                       else
+                                               HasDomain = true;
+                               }
+                       }
+               }
+
+               /*
+                * Set this to false to disable same-origin checks.
+                * 
+                * This should be done whenever the cookie does not actually
+                * contain a domain and we fallback to the Uri's hostname.
+                * 
+                */
+               internal bool HasDomain {
+                       get; set;
                }
 
                public bool Expired {
@@ -117,11 +142,9 @@ namespace System.Net {
                                return expires <= DateTime.Now && 
                                       expires != DateTime.MinValue;
                        }
-                       set { 
-                               expired = value; 
-                               if (expired) {
+                       set {  
+                               if (value)
                                        expires = DateTime.Now;
-                               }
                        }
                }
 
@@ -130,12 +153,16 @@ namespace System.Net {
                        set { expires = value; }
                }
 
+               public bool HttpOnly {
+                       get { return httpOnly; }
+                       set { httpOnly = value; }
+               }
+
                public string Name {
                        get { return name; }
                        set { 
-                               if (value == null || value.Length == 0) {
+                               if (String.IsNullOrEmpty (value))
                                        throw new CookieException ("Name cannot be empty");
-                               }                       
                                
                                if (value [0] == '$' || value.IndexOfAny (reservedCharsName) != -1) {
                                        // see CookieTest, according to MS implementation
@@ -149,14 +176,14 @@ namespace System.Net {
                }
 
                public string Path {
-                       get { return (path == null || path == "") ? "/" : path; }
+                       get { return (path == null) ? String.Empty : path; }
                        set { path = (value == null) ? String.Empty : value; }
                }
 
                public string Port {
                        get { return port; }
                        set { 
-                               if (value == null || value.Length == 0) {
+                               if (String.IsNullOrEmpty (value)) {
                                        port = String.Empty;
                                        return;
                                }
@@ -176,11 +203,13 @@ namespace System.Net {
                                                throw new CookieException("The 'Port'='" + value + "' part of the cookie is invalid. Invalid value: " + values [i], e);
                                        }
                                }
+                               Version = 1;
                        }
                }
 
                internal int [] Ports {
                        get { return ports; }
+                       set { ports = value; }
                }
 
                public bool Secure {
@@ -222,24 +251,24 @@ namespace System.Net {
                        }
                }
 
-               public override bool Equals (Object obj
+               public override bool Equals (Object comparand
                {
-                       System.Net.Cookie c = obj as System.Net.Cookie;                 
+                       System.Net.Cookie c = comparand as System.Net.Cookie;                   
                        
                        return c != null &&
                               String.Compare (this.name, c.name, true, CultureInfo.InvariantCulture) == 0 &&
                               String.Compare (this.val, c.val, false, CultureInfo.InvariantCulture) == 0 &&
-                              String.Compare (this.path, c.path, false, CultureInfo.InvariantCulture) == 0 &&
+                              String.Compare (this.Path, c.Path, false, CultureInfo.InvariantCulture) == 0 &&
                               String.Compare (this.domain, c.domain, true, CultureInfo.InvariantCulture) == 0 &&
                               this.version == c.version;
                }
 
                public override int GetHashCode ()
                {
-                       return hash(name.ToLower ().GetHashCode (),
+                       return hash(CaseInsensitiveHashCodeProvider.DefaultInvariant.GetHashCode(name),
                                    val.GetHashCode (),
-                                   path.GetHashCode (),
-                                   domain.ToLower ().GetHashCode (),
+                                   Path.GetHashCode (),
+                                   CaseInsensitiveHashCodeProvider.DefaultInvariant.GetHashCode (domain),
                                    version);
                }
 
@@ -250,30 +279,61 @@ namespace System.Net {
 
                // returns a string that can be used to send a cookie to an Origin Server
                // i.e., only used for clients
-               // see also para 3.3.4 of RFC 1965
+               // see para 4.2.2 of RFC 2109 and para 3.3.4 of RFC 2965
+               // see also bug #316017
                public override string ToString () 
+               {
+                       return ToString (null);
+               }
+
+               internal string ToString (Uri uri)
+               {
+                       if (name.Length == 0) 
+                               return String.Empty;
+
+                       StringBuilder result = new StringBuilder (64);
+       
+                       if (version > 0)
+                               result.Append ("$Version=").Append (version).Append ("; ");             
+                               
+                       result.Append (name).Append ("=").Append (val);
+                       
+                       if (version == 0)
+                               return result.ToString ();
+
+                       if (!String.IsNullOrEmpty (path))
+                               result.Append ("; $Path=").Append (path);
+
+                       bool append_domain = (uri == null) || (uri.Host != domain);
+                       if (append_domain && !String.IsNullOrEmpty (domain))
+                               result.Append ("; $Domain=").Append (domain);                   
+       
+                       if (port != null && port.Length != 0)
+                               result.Append ("; $Port=").Append (port);       
+                                               
+                       return result.ToString ();
+               }
+
+               internal string ToClientString () 
                {
                        if (name.Length == 0) 
                                return String.Empty;
 
                        StringBuilder result = new StringBuilder (64);
        
-                       if (version > 0) {
-                               result.Append ("$Version=").Append (version).Append (";");
-                       }                               
+                       if (version > 0) 
+                               result.Append ("Version=").Append (version).Append (";");
                                
                        result.Append (name).Append ("=").Append (val);
 
-                       // in the MS.Net implementation path and domain don't show up in
-                       // the result, I guess that's a bug in their implementation...
                        if (path != null && path.Length != 0)
-                               result.Append (";$Path=").Append (QuotedString (path));
+                               result.Append (";Path=").Append (QuotedString (path));
                                
                        if (domain != null && domain.Length != 0)
-                               result.Append (";$Domain=").Append (QuotedString (domain));                     
+                               result.Append (";Domain=").Append (QuotedString (domain));                      
        
                        if (port != null && port.Length != 0)
-                               result.Append (";$Port=").Append (port);        
+                               result.Append (";Port=").Append (port); 
                                                
                        return result.ToString ();
                }