Как изменить заголовок «Connection: Keep-Alive» на строчные «keep-alive» в C # - PullRequest
0 голосов
/ 30 июня 2018

Я отправляю некоторые запросы хосту, который продолжает отклонять мои запросы из-за заголовка Connection в моих запросах. Мне нужно изменить его на строчные. У меня точно такая же проблема, как описано в этом вопросе. Однако этому вопросу уже 3 года, поэтому мне было интересно, есть ли сейчас решение этой проблемы?

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

1 Ответ

0 голосов
/ 01 июля 2018

Остановитесь и прочитайте это решение, используя отражение на ChangeInternal, что, вероятно, является «достаточным» уровнем отражения. При его использовании не устанавливайте соединение через свойство.


Это отражение основывается на деталях реализации определенного времени выполнения. Хотя такое может «работать» в реализациях Microsoft .NET 4.x, есть ZERO GUARANTEE, оно будет работать на .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.

...