Explorar o código

In Test/System.Net:
2010-01-21 Sebastien Pouliot <[email protected]>

* CookieContainerTest.cs: Additional test cases from Tom Philpot

In System.Net:
2010-01-21 Sebastien Pouliot <[email protected]>

* CookieContainer.cs: Fix to cloning and expiration. Patch
by Tom Philpot <[email protected]>


svn path=/trunk/mcs/; revision=149976

Sebastien Pouliot %!s(int64=16) %!d(string=hai) anos
pai
achega
1cc8e885d5

+ 5 - 0
mcs/class/System/System.Net/ChangeLog

@@ -1,3 +1,8 @@
+2010-01-21  Sebastien Pouliot  <[email protected]>
+
+	* CookieContainer.cs: Fix to cloning and expiration. Patch
+	by Tom Philpot <[email protected]>
+
 2010-01-13 Gonzalo Paniagua Javier <[email protected]>
 
 	* HttpWebRequest.cs: when the server returns several different

+ 47 - 4
mcs/class/System/System.Net/CookieContainer.cs

@@ -36,6 +36,7 @@ using System.Collections;
 using System.Globalization;
 using System.Runtime.Serialization;
 using System.Text;
+using System.Text.RegularExpressions;
 
 namespace System.Net 
 {
@@ -146,7 +147,16 @@ namespace System.Net
 			if (cookie.Value.Length > maxCookieSize)
 				throw new CookieException ("value is larger than MaxCookieSize.");
 
-			AddCookie (cookie);
+			// .NET's Add (Cookie) is fundamentally broken and does not copy properties
+			// like Secure, HttpOnly and Expires so we clone the parts that .NET
+			// does keep before calling AddCookie
+			Cookie c = new Cookie (cookie.Name, cookie.Value);
+			c.Path = (cookie.Path.Length == 0) ? "/" : cookie.Path;
+			c.Domain = cookie.Domain;
+			c.ExactDomain = cookie.ExactDomain;
+			c.Version = cookie.Version;
+			
+			AddCookie (c);
 		}
 
 		void AddCookie (Cookie cookie)
@@ -169,6 +179,12 @@ namespace System.Net
 			c.Domain = cookie.Domain;
 			c.ExactDomain = cookie.ExactDomain;
 			c.Version = cookie.Version;
+			c.Expires = cookie.Expires;
+			c.CommentUri = cookie.CommentUri;
+			c.Comment = cookie.Comment;
+			c.Discard = cookie.Discard;
+			c.HttpOnly = cookie.HttpOnly;
+			c.Secure = cookie.Secure;
 
 			cookies.Add (c);
 			CheckExpiration ();
@@ -373,10 +389,25 @@ namespace System.Net
 				return;
 			
 			// Cookies must be separated by ',' (like documented on MSDN)
+			// but expires uses DAY, DD-MMM-YYYY HH:MM:SS GMT, so simple ',' search is wrong.
+			// See http://msdn.microsoft.com/en-us/library/aa384321%28VS.85%29.aspx
 			string [] jar = cookieHeader.Split (',');
