未设置cookie的路径时的CookieCollection问题

时间:2012-06-27 16:47:25

标签: c# .net cookies .net-4.0

我正在使用HttpWebRequestHttpWebResponse来抓取网站。我为每个请求使用相同的CookieContainer,确保自动处理cookie。

但是,其中一个请求需要一个特定的cookie,该cookie在之前的响应中设置。虽然它存在于集合中,但其Path属性显示不正确。根据{{​​3}}(页7),当使用空白路径设置cookie时(如此),应将路径设置为请求的URL,但不包括最终斜杠。实际发生的是它被设置为整个 URL路径,这意味着cookie不能随后被同一子域中的不同URL读取。

一个例子:

  1. 我在RFC2109
  2. 处请求该页面
  3. 响应包含Set-Cookie标题,其中包含 mycookie = 12345; expires = Wed,27-Jun-2012 16:20:00 GMT
  4. 将Cookie添加到.NET CookieCollection中。由于没有路径设置,路径是 错误地初始化为 /sub/mypage.php
  5. 我在同一个子域下请求另一个页面,但是需要mycookie cookie,例如http://www.myserver.com/sub/mypage.php
  6. 由于路径不完全匹配,因此.NET不提供cookie。如果Path是 / sub ,那么它将被正确提供
  7. 我使用带有Firebug和Firecookie扩展的Firefox浏览器执行了相同的导航步骤。路径设置正确,即在真实浏览器会话中设置为子域。

    任何人都可以确认这一点并可能指出我的解决方法或解决此问题吗?非常感谢。

1 个答案:

答案 0 :(得分: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;
}

因此它使用Plain 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));
}