[Mono-dev] Patch for CookieContainer.SetCookies
Sebastien Pouliot
sebastien.pouliot at gmail.com
Wed Jan 20 16:58:02 EST 2010
Hello again,
Sorry I hit send adding my comments on the patch itself.
> Index: mcs/class/System/System.Net/CookieContainer.cs
> ===================================================================
> --- mcs/class/System/System.Net/CookieContainer.cs (revision 149764)
> +++ mcs/class/System/System.Net/CookieContainer.cs (working copy)
> @@ -36,6 +36,7 @@
> using System.Globalization;
> using System.Runtime.Serialization;
> using System.Text;
> +using System.Text.RegularExpressions;
>
> namespace System.Net
> {
> @@ -53,7 +54,7 @@
> int perDomainCapacity = DefaultPerDomainCookieLimit;
> int maxCookieSize = DefaultCookieLengthLimit;
> CookieCollection cookies;
> -
> +
> // ctors
> public CookieContainer ()
> {
> @@ -146,7 +147,16 @@
> 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,16 @@
> 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 = c.Discard;
^ that's unlikely to be correct ;-)
> + if (cookie.HttpOnly) {
> + c.HttpOnly = true;
> + }
> + if (cookie.Secure) {
> + c.Secure = true;
> + }
why not simply
c.HttpOnly = cookie.HttpOnly;
c.Secure = cookie.Secure;
?
if there's a problem with this simpler code then it does not get caught
by your new unit tests.
>
> cookies.Add (c);
> CheckExpiration ();
> @@ -373,10 +393,21 @@
> return;
>
> // Cookies must be separated by ',' (like documented on MSDN)
> - string [] jar = cookieHeader.Split (',');
> - foreach (string cookie in jar) {
> + // 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(',');
> + 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 @@
> c.ExactDomain = true;
> }
>
> - Add (c);
> + AddCookie (c);
> }
> catch (Exception e) {
> string msg = String.Format ("Could not parse cookies for '{0}'.", uri);
> @@ -430,6 +461,17 @@
> 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;
Your additional unit tests do not cover the "secure" case above (i.e.
please add test for all new code).
I suspect the "expires" case is the buggy one wrt your unit test
(previous email).
Sebastien
More information about the Mono-devel-list
mailing list