CookieContainer的SetCookie方法抛出异常

时间:2012-06-17 05:28:55

标签: c# .net wordpress httpwebrequest webrequest

我在Set-Cookie标题中从Web服务器返回了这个cookie:

  

PHPSESSID = 462rutd8g0sbg9sinh3hqa2ol6;   路径= /,wordpress_test_cookie = WP +曲奇+检查;   路径= /,wordpress_ca07030412dd7fcd4dbeaae0bd9f5df9=testemail@example.com;   expires = Sun,01-Jul-2012 05:11:02 GMT;路径= /可湿性粉剂内容/插件;   仅Http,wordpress_ca07030412dd7fcd4dbeaae0bd9f5df9 = testemail子@ example.com;   expires = Sun,01-Jul-2012 05:11:02 GMT;路径= /可湿性粉剂管理员;   仅Http,wordpress_logged_in_ca07030412dd7fcd4dbeaae0bd9f5df9 = testemail子@ example.com;   expires = Sun,01-Jul-2012 05:11:02 GMT;路径= /;仅Http

我正在尝试使用CookieContainer.SetCookies(new Uri(url),cookie);

但它会引发异常' {"解析Uri' http://www.smallbizads.us/的Cookie标头时出错。'} System.FormatException {System .Net.CookieException'

一些挖掘揭示了SetCookies使用,来分解cookie。但这显然不会起作用,因为我的Expires标题也有,

知道如何解决这个问题?

注意:由于Wordpress问题,我只能通过从Set-Cookie标题中提取Cookie来使用此方法。所以请不要提出任何其他选择。

2 个答案:

答案 0 :(得分:2)

我花了一段时间来解剖它。

据我所知,您希望为多个路径设置WordPress为一个域(.smallbizads.us)生成的PHPSESSID(PHP会话ID)。到期日期始终相同。

首先你拿走你的cookie标题:

string cookieHeader = "PHPSESSID=462rutd8g0sbg9sinh3hqa2ol6; ...etc;"

将它拆分为';'分隔符。

var cookies = cookieHeader.Split(new[] {';'}).ToList();

最后列出了12个项目。例如:

  • “PHPSESSID = 462rutd8g0sbg9sinh3hqa2ol6”
  • “path = /,wordpress_test_cookie = WP + Cookie + check”
  • “expires = Sun,01-Jul-2012 05:11:02 GMT”
  • ...

到期日期在此列表中多次显示,但始终具有相同的值。 只需获取第一个到期日期并将其转换为DateTime。

var expiresValue = (from c in cookies
                    where c.Trim().StartsWith("expires")
                    select c).First();
var expiresOn = DateTime.Parse(expiresValue.Substring(expiresValue.IndexOf('=') + 1));

好的,现在让我们获取cookie的值。会话ID:

var sessionId = (from c in cookies
                 where c.Trim().StartsWith("PHPSESSID")
                 select c).Single();
sessionId = sessionId.Substring(sessionId.IndexOf('=') + 1);

现在获取您需要设置cookie的路径。

var paths = (from c in cookies
             where c.Trim().StartsWith("path=")
             select c).ToList();

现在,您可以使用CookieContainer和System.Net.Cookie类设置Cookie。

foreach (var path in paths)
{
    var cookie = new Cookie();
    cookie.Name = "PHPSESSID";
    cookie.Value = sessionId;
    cookie.Domain = ".smallbizads.us";
    cookie.Expires = expiresOn;
    cookie.HttpOnly = true;

    var container = new CookieContainer();

    var startIndex = path.IndexOf('=') + 1;
    var stopIndex = path.Contains(',') ? path.IndexOf(',') : path.Length;
    cookie.Path = path.Substring(startIndex, stopIndex - startIndex);

    container.Add(cookie);
}

答案 1 :(得分:0)

注意到星期几没有添加其他信息,并且可以在没有它的情况下解析日期,我们可以使用正则表达式来删除日期和逗号。这是一种用于代替CookieContainer.SetCookies()的扩展方法。

/// <summary>
/// Although it's invalid, in the wild we sometimes see a Set-Cookie header with the form "Name=Value; expires=Sun, 23-Dec-2012 12:25:37 GMT".
/// Multiple cookies can be set with one header, comma separated, so CookieContainer.SetCookies() can't parse this due to the comma in the date.
/// Fortunately, the DayOfWeek provides no useful information, and the date can be parsed without it, so this removes the day and comma.
/// </summary>
public static void SetCookiesWithExpires(this CookieContainer cookies, Uri uri, String cookieHeader) {
    // Note: The Regex may be created more than once in different threads. No problem; all but the last will be garbage collected.
    Regex expiresEqualsDay = _expiresEqualsDay ?? (_expiresEqualsDay = new Regex(EXPIRES_EQUALS_DAY_PATTERN, RegexOptions.IgnoreCase | RegexOptions.Compiled));
    cookies.SetCookies(uri, expiresEqualsDay.Replace(cookieHeader, EXPIRES_EQUALS));
}
private static Regex _expiresEqualsDay;     // Lazy-initialized.
private const String EXPIRES_EQUALS_DAY_PATTERN = "; *expires=[A-Za-z]+, *";
private const String EXPIRES_EQUALS = "; Expires=";