代码之家  ›  专栏  ›  技术社区  ›  regex

.NET CookieContainer帮助

  •  2
  • regex  · 技术社区  · 15 年前

    我最近遇到了一些关于CookieContainer的问题。或者我做了一些严重错误的事情,或者有一些带有CookieContainer对象的bug。它似乎没有用特定的set cookie头更新cookie集合。

    这可能是一篇冗长的文章,我对此进行了评估,但我希望尽可能地详细,所以我将列出我的HTTP嗅探日志以及实际的实现代码。

        public bool SendRequest(HttpWebRequest request, IDictionary<string, string> data, int retries)
        {
            // copy request in case request instance already failed
            HttpWebRequest newRequest = (HttpWebRequest)HttpWebRequest.Create(request.RequestUri);
            newRequest.Method = request.Method;
    
            // if POST data was provided, write it to the stream
            if (data != null && data.Count != 0)
            {
                StreamWriter writer = new StreamWriter(newRequest.GetRequestStream());
                writer.Write(createPostString(data));
                writer.Close();
            }
    
            // set request with global cookie container
            newRequest.CookieContainer = this.cookieJar;
    
            try
            {
                using (HttpWebResponse resp = (HttpWebResponse)newRequest.GetResponse())
                {
                    //CookieCollection newCooks = getCookies(resp.Headers);
                    //updateCookies(newCooks);
                    this.cookieJar = newRequest.CookieContainer;
                    this.Html = getResponseString(resp);
    
                 /* remainder snipped */
    


    所以这里有代码,这里有两个对我在fiddler中嗅到的响应的请求:


    请求1
    POST /login/ HTTP/1.1
    Host: www.site.com
    Content-Length: 47
    Expect: 100-continue
    Connection: Keep-Alive
    

    响应1

    HTTP/1.1 200 OK
    Date: Wed, 02 Dec 2009 17:03:35 GMT
    Server: Apache
    Set-Cookie: tcc=one; path=/
    Set-Cookie: cust_id=2702585226; domain=.site.com; path=/; expires=Mon, 01-Jan-2011 00:00:00 GMT
    Set-Cookie: cust_session=12%2F2%2F2009%20%2012%3A3%3A35; domain=.site.com; path=/; expires=Wed 2-Dec-2009  17:33:35
    Set-Cookie: refer_id_persistent=0000; domain=.site.com; path=/; expires=Fri 2-Dec-2011  17:3:35
    Set-Cookie: refer_id=0000; domain=.site.com; path=/
    Set-Cookie: private_browsing_mode=off; domain=.site.com; path=/; expires=Fri, 01-Jan-2010 17:03:35 GMT
    Set-Cookie: member_session=UmFuZG9tSVYL%5BS%5D%5BP%5DfhH77bYaVoS9j9Yd8ySRkyHHz%5BS%5Dk0S8MVsQ6AyraNlcdcCRC0RkB%5BP%5DfBYVM4vn6JQ3HlJxT3GlJi1RZiMGQaITg7HN9dpu9oRbZgMjhJlXXa%5BP%5D7pFSjqDIZWRr3LAfnhh3btv4E3rvVH42CeOP%5BS%5Dx6kDyvrokQEHyIHPGi7zswZbuHrUdx2XKEKKJzw1unDWfw0LZWjoehAs0QgSOz6Nzp8P4Hp8hqrULdIMch6acPT%5BS%5DbKV8zwugBIcjr5dI3rVR%5BP%5Dv42rsTtQB7dyb%5BP%5DRKb8Y83cGqhHM33hP%5BP%5DUtmbDC1PPfr%5BS%5DPC23lAO%5BS%5DmQ3mOy9x4pgQSOfp40XSfzgVg3EavITaxHBeI5nO3%5BP%5D%5BS%5D2rSDthDfuEm4sT9i6UF3sYd1vlOL0IC9ZsVatV1yhhpQ%5BE%5D%5BE%5D; domain=.site.com; path=/; expires=Fri, 01-Jan-2010 17:03:35 GMT
    Connection: close
    Transfer-Encoding: chunked
    Content-Type: text/html; charset=UTF-8
    

    请求2

    GET /test?search=jjkjf HTTP/1.1
    Host: www.site.com
    Cookie: tcc=one; cust_id=2702585226; private_browsing_mode=off; member_session=UmFuZG9tSVYL%5BS%5D%5BP%5DfhH77bYaVoS9j9Yd8ySRkyHHz%5BS%5Dk0S8MVsQ6AyraNlcdcCRC0RkB%5BP%5DfBYVM4vn6JQ3HlJxT3GlJi1RZiMGQaITg7HN9dpu9oRbZgMjhJlXXa%5BP%5D7pFSjqDIZWRr3LAfnhh3btv4E3rvVH42CeOP%5BS%5Dx6kDyvrokQEHyIHPGi7zswZbuHrUdx2XKEKKJzw1unDWfw0LZWjoehAs0QgSOz6Nzp8P4Hp8hqrULdIMch6acPT%5BS%5DbKV8zwugBIcjr5dI3rVR%5BP%5Dv42rsTtQB7dyb%5BP%5DRKb8Y83cGqhHM33hP%5BP%5DUtmbDC1PPfr%5BS%5DPC23lAO%5BS%5DmQ3mOy9x4pgQSOfp40XSfzgVg3EavITaxHBeI5nO3%5BP%5D%5BS%5D2rSDthDfuEm4sT9i6UF3sYd1vlOL0IC9ZsVatV1yhhpQ%5BE%5D%5BE%5D
    


    如您所见,用于每个请求的cookieContainer(this.cookiejar)没有为refer_id、cust_session、refer_id_persistent拾取set cookie头。不过,它确实会获取客户ID、私有浏览模式、TCC和成员会话…你知道为什么会这样吗?
    6 回复  |  直到 12 年前
        1
  •  8
  •   regex    15 年前

    只是想更新这篇文章,以防有人发现。问题是.NET符合cookie标签的RFC规范,但并非所有站点都符合。因此,归根结底,问题不在于微软,也不在于.NET。(尽管如此,也就是说,管理cookie很好,所以最好使用相同的分析方法重写它们的.NET cookie分析方法)问题在于不遵循的站点 RFC specifications .

    尽管如此,我经常遇到的一个问题是,网站将在其cookie的到期日期中使用逗号。.NET将这些解释为不同cookie字段之间的分隔符,并从cookie中去掉结尾和所有内容。

    RFC spec :“cookie:,后跟一个逗号分隔的一个或多个cookie列表。”解决此问题的简单方法是,Web服务器根据RFC文档将值用逗号括在引号中。但是,没有RFC警察,所以我们只能希望人们遵守规则。

        2
  •  3
  •   Terre    14 年前

    msdn设置cookies: setcookies从HTTP cookie头中提取所有HTTP cookie,为每个cookie构建一个cookie,然后将每个cookie添加到与URI关联的内部cookie集合中。cookieheader字符串中的HTTP cookie 必须用逗号分隔 .

    msdn getcookieheader(msdn getcookieheader) getcookieheader返回一个字符串,该字符串保存由uri指定的cookie实例的HTTP cookie头。HTTP头是通过添加与URI关联的每个cookie的字符串表示来构建的。请注意,字符串的确切格式取决于cookie所遵循的RFC。与URI关联的所有cookie实例的字符串组合在一起,并且 用分号分隔 .

    此字符串的格式不正确,无法用作setcookies方法的第二个参数。

        3
  •  1
  •   Michael Edwards    15 年前

    这只是一个快速扫描您的代码,但似乎您正在发送后数据之前,您发送的cookie在请求中。

       if (data != null && data.Count != 0)
        {
            StreamWriter writer = new StreamWriter(newRequest.GetRequestStream());
            writer.Write(createPostString(data));
            writer.Close();
        }
    
        // set request with global cookie container
        newRequest.CookieContainer = this.cookieJar;
    

    可能发生的情况是,当您将日志数据写入流时,会将其发送到远程服务器。但是,要设置cookie,它们必须在任何postdata之前发送到服务器。简单的解决方案是这样交换:

     // set request with global cookie container
     newRequest.CookieContainer = this.cookieJar;
    
     if (data != null && data.Count != 0)
        {
            StreamWriter writer = new StreamWriter(newRequest.GetRequestStream());
            writer.Write(createPostString(data));
            writer.Close();
        }
    
        4
  •  1
  •   user399421    12 年前

    CookieContainer有两个我遇到的主要问题,无论是设计还是我不知道的bug。

    1)302贴子上设置的cookies不会被提取。 例子

     Post to site
      302 redirect response
      Load New page which sets cookie
    

    解决方案 将autodirect设置为false,然后手动执行重定向并自己设置cookie

    2).net对于不正确地形成字符串中有逗号的cookie字符串非常挑剔。这实际上是正确的,但有时cookie的日期设置中包含逗号,这会停止所有cookie的设置。

    解决方案 手动分析cookie字符串并添加自己。一项可怕的任务。我对一个hack函数进行了大量的修改,循环和if,但最终的结果是它适用于迄今为止我所提出的所有情况。它不漂亮,但能完成任务

    不确定以上是你的问题,但也许。不管怎样,如果不是一些思考的食物

        5
  •  1
  •   Mr. TA    12 年前

    我的解决方案:将“UTC”替换为“GMT”。

        6
  •  0
  •   Pat    15 年前

    尝试使用cookiecontainer.getcookieheader和cookiecontainer.setcookies

    YourCookieContainer.GetCookieHeader(new Uri("your url"));
    
    YourCookieContainer.SetCookies(new Uri("your url"), "string from GetCookieHeader");