|
@@ -0,0 +1,244 @@
|
|
|
+using System;
|
|
|
+using System.Collections.Generic;
|
|
|
+using System.IO;
|
|
|
+using System.IO.Compression;
|
|
|
+using System.Linq;
|
|
|
+using System.Net;
|
|
|
+using System.Text;
|
|
|
+using System.Text.RegularExpressions;
|
|
|
+
|
|
|
+
|
|
|
+namespace WebManager
|
|
|
+{
|
|
|
+ /// <summary>
|
|
|
+ /// Http请求封装类,用于模拟登录等操作
|
|
|
+ /// 工作原理:
|
|
|
+ /// 1.通过chrome的NetWork面板,跟踪到请求过程中传递的 Request Headers
|
|
|
+ /// 2.将Request Headers 附加到请求。
|
|
|
+ /// 3.请求成功后,将HttpResponseHeader.SetCookie记录下来。
|
|
|
+ /// 4.下次请求时,附加上第3步的cookie,即可模拟登录后操作。
|
|
|
+ /// </summary>
|
|
|
+ public class HttpRequestHelper
|
|
|
+ {
|
|
|
+ /// <summary>
|
|
|
+ /// cookie集合,用于模拟登陆
|
|
|
+ /// </summary>
|
|
|
+ private static readonly Dictionary<string, Cookie> CookieDic = new Dictionary<string, Cookie>();
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Http请求
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="url"></param>
|
|
|
+ /// <param name="method"></param>
|
|
|
+ /// <param name="headers"></param>
|
|
|
+ /// <param name="content"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public static string DoRequest(string url, string method, string headers, string content)
|
|
|
+ {
|
|
|
+ var request = (HttpWebRequest)WebRequest.Create(url);
|
|
|
+ request.Method = method;
|
|
|
+ if (method.Equals("GET", StringComparison.InvariantCultureIgnoreCase))
|
|
|
+ {
|
|
|
+ request.MaximumAutomaticRedirections = 100;
|
|
|
+ request.AllowAutoRedirect = false;
|
|
|
+ }
|
|
|
+ #region 1.设置Http头部
|
|
|
+ if (!string.IsNullOrWhiteSpace(headers))
|
|
|
+ {
|
|
|
+ var hsplit = headers.Split(new[] { "\n" }, StringSplitOptions.RemoveEmptyEntries);
|
|
|
+ foreach (var item in hsplit)
|
|
|
+ {
|
|
|
+ if (!item.StartsWith(":"))
|
|
|
+ {
|
|
|
+ var kv = item.Split(':');
|
|
|
+ if (kv.Length == 2)
|
|
|
+ {
|
|
|
+ var key = kv[0].Trim();
|
|
|
+ var value = string.Join(":", kv.Skip(1)).Trim();
|
|
|
+ #region 设置http头
|
|
|
+ switch (key.ToLower())
|
|
|
+ {
|
|
|
+ case "accept":
|
|
|
+ {
|
|
|
+ request.Accept = value;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case "host":
|
|
|
+ {
|
|
|
+ request.Host = value;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case "connection":
|
|
|
+ {
|
|
|
+ if (value == "keep-alive")
|
|
|
+ request.KeepAlive = true;
|
|
|
+ else
|
|
|
+ request.KeepAlive = false; //just test
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case "content-type":
|
|
|
+ {
|
|
|
+ request.ContentType = value;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case "user-agent":
|
|
|
+ {
|
|
|
+ request.UserAgent = value;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case "referer":
|
|
|
+ {
|
|
|
+ request.Referer = value;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case "content-length":
|
|
|
+ {
|
|
|
+ request.ContentLength = Convert.ToInt64(value);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case "expect":
|
|
|
+ {
|
|
|
+ request.Expect = value;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case "if-modified-since":
|
|
|
+ {
|
|
|
+ request.IfModifiedSince = Convert.ToDateTime(value);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case "cookie":
|
|
|
+ {
|
|
|
+ var cc = new CookieCollection();
|
|
|
+ var cookieString = value;
|
|
|
+ if (!string.IsNullOrWhiteSpace(cookieString))
|
|
|
+ {
|
|
|
+ var spilit = cookieString.Split(';');
|
|
|
+ foreach (var ci in spilit)
|
|
|
+ {
|
|
|
+ var arr = ci.Split('=');
|
|
|
+ if (kv.Length == 2)
|
|
|
+ cc.Add(new Cookie(arr[0].Trim(), arr[1].Trim()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ #endregion
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region 2.设置cookie
|
|
|
+ request.Headers[HttpRequestHeader.Cookie] = GetCookieStr();
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region 3.发送请求数据
|
|
|
+ if (!string.IsNullOrWhiteSpace(content))
|
|
|
+ {
|
|
|
+ var data = Encoding.UTF8.GetBytes(content);
|
|
|
+ request.ContentLength = data.Length;
|
|
|
+ using (var stream = request.GetRequestStream())
|
|
|
+ {
|
|
|
+ stream.Write(data, 0, data.Length);
|
|
|
+ stream.Close();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ var response = (HttpWebResponse)request.GetResponse();
|
|
|
+
|
|
|
+ #region 4.保存cookie,用于下次请求
|
|
|
+ //var cookies = new CookieCollection();
|
|
|
+ //var s = response.Headers[HttpResponseHeader.SetCookie].Replace("HttpOnly,", "").Replace("httponly,", "");
|
|
|
+ //if (!string.IsNullOrWhiteSpace(s))
|
|
|
+ //{
|
|
|
+ // var spilit = s.Split(';');
|
|
|
+ // foreach (var item in spilit)
|
|
|
+ // {
|
|
|
+ // var kv = item.Split('=');
|
|
|
+ // if (kv.Length == 2)
|
|
|
+ // cookies.Add(new Cookie(kv[0].Trim(), kv[1].Trim()));
|
|
|
+ // }
|
|
|
+ //}
|
|
|
+ //foreach (Cookie c in cookies)
|
|
|
+ // if (CookieDic.ContainsKey(c.Name))
|
|
|
+ // CookieDic[c.Name] = c;
|
|
|
+ // else
|
|
|
+ // CookieDic.Add(c.Name, c);
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ var result = GetResponse(response);
|
|
|
+ return Unicode2String(result);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 将Unicode转换为中文
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="source"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public static string Unicode2String(string source)
|
|
|
+ {
|
|
|
+ return new Regex(@"\\u([0-9A-F]{4})", RegexOptions.IgnoreCase).Replace(
|
|
|
+ source, x => string.Empty + Convert.ToChar(Convert.ToUInt16(x.Result("$1"), 16)));
|
|
|
+ }
|
|
|
+ /// <summary>
|
|
|
+ /// 从HttpWebResponse读取响应文本
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="response"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ private static string GetResponse(HttpWebResponse response)
|
|
|
+ {
|
|
|
+ var defaultEncode = Encoding.UTF8;
|
|
|
+ var contentType = response.ContentType;
|
|
|
+ if (contentType.ToLower().Contains("gb2312"))
|
|
|
+ defaultEncode = Encoding.GetEncoding("gb2312");
|
|
|
+ else if (contentType.ToLower().Contains("gbk"))
|
|
|
+ defaultEncode = Encoding.GetEncoding("gbk");
|
|
|
+ else if (contentType.ToLower().Contains("zh-cn")) defaultEncode = Encoding.GetEncoding("zh-cn");
|
|
|
+ string responseBody;
|
|
|
+ if (response.ContentEncoding.ToLower().Contains("gzip"))
|
|
|
+ using (var stream = new GZipStream(response.GetResponseStream(), CompressionMode.Decompress))
|
|
|
+ {
|
|
|
+ using (var reader = new StreamReader(stream))
|
|
|
+ {
|
|
|
+ responseBody = reader.ReadToEnd();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (response.ContentEncoding.ToLower().Contains("deflate"))
|
|
|
+ using (var stream = new DeflateStream(response.GetResponseStream(), CompressionMode.Decompress))
|
|
|
+ {
|
|
|
+ using (var reader = new StreamReader(stream, defaultEncode))
|
|
|
+ {
|
|
|
+ responseBody = reader.ReadToEnd();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ using (var stream = response.GetResponseStream())
|
|
|
+ {
|
|
|
+ using (var reader = new StreamReader(stream, defaultEncode))
|
|
|
+ {
|
|
|
+ responseBody = reader.ReadToEnd();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return responseBody;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static string GetCookieStr()
|
|
|
+ {
|
|
|
+ var sb = new StringBuilder();
|
|
|
+ foreach (var item in CookieDic)
|
|
|
+ if (!item.Value.Expired)
|
|
|
+ {
|
|
|
+ if (sb.Length == 0)
|
|
|
+ sb.Append(item.Key).Append("=").Append(item.Value.Value);
|
|
|
+ else
|
|
|
+ sb.Append("; ").Append(item.Key).Append(" = ").Append(item.Value.Value);
|
|
|
+ }
|
|
|
+ return sb.ToString();
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|