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

С# - Соединение: keep-alive Заголовок не отправляется во время HttpWebRequest

Я пытаюсь отправить, чтобы отправить следующий заголовок с моим HttpWebRequest:

Connection: keep-alive

Однако заголовок никогда не отправляется. Fiddler2 показывает, что всякий раз, когда я запрашиваю страницу в Google Chrome, заголовок отправляется. Однако мое приложение отказывается отправить этот заголовок по какой-либо причине.

Я установил свойство KeepAlive в true (it true по умолчанию в любом случае), но заголовок все равно не отправляется.

Я пытаюсь отправить этот заголовок несколькими HttpWebRequests, но все они в основном выглядят так:

HttpWebRequest logIn6 = (HttpWebRequest)WebRequest.Create(new Uri(responseFromLogIn5));
logIn6.CookieContainer = cookies;
logIn6.KeepAlive = true;
logIn6.Referer = "https://login.yahoo.com/config/login?.src=spt&.intl=us&.lang=en-US&.done=http://football.fantasysports.yahoo.com/";
logIn6.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.220 Safari/535.1";
logIn6.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
logIn6.Headers.Add("Accept-Encoding:gzip,deflate,sdch");
logIn6.Headers.Add("Accept-Language:en-US,en;q=0.8");
logIn6.Headers.Add("Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3");
logIn6.AllowAutoRedirect = false;

HttpWebResponse logIn6Response = (HttpWebResponse)logIn6.GetResponse();
string responseFromLogIn6 = logIn6Response.GetResponseHeader("Location");

cookies.Add(logIn6Response.Cookies);

logIn6Response.Close();

Кто-нибудь знает, что мне нужно сделать, чтобы удостовериться, что этот заголовок отправлен?

Fiddler2 Raw из Chrome:

GET xxx HTTP/1.1
Host: accounts.google.com
Connection: keep-alive
Referer: https://login.yahoo.com/config/login?.src=spt&.intl=us&.lang=en-US&.done=http://football.fantasysports.yahoo.com/
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.220 Safari/535.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: xxx

HTTP/1.1 302 Moved Temporarily
Set-Cookie: xxx
Set-Cookie: xxx
Location: xxx
Content-Type: text/html; charset=UTF-8
P3P: CP="This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info."
Date: Sat, 17 Sep 2011 22:27:09 GMT
Expires: Sat, 17 Sep 2011 22:27:09 GMT
Cache-Control: private, max-age=0
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Content-Length: 2176
Server: GSE

Fiddler2 Raw из моего приложения:

GET xxx HTTP/1.1
Referer: https://login.yahoo.com/config/login?.src=spt&.intl=us&.lang=en-US&.done=http://football.fantasysports.yahoo.com/
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.220 Safari/535.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Host: accounts.google.com

HTTP/1.1 302 Moved Temporarily
Location: xxx
Content-Type: text/html; charset=UTF-8
Date: Sun, 18 Sep 2011 00:05:40 GMT
Expires: Sun, 18 Sep 2011 00:05:40 GMT
Cache-Control: private, max-age=0
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Content-Length: 573
Server: GSE

Я пытаюсь получить вторую исходную информацию Fiddler2, чтобы выглядеть как первая исходная информация Fiddler2.

4b9b3361

Ответ 1

У меня была такая же проблема: заголовок Connection: Keep-Alive не отправляется, кроме первого запроса, и сервер, к которому я обращался, не даст мне правильный ответ, если он отсутствует. Итак, вот мои обходные пути к этой проблеме:

Сначала устанавливается свойство ProtocolVersion экземпляра HttpWebRequest на HttpVersion.Version10. За исключением того, что команда http станет GET xxx HTTP/1.0, она работает и использует только общедоступный API.

Второй способ использует отражение для изменения внутреннего свойства ServicePoint.HttpBehaviour экземпляра HttpWebRequest, например:

var req = (HttpWebRequest)WebRequest.Create(someUrl);

