HttpRequestHelper.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.IO.Compression;
  5. using System.Linq;
  6. using System.Net;
  7. using System.Text;
  8. using System.Text.RegularExpressions;
  9. namespace AiControlRequest
  10. {
  11. /// <summary>
  12. /// Http请求封装类,用于模拟登录等操作
  13. /// 工作原理:
  14. /// 1.通过chrome的NetWork面板,跟踪到请求过程中传递的 Request Headers
  15. /// 2.将Request Headers 附加到请求。
  16. /// 3.请求成功后,将HttpResponseHeader.SetCookie记录下来。
  17. /// 4.下次请求时,附加上第3步的cookie,即可模拟登录后操作。
  18. /// </summary>
  19. public class HttpRequestHelper
  20. {
  21. /// <summary>
  22. /// cookie集合,用于模拟登陆
  23. /// </summary>
  24. private static readonly Dictionary<string, Cookie> CookieDic = new Dictionary<string, Cookie>();
  25. /// <summary>
  26. /// Http请求
  27. /// </summary>
  28. /// <param name="url"></param>
  29. /// <param name="method"></param>
  30. /// <param name="headers"></param>
  31. /// <param name="content"></param>
  32. /// <returns></returns>
  33. public static string DoRequest(string url, string method, string headers, string content)
  34. {
  35. var request = (HttpWebRequest)WebRequest.Create(url);
  36. request.Method = method;
  37. request.Timeout = 600000 * 4;
  38. if (method.Equals("GET", StringComparison.InvariantCultureIgnoreCase))
  39. {
  40. request.MaximumAutomaticRedirections = 100;
  41. request.AllowAutoRedirect = false;
  42. }
  43. #region 1.设置Http头部
  44. if (!string.IsNullOrWhiteSpace(headers))
  45. {
  46. var hsplit = headers.Split(new[] { "\n" }, StringSplitOptions.RemoveEmptyEntries);
  47. foreach (var item in hsplit)
  48. {
  49. if (!item.StartsWith(":"))
  50. {
  51. var kv = item.Split(':');
  52. if (kv.Length == 2)
  53. {
  54. var key = kv[0].Trim();
  55. var value = string.Join(":", kv.Skip(1)).Trim();
  56. #region 设置http头
  57. switch (key.ToLower())
  58. {
  59. case "accept":
  60. {
  61. request.Accept = value;
  62. break;
  63. }
  64. case "host":
  65. {
  66. request.Host = value;
  67. break;
  68. }
  69. case "connection":
  70. {
  71. if (value == "keep-alive")
  72. request.KeepAlive = true;
  73. else
  74. request.KeepAlive = false; //just test
  75. break;
  76. }
  77. case "content-type":
  78. {
  79. request.ContentType = value;
  80. break;
  81. }
  82. case "user-agent":
  83. {
  84. request.UserAgent = value;
  85. break;
  86. }
  87. case "referer":
  88. {
  89. request.Referer = value;
  90. break;
  91. }
  92. case "content-length":
  93. {
  94. request.ContentLength = Convert.ToInt64(value);
  95. break;
  96. }
  97. case "expect":
  98. {
  99. request.Expect = value;
  100. break;
  101. }
  102. case "if-modified-since":
  103. {
  104. request.IfModifiedSince = Convert.ToDateTime(value);
  105. break;
  106. }
  107. case "cookie":
  108. {
  109. var cc = new CookieCollection();
  110. var cookieString = value;
  111. if (!string.IsNullOrWhiteSpace(cookieString))
  112. {
  113. var spilit = cookieString.Split(';');
  114. foreach (var ci in spilit)
  115. {
  116. var arr = ci.Split('=');
  117. if (kv.Length == 2)
  118. cc.Add(new Cookie(arr[0].Trim(), arr[1].Trim()));
  119. }
  120. }
  121. }
  122. break;
  123. }
  124. #endregion
  125. }
  126. }
  127. }
  128. }
  129. #endregion
  130. #region 2.设置cookie
  131. request.Headers[HttpRequestHeader.Cookie] = GetCookieStr();
  132. #endregion
  133. #region 3.发送请求数据
  134. if (!string.IsNullOrWhiteSpace(content))
  135. {
  136. var data = Encoding.UTF8.GetBytes(content);
  137. request.ContentLength = data.Length;
  138. using (var stream = request.GetRequestStream())
  139. {
  140. stream.Write(data, 0, data.Length);
  141. stream.Close();
  142. }
  143. }
  144. #endregion
  145. var response = (HttpWebResponse)request.GetResponse();
  146. #region 4.保存cookie,用于下次请求
  147. //var cookies = new CookieCollection();
  148. //var s = response.Headers[HttpResponseHeader.SetCookie].Replace("HttpOnly,", "").Replace("httponly,", "");
  149. //if (!string.IsNullOrWhiteSpace(s))
  150. //{
  151. // var spilit = s.Split(';');
  152. // foreach (var item in spilit)
  153. // {
  154. // var kv = item.Split('=');
  155. // if (kv.Length == 2)
  156. // cookies.Add(new Cookie(kv[0].Trim(), kv[1].Trim()));
  157. // }
  158. //}
  159. //foreach (Cookie c in cookies)
  160. // if (CookieDic.ContainsKey(c.Name))
  161. // CookieDic[c.Name] = c;
  162. // else
  163. // CookieDic.Add(c.Name, c);
  164. #endregion
  165. var result = GetResponse(response);
  166. return Unicode2String(result);
  167. }
  168. /// <summary>
  169. /// 将Unicode转换为中文
  170. /// </summary>
  171. /// <param name="source"></param>
  172. /// <returns></returns>
  173. public static string Unicode2String(string source)
  174. {
  175. return new Regex(@"\\u([0-9A-F]{4})", RegexOptions.IgnoreCase).Replace(
  176. source, x => string.Empty + Convert.ToChar(Convert.ToUInt16(x.Result("$1"), 16)));
  177. }
  178. /// <summary>
  179. /// 从HttpWebResponse读取响应文本
  180. /// </summary>
  181. /// <param name="response"></param>
  182. /// <returns></returns>
  183. private static string GetResponse(HttpWebResponse response)
  184. {
  185. var defaultEncode = Encoding.UTF8;
  186. var contentType = response.ContentType;
  187. if (contentType.ToLower().Contains("gb2312"))
  188. defaultEncode = Encoding.GetEncoding("gb2312");
  189. else if (contentType.ToLower().Contains("gbk"))
  190. defaultEncode = Encoding.GetEncoding("gbk");
  191. else if (contentType.ToLower().Contains("zh-cn")) defaultEncode = Encoding.GetEncoding("zh-cn");
  192. string responseBody;
  193. if (response.ContentEncoding.ToLower().Contains("gzip"))
  194. using (var stream = new GZipStream(response.GetResponseStream(), CompressionMode.Decompress))
  195. {
  196. using (var reader = new StreamReader(stream))
  197. {
  198. responseBody = reader.ReadToEnd();
  199. }
  200. }
  201. else if (response.ContentEncoding.ToLower().Contains("deflate"))
  202. using (var stream = new DeflateStream(response.GetResponseStream(), CompressionMode.Decompress))
  203. {
  204. using (var reader = new StreamReader(stream, defaultEncode))
  205. {
  206. responseBody = reader.ReadToEnd();
  207. }
  208. }
  209. else
  210. using (var stream = response.GetResponseStream())
  211. {
  212. using (var reader = new StreamReader(stream, defaultEncode))
  213. {
  214. responseBody = reader.ReadToEnd();
  215. }
  216. }
  217. return responseBody;
  218. }
  219. private static string GetCookieStr()
  220. {
  221. var sb = new StringBuilder();
  222. foreach (var item in CookieDic)
  223. if (!item.Value.Expired)
  224. {
  225. if (sb.Length == 0)
  226. sb.Append(item.Key).Append("=").Append(item.Value.Value);
  227. else
  228. sb.Append("; ").Append(item.Key).Append(" = ").Append(item.Value.Value);
  229. }
  230. return sb.ToString();
  231. }
  232. }
  233. }