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 AiControlRequest
{
///
/// Http请求封装类,用于模拟登录等操作
/// 工作原理:
/// 1.通过chrome的NetWork面板,跟踪到请求过程中传递的 Request Headers
/// 2.将Request Headers 附加到请求。
/// 3.请求成功后,将HttpResponseHeader.SetCookie记录下来。
/// 4.下次请求时,附加上第3步的cookie,即可模拟登录后操作。
///
public class HttpRequestHelper
{
///
/// cookie集合,用于模拟登陆
///
private static readonly Dictionary CookieDic = new Dictionary();
///
/// Http请求
///
///
///
///
///
///
public static string DoRequest(string url, string method, string headers, string content)
{
var request = (HttpWebRequest)WebRequest.Create(url);
request.Method = method;
request.Timeout = 600000 * 4;
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);
}
///
/// 将Unicode转换为中文
///
///
///
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)));
}
///
/// 从HttpWebResponse读取响应文本
///
///
///
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();
}
}
}