var sp = req.ServicePoint;
var prop = sp.GetType().GetProperty("HttpBehaviour", 
                        BindingFlags.Instance | BindingFlags.NonPublic);
prop.SetValue(sp, (byte)0, null);

req.GetResponse().Close();

Надеюсь, что это поможет.

Ответ 2

Я боролся с этой проблемой полдня! И дорогой старый Фиддлер (мой ангел-хранитель) был непреднамеренно частью проблемы:

Всякий раз, когда я тестировал свои HTTP-сообщения, используя мониторинг Fiddler ON, проблема DID NOT Всякий раз, когда я тестировал свои HTTP-POST с мониторингом Fiddler OFF, появляется проблема DID

Мои POSTS были отправлены с протоколом 1.1, и Keep-Alive был проигнорирован/избыточен/почему после первоначального соединения. то есть я мог видеть это в заголовке первого POST (через Fiddler!), но не в последующих POST, несмотря на использование того же кода. Привет, хо...

Но удаленный сервер ответил бы только, если был отправлен Keep-Alive. Теперь я не могу это доказать, но я подозреваю, что Fiddler, контролирующий соединение, заставил удаленный сервер думать или полагать, что соединение все еще активно (несмотря на отсутствие Keep-Alives, отправленное после моего первого POST), и ответило правильно. Как я уже сказал, второй, я выключил Fiddler, отсутствие Keep-Alives заставило удаленный сервер тайм-аут на меня.

Я реализовал решение 1.0, описанное выше, и мои POSTS теперь работают с включенным или выключенным Fiddler или без него. Надеюсь, это поможет кому-то еще застрять где-то...

Ответ 3

Вы делаете это правильно. Код должен содержать следующий заголовок:

Connection: Keep-Alive

Отправьте код, который вы используете для отправки запроса, и Raw-выход из Fiddler, если вы не видите этот заголовок. Вы также можете игнорировать это, потому что соединение HTTP 1.1 сохранить-по умолчанию.

Обновление: похоже, что .NET только устанавливает Keep-Alive явно для первого (!) запроса. Дальнейшие запросы к тому же хосту /url не будут иметь этот заголовок, предположительно, потому что базовое соединение tcp уже используется повторно.

Ответ 4

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

Смотрите код ниже:

    public class CookieAwareWebClient : WebClient
{
    public CookieContainer CookieContainer { get; set; }

    public CookieAwareWebClient()
        : this(new CookieContainer())
    { }

    public CookieAwareWebClient(CookieContainer c)
    {
        this.CookieContainer = c;
    }

    protected override WebRequest GetWebRequest(Uri address)
    {
        WebRequest request = base.GetWebRequest(address);
        var castRequest = request as HttpWebRequest;

        if (castRequest != null)
        {
            castRequest.KeepAlive = true; //<-- this what you want! The rest you don't need. 
            castRequest.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
            castRequest.UserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.104 Safari/537.36";
            castRequest.Referer = "https://www.jobserve.com/gb/en/Candidate/Login.aspx?url=48BB4C724EA6A1F2CADF4243A0D73C13225717A29AE8DAD6913D";
            castRequest.Headers.Add("Accept-Encoding", "gzip,deflate,sdch");
            castRequest.Headers.Add("Accept-Language", "en-GB,en-US;q=0.8,en;q=0.6");
            castRequest.CookieContainer = this.CookieContainer;
        }

        return request;
    }
}

Как вы можете видеть, я не только поддерживаю поддержку, но также использую файлы cookie и другие заголовки.

Я надеюсь, что это поможет!

Киран

Ответ 5

После загрузки HttpWebRequest исходного кода заметили, что каждое свойство проверяет некоторые известные заголовки для HeaderCollection. Чтобы избавиться от того, что делает некоторые вещи отражения в этой коллекции, заставьте ее работать

var webRequest = (HttpWebRequest) WebRequest.Create(url);
webRequest.Headers.GetType().InvokeMember("ChangeInternal",
    BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.InvokeMethod,
    Type.DefaultBinder, webRequest.Headers, new object[] {name, value}
);