2012-06-17 167 views
1

我得到這個cookie從網絡服務器中的setcookie頭返回:的setcookie方法拋出異常

PHPSESSID = 462rutd8g0sbg9sinh3hqa2ol6; path = /,wordpress_test_cookie = WP + Cookie + check; path = /,[email protected]; expires = Sun,2012年07月01日05:11:02 GMT;路徑= /可溼性粉劑內容/插件; httponly,wordpress_ca07030412dd7fcd4dbeaae0bd9f5df9 = testemail @ example.com; expires = Sun,2012年07月01日05:11:02 GMT;路徑= /可溼性粉劑管理員; httponly,wordpress_logged_in_ca07030412dd7fcd4dbeaae0bd9f5df9 = testemail @ example.com; expires = Sun,2012年07月01日05:11:02 GMT;路徑= /;僅Http

我試圖用CookieContainer.SetCookies(new Uri(url),cookie);

但 '{ 「解析爲URI中的Cookie頭時發生錯誤 'http://www.smallbizads.us/'。」} {System.FormatException System.Net.CookieException' 它拋出異常

一些挖顯示,SetCookies使用,打破了餅乾。但是,因爲我已經Expires頭裏面也有,

任何想法,我怎麼能解決這個問題得到,不會明顯地工作?

注意:我只能使用這種方法通過從Set-Cookie頭取得cookie由於Wordpress問題。所以請不要建議任何其他選項。

回答

2

我花了一段時間來對它進行解剖。

至於我可以看到你想要設置由WordPress爲幾個路徑一個域(.smallbizads.us)產生的PHPSESSID(PHP會話ID)。到期日期總是相同的。

首先你把你的餅乾頭:

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

拆分它由 ';'分隔符。

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

你最終列出了12個項目。例如:

  • 「PHPSESSID = 462rutd8g0sbg9sinh3hqa2ol6」
  • 「路徑= /,wordpress_test_cookie = WP +曲奇+檢查」
  • 「期滿=星期日,01-JUL-2012 5點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類的餅乾。

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); 
} 
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=";