如何在C#中将“连接:保持活动”标头更改为小写的“保持活动”

时间:2018-06-30 20:11:54

标签: c# http-headers httpwebrequest

我正在向主机发送一些请求,该主机由于请求中的Connection标头而一直拒绝我的请求。我需要将其更改为小写。我有与this问题中所述的完全相同的问题。但是,这个问题已有3年历史了,所以我想知道现在是否可以解决这个问题?

那里的答案是关于使用反射先删除标头,然后再将其重新设置为小写。有人可以解释我如何实现这一目标吗?谢谢。

1 个答案:

答案 0 :(得分:1)

停止并读取this solution using reflection on ChangeInternal,这可能是反射的“足够”水平。使用时,请不要通过属性设置“连接”。


此反映依赖于特定运行时的实现细节。 虽然在Microsoft .NET 4.x实现中可能会“起作用”,但存在零担保将在.NET Core,Mono等上起作用。(实际上,它很可能不会起作用)

“而且我们再也不会谈论这个了。”

private static void SetHeaderRestriction(string name, bool restricted) {
    var hInfoPi = typeof(WebHeaderCollection)
        .GetField("HInfo", BindingFlags.NonPublic | BindingFlags.Static);
    var headerInfoTableType = hInfoPi.GetValue(null).GetType();
    var headerInfoHashPi = headerInfoTableType
        .GetField("HeaderHashTable", BindingFlags.NonPublic | BindingFlags.Static);
    // Internal cache singleton of header info / restriction data
    var headerInfoHash = (Hashtable)headerInfoHashPi.GetValue(null);
    var connectionHeaderInfo = headerInfoHash["Connection"];
    // IsRequestRestricted is 'readonly', but reflection can trump.
    // An alternative would be to [temporarily] replace the entry entirely.
    var restrictedPi = connectionHeaderInfo.GetType()
        .GetField("IsRequestRestricted", BindingFlags.NonPublic | BindingFlags.Instance);
    restrictedPi.SetValue(connectionHeaderInfo, restricted);
}

void Main()
{
    var wr = (HttpWebRequest)WebRequest.Create("http://www.google.com");

    SetHeaderRestriction("Connection", false);
    wr.Headers["Connection"] = "keep-alive";
    SetHeaderRestriction("Connection", true);

    wr.Connection.Dump(); // "keep-alive"
    ((HttpWebResponse)wr.GetResponse()).StatusCode.Dump(); // OK
}

此代码在LINQPad(Dump()的来源)和.NET 4.7.1中执行。 YMMV。