執行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