Помощь с .NET CookieContainer - PullRequest
       13

Помощь с .NET CookieContainer

2 голосов
/ 02 декабря 2009

Недавно я столкнулся с некоторыми проблемами с CookieContainer. Либо я делаю что-то серьезно неправильно, либо есть какая-то ошибка с объектом CookieContainer. Кажется, он не обновляет коллекцию cookie с помощью определенных заголовков Set-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), ​​который используется для каждого запроса, не получает заголовок Set-Cookie для refer_id, cust_session, refer_id_persistent. Однако он выбирает cust_id, private_browsing_mode, tcc и member_session ... Есть идеи, почему это может быть?

Ответы [ 6 ]

8 голосов
/ 22 января 2010

Просто хотел обновить этот пост на случай, если кто-то еще сталкивался с этим. Проблема заключается в том, что .NET соответствует спецификации RFC для тегов cookie, но не все сайты это делают. Так что, в конечном итоге, проблема не в Microsoft или .NET. (Хотя IE хорошо управляет файлами cookie, поэтому было бы лучше переписать их методы анализа файлов cookie .NET, используя те же методы анализа). Проблема заключается в сайтах, которые не следуют RFC спецификации .

Тем не менее, проблема, с которой я часто сталкивался, заключается в том, что сайты будут использовать запятые в датах истечения срока действия в своих файлах cookie. .NET интерпретирует их как разделители между различными полями cookie и удаляет окончание и все, что есть после отключения cookie.

RFC spec : "Cookie:, за которым следует разделенный запятыми список из одного или нескольких файлов cookie". Простым решением этой проблемы было бы для веб-сервера заключать значения с запятыми в кавычки согласно документу RFC. Тем не менее, нет полиции RFC, поэтому мы можем только надеяться, что люди будут следовать правилам.

3 голосов
/ 08 января 2011

MSDN SetCookies: SetCookies извлекает все файлы cookie HTTP из заголовка файла cookie HTTP, создает файл Cookie для каждого из них, а затем добавляет каждый файл cookie во внутреннюю коллекцию Cookie, связанную с URI. HTTP-куки в строке cookieHeader должны быть разделены запятыми .

MSDN GetCookieHeader GetCookieHeader возвращает строку, которая содержит HTTP-заголовок cookie для экземпляров Cookie, указанных uri. Заголовок HTTP создается путем добавления строкового представления каждого Cookie, связанного с uri. Обратите внимание, что точный формат строки зависит от RFC, которому соответствует Cookie. Строки для всех экземпляров Cookie, связанных с uri, объединяются и разделяются точкой с запятой .

Эта строка имеет неправильный формат для использования в качестве второго параметра метода SetCookies.

1 голос
/ 25 мая 2013

Мое решение: заменить «UTC» на «GMT».

1 голос
/ 20 декабря 2012

CookieContainer имеет 2 основные проблемы, с которыми я столкнулся, будь то из-за дизайна или из-за ошибки, которую я не знаю.

1) Файлы cookie, установленные на пост 302, не принимаются. Пример

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

Решение Задайте для автоматического перенаправления значение false, вручную следуйте инструкциям по перенаправлению и установите файлы cookie самостоятельно

2) .Net ОЧЕНЬ суетлив из-за неправильной формы строк cookie, в строке которых есть запятая. Это действительно правильно, но иногда куки-файлы имеют установленную дату, которая включает запятую, которая останавливает все куки-файлы.

Решение Вручную разобрать строки cookie и добавить себя. Ужасная задача. У меня растянулся беспорядок в хакерской функции, которая зацикливается и выполняет операции, но конечный результат - это работает для всех случаев, которые я к этому приложил. Это не красиво, но оно выполняет свою работу

Не уверен, что это ваша проблема, но возможно. Если бы не пища для размышлений, в любом случае

1 голос
/ 02 декабря 2009

Это только быстрое сканирование вашего кода, но кажется, что вы отправляете почтовые данные, прежде чем отправлять куки в запросе.

   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;

Что может случиться, когда вы записываете свои данные в поток, который отправляется на удаленный сервер. Однако для того, чтобы куки были установлены, они должны быть отправлены на сервер перед любыми постданными. Простое решение состоит в том, чтобы поменять это так:

 // 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();
    }
0 голосов
/ 22 января 2010

Попробуйте использовать CookieContainer.GetCookieHeader и CookieContainer.SetCookies

YourCookieContainer.GetCookieHeader(new Uri("your url"));

YourCookieContainer.SetCookies(new Uri("your url"), "string from GetCookieHeader");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...