【问题标题】:How to set useUnsafeHeaderParsing in code如何在代码中设置 useUnsafeHeaderParsing
【发布时间】:2011-12-07 23:28:01
【问题描述】:

我收到以下异常:

服务器违反了协议。 Section=ResponseHeader Detail=CR后面必须跟LF

从这个问题:

HttpWebRequestError: The server committed a protocol violation. Section=ResponseHeader Detail=CR must be followed by LF

我了解我需要将 useUnsafeHeaderParsing 设置为 True。

这是我的代码:

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

useUnsafeHeaderParsing 是 HttpWebRequestElement 类的一个属性。

如何将其集成到上述代码中?

【问题讨论】:

    标签: c# c#-4.0 httpwebrequest httpwebresponse


    【解决方案1】:

    您需要在 web.config 中的 <system.net> 部分中设置它,如下所示:

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

    如果出于某种原因,您不想从配置中执行此操作,您可以通过以语法方式设置配置设置从代码中执行此操作。示例见this page

    【讨论】:

    • 此代码如何添加到 c# webform 应用程序中的“app.config”?
    • 我使用httpClient.PostAsync。我收到 ServerProtocolViolation 错误。我将useUnsafeHeaderParsing 设置为true。现在我得到 ArgumetOutOfRangeExceptionSystem.Net.Http.HttpResponseMessage..ctor(HttpStatusCode statusCode)
    • 我用一个 c# 7.1 控制台应用程序尝试了这个解决方案,将它添加到 app.config,但它没有解决问题。知道为什么吗?
    • 有没有办法在 .Net Core 中做同样的事情,或者我如何处理 .Net Core 中服务器返回的一些不安全的标头?
    【解决方案2】:

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

    【讨论】:

    • 前段时间我将它添加到了一个 .Net Framework 应用程序中,它可以工作。我们正在将该应用程序切换到 .Net Standard 2.1,并且不支持 System.Net.dll。有没有人尝试为 .Net Standard 或 .Net Core 应用程序解决这个问题?
    【解决方案3】:

    如果你不想使用反射,你可以试试这个代码(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");
    

    【讨论】:

    • 此更改是永久性的,还是仅适用于当前请求?
    • 感谢这有助于我们在没有配置文件的情况下调用插件而不是完整的应用程序。
    猜你喜欢
    • 1970-01-01
    • 2015-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-23
    • 2017-08-04
    • 1970-01-01
    相关资源
    最近更新 更多