Подтвердить что ты не робот

HTTPWebRequest.GetResponse() не работает с аутентифицированными запросами через прозрачный прокси-сервер

Мы используем объекты HTTPWebRequest для создания HTTP-запросов к нашему приложению, и у нас возникает проблема, когда запрос требует аутентификации, и есть прозрачный прокси (Squid 3.1.10).

string url = "http://www.icode.co.uk/test/auth.php";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Credentials = new NetworkCredential("username", "password");

HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream stream = response.GetResponseStream();
StreamReader reader = new StreamReader(stream);

MessageBox.Show(reader.ReadToEnd());

reader.Close();
stream.Close();
response.Close();

В нашем исходном коде использовался класс WebClient, который показал ту же проблему.

При первом запуске этого кода он корректно отображает результат. Когда код выполняется во второй раз, он не работает в строке GetResponse() с:

System.Net.WebException was unhandled
  Message="The server committed a protocol violation. Section=ResponseStatusLine"
  Source="System"
  StackTrace:
       at System.Net.HttpWebRequest.GetResponse()
       at Dummy.DummyForm.button1_Click(Object sender, EventArgs e) in H:\Trial\Dummy\DummyForm.cs:line 42
       at ...

В Windows 7 перезапуск процесса заставляет его восстанавливать и работать один раз, но Server 2003 требует полной перезагрузки.

Глядя на сетевой захват, два запроса идентичны для начала, первоначальный неаутентифицированный запрос отправляется и сервер отвечает, но ошибка запросы отправляют второй аутентифицированный запрос в середине начального ответа, как если бы он игнорировал заголовок Content-Length (что является правильным). Затем он получает остальную часть исходного ответа и терпит неудачу с ошибкой протокола.

Wireshark capture

Кажется странным, что клиент (HTTPWebRequest) не закрывает соединение, хотя.

Если прокси-сервер не используется (не порт 80 или внутренний трафик), все запросы работают так, как ожидалось. Когда аутентификация отсутствует, она также работает, поскольку она делает единственный запрос.

Я уже уменьшил код проблемы до минимума и воспроизвел его с помощью образца MSDN, но кто-нибудь знает, является ли это известной проблемой или проблемой в нашей (.NET или Squid) конфигурации?

4b9b3361

Ответ 1

Так как он только терпит неудачу во второй раз, <

request.KeepAlive = false;

сделать разницу?

Ответ 2

Я думаю, что проверка подлинности NTLM (NetworkCredential) не работает одновременно с прозрачной функцией прокси-сервера SQUID.: - (

http://www.squid-cache.org/mail-archive/squid-users/201110/0025.html

Не могли бы вы попробовать другую схему аутентификации?

Ответ 3

Попробуйте аутентифицироваться,

request.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(username + ":" + password));

до request.GetResponse();

Это сработало для меня. Сначала я попытался вставить всю строку, которая не сработала!