针对错误 “服务器提交了协议冲突. Section=ResponseHeader Detail=CR 后面必须是 LF” 的原因分析

执行http的文件下载有一段代码需要发送http HEAD请求通过反馈解析得到下载文件服务器的文件名称【为了避免请求数据量过大所以只要HEAD头其他信息不要减少时间消耗】

 1  public static string GetDownloadFileServerName(string url)
 2         {
 3             //SetAllowUnsafeHeaderParsing(true);
 4             string filename = "";
 5             try
 6             {
 7                 if (string.IsNullOrEmpty(url))
 8                     return filename;
 9                 var req = WebRequest.CreateDefault(new Uri(url)) as HttpWebRequest;
10                 req.Method = "HEAD";
11                 req.Timeout = 10000;
12                 var res = req.GetResponse() as HttpWebResponse;
13                 if (res.StatusCode == HttpStatusCode.OK)
14                 {
15                     filename = res.GetResponseHeader("Content-Disposition");//获取文件名
16                     if (filename.IndexOf("filename=") > 0)
17                         filename = filename.Substring(filename.IndexOf("=") + 1);
18                 }
19                 res.Close();
20             }
21             catch (WebException wex)
22             {
23                 log.Error(wex.Message.ToString());
24             }
25             return filename;
26         }

但在测试过程中catch异常跑出 “服务器提交了协议冲突. Section=ResponseHeader Detail=CR 后面必须是 LF” 网上一大堆的解决方案,但处理方式都是一致的:

解决方案:winfrom 在app.config种添加 web 在 web.config种添加

 <system.net>
    <settings>
      <httpWebRequest useUnsafeHeaderParsing="true" />
    </settings>
  </system.net>
或者以反射的形式在程序中设定useUnsafeHeaderParsing的值【该方法须在发送请求之前进行设定否则无效果】
 1 public static bool SetAllowUnsafeHeaderParsing(bool useUnsafe)
 2         {
 3             //Get the assembly that contains the internal class
 4             System.Reflection.Assembly aNetAssembly = System.Reflection.Assembly.GetAssembly(typeof(System.Net.Configuration.SettingsSection));
 5             if (aNetAssembly != null)
 6             {
 7                 //Use the assembly in order to get the internal type for the internal class
 8                 Type aSettingsType = aNetAssembly.GetType("System.Net.Configuration.SettingsSectionInternal");
 9                 if (aSettingsType != null)
10                 {
11                     //Use the internal static property to get an instance of the internal settings class.
12                     //If the static instance isn't created allready the property will create it for us.
13                     object anInstance = aSettingsType.InvokeMember("Section",
14                       System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.GetProperty | System.Reflection.BindingFlags.NonPublic, null, null, new object[] { });
15 
16                     if (anInstance != null)
17                     {
18                         //Locate the private bool field that tells the framework is unsafe header parsing should be allowed or not
19                         System.Reflection.FieldInfo aUseUnsafeHeaderParsing = aSettingsType.GetField("useUnsafeHeaderParsing", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
20                         if (aUseUnsafeHeaderParsing != null)
21                         {
22                             aUseUnsafeHeaderParsing.SetValue(anInstance, useUnsafe);
23                             return true;
24                         }
25                     }
26                 }
27             }
28             return false;
29         }

但自我感觉以这种客户端采用关闭安全头部解析来进行规避不是解决问题的根本办法于是通过查询相关资料了解该异常的根本原因与HTTP的HEAD头信息规范
https://msdn.microsoft.com/zh-cn/library/system.net.configuration.httpwebrequestelement.useunsafeheaderparsing

http://www.360doc.com/content/11/0113/20/3508740_86319358.shtml

https://my.oschina.net/EricWe/blog/126844

http://www.360doc.com/content/10/0930/17/3668821_57590979.shtml

通过综合信息的分析基本可以确定是web服务器在文件下载处理上有问题,只能通过Wireshark 抓包进行确认,首先分析ResponseHeader 头部是否符合规则 意外发现ETag中存在乱码

这就是造成HTTP 头部解析失败的原因了,该信息因为服务器在处理MD5字符未采用常规转化造成主要应用于断点续传

违反了下方的规则,但错误提示违反的是第一条规则走了些弯路,所以在解决问题的同时应该依靠实际场景进行具体分析才能更准确的定位问题

希望可以帮助到遇到相同问题的码友们,在此感谢

http://www.cnblogs.com/uu102/p/3671778.html

原文地址:https://www.cnblogs.com/lewisli/p/6775010.html