-			foreach (string cookie in jar) {
+			string tmpCookie;
+			for (int i = 0; i < jar.Length; i++) {
+				tmpCookie = jar [i];
+
+				if (jar.Length > i + 1
+					&& Regex.IsMatch (jar[i],
+						@".*expires\s*=\s*(Mon|Tue|Wed|Thu|Fri|Sat|Sun)",
+						RegexOptions.IgnoreCase) 
+					&& Regex.IsMatch (jar[i+1],
+						@"\s\d{2}-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-\d{4} \d{2}:\d{2}:\d{2} GMT",
+						RegexOptions.IgnoreCase)) {
+					tmpCookie = new StringBuilder (tmpCookie).Append (",").Append (jar [++i]).ToString ();
+				}
+
 				try {
-					Cookie c = Parse (cookie);
+					Cookie c = Parse (tmpCookie);
 
 					// add default values from URI if missing from the string
 					if (c.Path.Length == 0) {
@@ -392,7 +423,7 @@ namespace System.Net
 						c.ExactDomain = true;
 					}
 
-					Add (c);
+					AddCookie (c);
 				}
 				catch (Exception e) {
 					string msg = String.Format ("Could not parse cookies for '{0}'.", uri);
@@ -430,6 +461,18 @@ namespace System.Net
 						c.ExactDomain = false;
 					}
 					break;
+				case "expires":
+				case "$expires":
+					if (c.Expires == DateTime.MinValue)
+						c.Expires = DateTime.SpecifyKind (DateTime.ParseExact (value,
+							@"ddd, dd-MMM-yyyy HH:mm:ss G\MT", CultureInfo.InvariantCulture), DateTimeKind.Utc);
+						break;
+				case "httponly":
+					c.HttpOnly = true;
+					break;
+				case "secure":
+					c.Secure = true;
+					break;
 				default:
 					if (c.Name.Length == 0) {
 						c.Name = key;

+ 4 - 0
mcs/class/System/Test/System.Net/ChangeLog

@@ -1,3 +1,7 @@
+2010-01-21  Sebastien Pouliot  <[email protected]>
+
+	* CookieContainerTest.cs: Additional test cases from Tom Philpot
+
 2010-01-15  Jonathan Pobst  <[email protected]>
 
 	* HttpWebRequestTest.cs: Mark test WriteServerAborts as

+ 67 - 0
mcs/class/System/Test/System.Net/CookieContainerTest.cs

@@ -1566,5 +1566,72 @@ namespace MonoTests.System.Net {
 			Assert.AreEqual (CookieContainer.DefaultCookieLimit, cc.Count, "Count");
 			// so one (yes '1' ;-) was removed
 		}
+
+		[Test]
+		public void SaveAndLoadViaAddUriCookie ()
+		{
+			Cookie cookie = new Cookie ("name", "value")
+			{
+				Domain = ".example.com",
+				Expires = new DateTime (2015, 1, 1, 0, 0, 0, DateTimeKind.Utc),
+				HttpOnly = true,
+				Secure = true,
+			};
+
+			Uri uri = new Uri ("https://www.example.com/path/file");
+			CookieContainer container = new CookieContainer ();
+			container.Add (uri, cookie);
+			CookieCollection collection = container.GetCookies (uri);
+			Assert.AreEqual (collection.Count, 1, "#A1");
+			Cookie cloned = collection [0];
+			
+			Assert.AreEqual (cookie.Comment, cloned.Comment, "#A2");
+			Assert.AreEqual (cookie.CommentUri, cloned.CommentUri, "#A3");
+			Assert.AreEqual (cookie.Domain, cloned.Domain, "#A4");
+			Assert.AreEqual (cookie.Discard, cloned.Discard, "#A5");
+			Assert.AreEqual (cookie.Expired, cloned.Expired, "#A6");
+			Assert.AreEqual (cookie.Expires.ToUniversalTime (), cloned.Expires.ToUniversalTime (), "#A7");
+			Assert.AreEqual (cookie.HttpOnly, cloned.HttpOnly, "#A8");
+			Assert.AreEqual (cookie.Name, cloned.Name, "#A9");
+			Assert.AreEqual (cookie.Path, cloned.Path, "#A10");
+			Assert.AreEqual (cookie.Port, cloned.Port, "#A11");
+			Assert.AreEqual (cookie.Value, cloned.Value, "#A12");
+			Assert.AreEqual (cookie.Version, cloned.Version, "#A13");
+			Assert.AreEqual (cookie.Secure, cloned.Secure, "#A14");
+		}
+
+		[Test]
+		public void SaveAndLoadViaSetCookies ()
+		{
+			Cookie cookie = new Cookie ("name", "value")
+			{
+				Domain = ".example.com",
+				Expires = new DateTime (2015, 1, 1, 0, 0, 0, DateTimeKind.Utc),
+				HttpOnly = true,
+				Secure = true,
+			};
+
+			Uri uri = new Uri ("https://www.example.com/path/file");
+			CookieContainer container = new CookieContainer ();
+			container.SetCookies (uri, "name=value; domain=.example.com; expires=Thu, 01-Jan-2015 00:00:00 GMT; HttpOnly; secure");
+			CookieCollection collection = container.GetCookies (uri);
+			Assert.AreEqual (collection.Count, 1, "#A1");
+			Cookie cloned = collection [0];
+			
+			Assert.AreEqual (cookie.Comment, cloned.Comment, "#A2");
+			Assert.AreEqual (cookie.CommentUri, cloned.CommentUri, "#A3");
+			Assert.AreEqual (cookie.Domain, cloned.Domain, "#A4");
+			Assert.AreEqual (cookie.Discard, cloned.Discard, "#A5");
+			Assert.AreEqual (cookie.Expired, cloned.Expired, "#A6");
+			Assert.AreEqual (cookie.Expires.ToUniversalTime (), cloned.Expires.ToUniversalTime (), "#A7");
+			Assert.AreEqual (cookie.HttpOnly, cloned.HttpOnly, "#A8");
+			Assert.AreEqual (cookie.Name, cloned.Name, "#A9");
+			Assert.AreEqual (cookie.Path, "", "#A10");
+			Assert.AreEqual (cloned.Path, "/path/file", "#A11");
+			Assert.AreEqual (cookie.Port, cloned.Port, "#A12");
+			Assert.AreEqual (cookie.Value, cloned.Value, "#A13");
+			Assert.AreEqual (cookie.Version, cloned.Version, "#A14");
+			Assert.AreEqual (cookie.Secure, cloned.Secure, "#A15");
+		}
 	}
 }