2012-06-27 36 views
2

我使用HttpWebRequestHttpWebResponse來抓取網站。我爲每個請求使用相同的CookieContainer,確保cookie自動處理。當Cookie的路徑未設置時CookieCollection問題

但是,其中一個請求需要一個特定的cookie,該cookie是在先前的響應中設置的。雖然這存在於集合中,但其Path屬性顯示不正確。根據RFC2109(第7頁),當Cookie設置爲空路徑(如本文所述)時,路徑應設置爲請求的URL,但不包括最終斜線。實際發生的情況是,它被設置爲整個 URL路徑,這意味着該cookie不能被相同子域中的不同URL讀取。

一個例子:

  1. 我在http://www.myserver.com/sub/mypage.php
  2. 響應請求的頁面包括Set-Cookie標頭,讀取的myCookie = 12345; expires = 2012年6月27日星期三16:20:00 GMT
  3. 該Cookie已添加到.NET CookieCollection中。由於沒有路徑設置,路徑爲 的初始化爲/sub/mypage.php
  4. 我在同一個子域下請求另一個頁面,但需要mycookie cookie,例如, http://www.myserver.com/sub/anotherpage.php
  5. Cookie不是由.NET提供的,因爲路徑不完全匹配。如果路徑是/分,它會一直擔任正確

我已經執行使用Firefox瀏覽器的Firebug和Firecookie擴展相同的導航步驟。在真實瀏覽器會話中,路徑設置正確,即對子域。

任何人都可以證實這一點,並可能指向我的解決方法或解決此問題?非常感謝。

回答

3

下面是有關內部代碼的問題。看起來不像是一個意外的錯誤。如果不遵循標準,你應該報告問題。

switch (this.m_cookieVariant) 
{ 
    case CookieVariant.Plain: 
     this.m_path = absolutePath; 
     break; 

    case CookieVariant.Rfc2109: 
     this.m_path = absolutePath.Substring(0, absolutePath.LastIndexOf('/')); 
     break; 

    default: 
     this.m_path = absolutePath.Substring(0, absolutePath.LastIndexOf('/') + 1); 
     break; 
} 

因此,它使用普通cookie變體,除非cookie本身另有規定。你將不得不迭代所有的cookie檢查。真的,這是我討厭.net的cookie處理的衆多原因之一。無法輕鬆獲取所有網域/ Cookie。最簡單的解決方法是執行以下操作。但是,您最終會得到重複的Cookie。所以你可能想要通過uri獲取cookie。

public static CookieCollection FixCookies(CookieCollection collection) 
{ 
    foreach (Cookie cookie in collection) 
    { 
     if (string.IsNullOrEmpty(cookie.Path)) 
      continue; 

     int idx = cookie.Path.LastIndexOf('/'); 
     if (idx == -1) 
      continue; 

     cookie.Path = cookie.Path.Substring(0, idx); 
    } 
    return collection; 
} 

[STAThread] 
private static void Main(string[] args) 
{ 
    var http = (HttpWebRequest)WebRequest.Create("http://localhost/test/test.php"); 
    http.CookieContainer = new CookieContainer(); 
    var resp = (HttpWebResponse)http.GetResponse(); 
    http.CookieContainer.Add(FixCookies(resp.Cookies)); 
} 
+0

謝謝,威爾。它看起來像.NET默認cookie的'平原'版本0變種(從原始的Netscape實現),我不知道其實是正確的。我有興趣瞭解Version和CookieVariant在內部是否被重寫,但在那之前我會堅持使用您推薦解決此問題的解決方案。再次感謝! –

+0

該變體通過發送像'mycookie = 12345; expires = Wed,版本= 1,端口= 80'。設置版本會將其設置爲Rfc2109。設置端口將改爲將其設置爲Rfc2965。 – Will