web-dev-qa-db-ja.com

コードでuseUnsafeHeaderParsingを設定する方法

次の例外が発生します。

サーバーはプロトコル違反をコミットしました。 Section = ResponseHeader Detail = CRの後にLFを続ける必要があります

この質問から:

HttpWebRequestError:サーバーがプロトコル違反をコミットしました。Section= ResponseHeader Detail = CRの後にLFが続く必要があります

UseUnsafeHeaderParsingをTrueに設定する必要があることを理解しています。

これが私のコードです:

HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(url);
WebResponse myResp = myReq.GetResponse(); //exception is thrown here

useUnsafeHeaderParsingは、HttpWebRequestElementクラスのプロパティです。

上記のコードにどのように統合しますか?

18
Barka

これは、次のように<system.net>セクション内のweb.configに設定する必要があります。

<system.net> 
  <settings> 
   <httpWebRequest useUnsafeHeaderParsing="true" /> 
  </settings> 
</system.net> 

なんらかの理由で、構成から実行したくない場合は、構成設定をプログラムで設定することにより、コードから実行できます。例については このページ を参照してください。

32
Edwin de Koning

Edwinが指摘したように、web.configまたはapp.configファイルでuseUnsafeHeaderParsing属性を設定する必要があります。実行時に値を動的に変更したい場合は、値がSystem.Net.Configuration.SettingsSectionInternalのインスタンスに埋め込まれており、パブリックにアクセスできないため、リフレクションを使用する必要があります。

トリックを行うコード例(見つかった情報 here に基づく)を次に示します。

using System;
using System.Net;
using System.Net.Configuration;
using System.Reflection;

namespace UnsafeHeaderParsingSample
{
    class Program
    {
        static void Main()
        {
            // Enable UseUnsafeHeaderParsing
            if (!ToggleAllowUnsafeHeaderParsing(true))
            {
                // Couldn't set flag. Log the fact, throw an exception or whatever.
            }

            // This request will now allow unsafe header parsing, i.e. GetResponse won't throw an exception.
            var request = (HttpWebRequest) WebRequest.Create("http://localhost:8000");
            var response = request.GetResponse();

            // Disable UseUnsafeHeaderParsing
            if (!ToggleAllowUnsafeHeaderParsing(false))
            {
                // Couldn't change flag. Log the fact, throw an exception or whatever.
            }

            // This request won't allow unsafe header parsing, i.e. GetResponse will throw an exception.
            var strictHeaderRequest = (HttpWebRequest)WebRequest.Create("http://localhost:8000");
            var strictResponse = strictHeaderRequest.GetResponse();
        }

        // Enable/disable useUnsafeHeaderParsing.
        // See http://o2platform.wordpress.com/2010/10/20/dealing-with-the-server-committed-a-protocol-violation-sectionresponsestatusline/
        public static bool ToggleAllowUnsafeHeaderParsing(bool enable)
        {
            //Get the Assembly that contains the internal class
            Assembly assembly = Assembly.GetAssembly(typeof(SettingsSection));
            if (Assembly != null)
            {
                //Use the Assembly in order to get the internal type for the internal class
                Type settingsSectionType = Assembly.GetType("System.Net.Configuration.SettingsSectionInternal");
                if (settingsSectionType != null)
                {
                    //Use the internal static property to get an instance of the internal settings class.
                    //If the static instance isn't created already invoking the property will create it for us.
                    object anInstance = settingsSectionType.InvokeMember("Section",
                    BindingFlags.Static | BindingFlags.GetProperty | BindingFlags.NonPublic, null, null, new object[] { });
                    if (anInstance != null)
                    {
                        //Locate the private bool field that tells the framework if unsafe header parsing is allowed
                        FieldInfo aUseUnsafeHeaderParsing = settingsSectionType.GetField("useUnsafeHeaderParsing", BindingFlags.NonPublic | BindingFlags.Instance);
                        if (aUseUnsafeHeaderParsing != null)
                        {
                            aUseUnsafeHeaderParsing.SetValue(anInstance, enable);
                            return true;
                        }

                    }
                }
            }
            return false;
        }
    }
}
26
afrischke

Reflectionを使用したくない場合は、次のコード(System.Configuration.dllリファレンス)を試すことができます。

using System.Configuration;
using System.Net.Configuration;

var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
var settings = (SettingsSection)config.GetSection("system.net/settings");
settings.HttpWebRequest.UseUnsafeHeaderParsing = true;
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("system.net/settings");
0
Geograph