国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C# > 正文

C#如何解析http報文

2020-01-24 01:34:25
字體:
來源:轉載
供稿:網友

下面通過一段內容有文字說明有代碼分析,并附有展示圖供大家學習。

要解析HTTP報文,需要實現以下操作:

讀取HTTP報頭提供的各種屬性
分析屬性值,從中獲取內容編碼和字符集編碼
將報頭數據和內容進行分離
判斷內容是否文本還是二進制,如果是二進制的則不進行處理
如果內容是文本,按報頭中提供的內容編碼和字符集編碼進行解壓縮和解碼
目前沒有找到.Net框架內置的解析方法,理論上HttpClient等類在內部應該已經實現了解析,但不知為何沒有公開這些處理方法。(亦或是我沒找到)

那么只能自己來解析這些數據了。

我們先來看看這個經過gzip壓縮的文本內容的HTTP報文:

這里提供一個老外寫的簡陋的解析類(已經過修改,原代碼中存在一些嚴重BUG):

public enum HTTPHeaderField{ Accept = 0, Accept_Charset = 1, Accept_Encoding = 2, Accept_Language = 3, Accept_Ranges = 4, Authorization = 5, Cache_Control = 6, Connection = 7, Cookie = 8, Content_Length = 9, Content_Type = 10, Date = 11, Expect = 12, From = 13, Host = 14, If_Match = 15, If_Modified_Since = 16, If_None_Match = 17, If_Range = 18, If_Unmodified_Since = 19, Max_Forwards = 20, Pragma = 21, Proxy_Authorization = 22, Range = 23, Referer = 24, TE = 25, Upgrade = 26, User_Agent = 27, Via = 28, Warn = 29, Age = 30, Allow = 31, Content_Encoding = 32, Content_Language = 33, Content_Location = 34, Content_Disposition = 35, Content_MD5 = 36, Content_Range = 37, ETag = 38, Expires = 39, Last_Modified = 40, Location = 41, Proxy_Authenticate = 42, Refresh = 43, Retry_After = 44, Server = 45, Set_Cookie = 46, Trailer = 47, Transfer_Encoding = 48, Vary = 49, Warning = 50, WWW_Authenticate = 51};class HTTPHeader{ #region PROPERTIES private string[] m_StrHTTPField = new string[52]; private byte[] m_byteData = new byte[4096]; public string[] HTTPField {  get { return m_StrHTTPField; }  set { m_StrHTTPField = value; } } public byte[] Data {  get { return m_byteData; }  set { m_byteData = value; } } #endregion // convertion System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding(); #region CONSTRUCTEUR /// <summary> /// Constructeur par défaut - non utilisé /// </summary> private HTTPHeader() { } public HTTPHeader(byte[] ByteHTTPRequest) {  string HTTPRequest = encoding.GetString(ByteHTTPRequest);  try  {   int IndexHeaderEnd;   string Header;   // Si la taille de requête est supérieur ou égale à 1460, alors toutes la chaine est l'entête http   if (HTTPRequest.Length <= 1460)    Header = HTTPRequest;   else   {    IndexHeaderEnd = HTTPRequest.IndexOf("/r/n/r/n");    Header = HTTPRequest.Substring(0, IndexHeaderEnd);    Data = ByteHTTPRequest.Skip(IndexHeaderEnd + 4).ToArray();   }   HTTPHeaderParse(Header);  }  catch (Exception)  { } } #endregion #region METHODES private void HTTPHeaderParse(string Header) {  #region HTTP HEADER REQUEST & RESPONSE  HTTPHeaderField HHField;  string HTTPfield, buffer;  int Index;  foreach (int IndexHTTPfield in Enum.GetValues(typeof(HTTPHeaderField)))  {   HHField = (HTTPHeaderField)IndexHTTPfield;   HTTPfield = "/n" + HHField.ToString().Replace('_', '-') + ": "; //Ajout de /n devant pour éviter les doublons entre cookie et set_cookie   // Si le champ n'est pas présent dans la requête, on passe au champ suivant   Index = Header.IndexOf(HTTPfield);   if (Index == -1)    continue;   buffer = Header.Substring(Index + HTTPfield.Length);   Index = buffer.IndexOf("/r/n");   if (Index == -1)    m_StrHTTPField[IndexHTTPfield] = buffer.Trim();   else    m_StrHTTPField[IndexHTTPfield] = buffer.Substring(0, Index).Trim();   //Console.WriteLine("Index = " + IndexHTTPfield + " | champ = " + HTTPfield.Substring(1) + " " + m_StrHTTPField[IndexHTTPfield]);  }  // Affichage de tout les champs  /*for (int j = 0; j < m_StrHTTPField.Length; j++)  {   HHField = (HTTPHeaderField)j;   Console.WriteLine("m_StrHTTPField[" + j + "]; " + HHField + " = " + m_StrHTTPField[j]);  }  */  #endregion } #endregion}

編寫以下代碼以實現解析文件:

class Program{ static void Main(string[] args) {  SRART: Console.WriteLine("輸入待解析的HTTP報文數據文件完整路徑:");  var filename = Console.ReadLine();  try  {   FileStream fs = new FileStream(filename, FileMode.Open);   BinaryReader br = new BinaryReader(fs);   var data = br.ReadBytes((int)fs.Length);   var header = new HTTPHeader(data);   var x = 0;   foreach (var f in header.HTTPField)   {    if (!String.IsNullOrEmpty(f))    {     Console.WriteLine($"[{x:00}] - {(HTTPHeaderField) x} : {f}");    }    x++;   }   Console.WriteLine($"總數據尺寸{fs.Length}字節,實際數據尺寸{header.Data.Length}字節");   Console.WriteLine(Encoding.UTF8.GetString(header.Data));   Console.WriteLine();   br.Close();   fs.Close();    }  catch (Exception e)  {   Console.WriteLine(e);  }  goto SRART; }}

這里還未實現gzip解壓縮和字符解碼,直接用UTF8解碼輸出的。(需要時再寫吧,都是體力活兒~)

效果圖展示:

下面的圖是沒有經過gzip壓縮過的數據。

以上就是用C#如何解析http報文的全部內容,哪位大俠還有好的方法歡迎提出寶貴意見,喜歡大家喜歡以上內容所述。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 海淀区| 灵武市| 松潘县| 龙岩市| 柯坪县| 盘锦市| 青田县| 牟定县| 竹溪县| 南宁市| 延长县| 昌都县| 和平区| 满城县| 那坡县| 旺苍县| 海城市| 喀喇| 临安市| 青冈县| 友谊县| 阳曲县| 博白县| 双柏县| 额济纳旗| 德阳市| 岐山县| 镇原县| 喀喇沁旗| 固镇县| 溧阳市| 湘阴县| 德庆县| 濮阳市| 济宁市| 尼木县| 大厂| 庄河市| 喀喇沁旗| 西安市| 康定县|