How to send lower-case Keep-Alive header through HttpWebRequest

醉酒当歌 提交于 2019-11-29 02:42:15

In .net 4.0 this works:

request.Headers.GetType().InvokeMember(
    "ChangeInternal",
    BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.InvokeMethod,
    Type.DefaultBinder, 
    request.Headers, 
    new object[] { "Connection", "keep-alive" }
);

Just be sure you don't actually set the KeepAlive property on the request

I also need to do this using C# and have been trying with HttpWebRequest. A non .NET SOAP web service I want to call expects Connection: keep-alive in lower case too.

I would rather not go down the route of doing socket programming for this, so if you have any suggestions on how you worked around this, if you did it would be very helpful.

My investigation so far :

When using http Protocol version 1.1, the header isn't even sent, even if you specify the property.

e.g.

var request = (HttpWebRequest)WebRequest.Create(Endpoint); 
request.KeepAlive = true;

The solution for this is to use System.Reflection to modify the httpBehaviour which will mean Keep-Alive is sent. This will send an initial upper-case K and A 'Keep-Alive' on every request.

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

I tried using System.Reflection to modify the header too. The below code will add the flag correctly in lower case :

request.Headers.GetType().InvokeMember("ChangeInternal", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.InvokeMethod, Type.DefaultBinder, request.Headers, new object[] { "Connection", "keep-alive" });

However, at the point where I am calling GetResponse

var response = (HttpWebResponse)request.GetResponse()

The header is wiped out. Looking at the source code for HttpWebRequest.cs, this happens right before sending headers to the wire.

    //
    // The method is called right before sending headers to the wire*
    // The result is updated internal _WriteBuffer
    //
    // See ClearRequestForResubmit() for the matching cleanup code path.
    // 
    internal void SerializeHeaders() {

    ....
    ....

        string connectionString = HttpKnownHeaderNames.Connection; 
        if (UsesProxySemantics || IsTunnelRequest ) { 
            _HttpRequestHeaders.RemoveInternal(HttpKnownHeaderNames.Connection);
            connectionString = HttpKnownHeaderNames.ProxyConnection; 
            if (!ValidationHelper.IsBlankString(Connection)) {
                _HttpRequestHeaders.AddInternal(HttpKnownHeaderNames.ProxyConnection, _HttpRequestHeaders[HttpKnownHeaderNames.Connection]);
            }
        } 
        else {
            _HttpRequestHeaders.RemoveInternal(HttpKnownHeaderNames.ProxyConnection); 
        } 

RemoveInternal will also remove the header we have hacked in using Reflection.

So this still leaves me stuck.

Are there other any way around this other than going at a socket level? Are there other classes or 3rd party libraries which allow me to amend headers as I wish?

Sorry this is not an answer, but I can't yet comment on your question.

functravel.com

Connection: keep-alive is default header of Chrome and Firefox browser.

Connection: Keep-Alive is default header of Internet Explorer. Absolutely

Connection: Keep-Alive is default header of HttpWebRequest. I think you should writing a bot like IE is best choice if using HttpWebRequest.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!