c# -连接:在HttpWebRequest期间没有发送keepalive报头

本文关键字:keepalive 报头 -连接 HttpWebRequest | 更新日期: 2023-09-27 18:08:59

我试图发送发送以下header与我的HttpWebRequest:

Connection: keep-alive

然而,报头永远不会被发送。Fiddler2显示,每当我在Google Chrome中请求页面时,都会发送标题。但是,由于某些原因,我的应用程序拒绝发送此标头。

我已经将KeepAlive属性设置为true(默认情况下是true),但头仍然没有发送。

我试图发送多个httpwebrequest,但他们基本上都是这样的头:

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 From 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 From My Application:

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原始信息。

c# -连接:在HttpWebRequest期间没有发送keepalive报头

我有同样的问题:Connection: Keep-Alive头除了第一个请求外没有发送,我访问的服务器不会给我正确的响应,如果它丢失了。所以,以下是我解决这个问题的方法:

首先将HttpWebRequest实例的ProtocolVersion属性设置为HttpVersion.Version10。除了http命令将变成GET xxx HTTP/1.0之外,它只使用公共API。

第二种方法是使用反射来修改HttpWebRequest实例的内部属性ServicePoint.HttpBehaviour,如下所示:

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();

我为这个问题挣扎了半天!亲爱的老提琴手(我的守护天使)无意中成为问题的一部分:

每当我测试我的HTTP帖子使用Fiddler监控-问题没有出现每当我测试我的HTTP post与Fiddler监控关闭-问题确实出现

我的post是用1.1协议发送的,在初始连接之后,Keep-Alive被忽略了/冗余/为什么即我可以看到它在第一个POST的头(通过提琴手!),但不是在随后的帖子,尽管使用相同的代码。

但是远程服务器只有在发送Keep-Alive时才会响应。现在我无法证明这一点,但我怀疑监视连接的Fiddler导致远程服务器认为或相信连接仍然处于活动状态(尽管在我的第一个POST之后没有发送keep - alive)并正确响应。正如我所说的,当我关闭Fiddler时,keep - alive的缺失导致远程服务器超时。

我实现了上面描述的1.0解决方案,我的POSTS现在可以工作了,无论是否打开或关闭Fiddler。

你做得对。该代码应该导致添加以下头:

Connection: Keep-Alive

张贴你用来发送请求和原始输出Fiddler的代码,如果你没有看到这个头。你也可以忽略这个,因为HTTP 1.1连接默认是保持活动的。

更新:看起来。net只为第一个(!)请求显式设置Keep-Alive。对同一主机/url的进一步请求将没有此标头,可能是因为底层tcp连接已被重用。

下载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}
);

我知道这个问题的答案,因为我有同样的问题,并设法通过继承Web客户端和重写它的Get Web请求方法来解决它。

请看下面的代码:

    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;
    }
}

正如你所看到的,我不仅启用了keep-alive,而且还利用了cookie和其他报头!

我希望这对你有帮助!

Kiran