using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.IO; using System.Drawing; using System.Collections.Specialized; namespace Pcb.Common { public class HttpHelper { public class HttpResult { /// /// 返回状态码 /// public int StatusCode { get; set; } /// /// 返回的html代码 /// public string ResultHtml { get; set; } public byte[] Data { get; set; } // public WebHeaderCollection RequestHeader { get; set; } /// /// 响应头 /// public WebHeaderCollection ResponseHeader { get; set; } } static List _userAgentList = new List(10); public static void Add(string userAgent) { _userAgentList.Add(userAgent); } static HttpHelper() { _userAgentList.Add("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.62 Safari/537.36"); _userAgentList.Add("User-Agent Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"); _userAgentList.Add("Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0"); } public HttpHelper(string encoding) : this(Encoding.GetEncoding(encoding)) { } public HttpHelper(Encoding encoding) : this(encoding, null, null) { } public HttpHelper(Encoding e, bool? isGzip, bool? isAllowAutoRedirect) { this.Encode = e; this.IsGZip = isGzip; this.AllowAutoRedirect = isAllowAutoRedirect; this.RequestUrlList = new List(20); this.UserAgent = _userAgentList[Math.Abs(Guid.NewGuid().GetHashCode() % _userAgentList.Count)]; this.CookieContainer = new CookieContainer(); } /// /// 站点编码,GB2312,UTF-8等 /// public Encoding Encode { get; set; } /// /// Cookie /// public CookieContainer CookieContainer { get; private set; } /// /// 是否压缩,未实现 /// public bool? IsGZip { get; set; } /// /// 是否允许跳转。Get或Post之前设置。 /// public bool? AllowAutoRedirect { get; set; } /// /// 用户代码头 /// public string UserAgent { get; set; } /// /// KeepAlive 始终false /// public bool KeepAlive { get; set; } /// /// 请求url列表 /// public List RequestUrlList { get; private set; } /// /// Get请头,默认前导页面为上一次请求的地址 /// /// /// public HttpResult Get(string url) { return Get(url, null, new NameValueCollection()); } HttpWebRequest GetRequest(string url, string referer, NameValueCollection requestHeaders) { HttpWebRequest request = null; request = WebRequest.Create(url) as HttpWebRequest; request.Method = "GET"; request.Accept = "*/*"; request.CookieContainer = CookieContainer; request.KeepAlive = this.KeepAlive; if (this.UserAgent == null) { request.UserAgent = _userAgentList[Guid.NewGuid().GetHashCode() % _userAgentList.Count]; } if (referer == null && RequestUrlList.Count > 0) { request.Referer = RequestUrlList[RequestUrlList.Count - 1]; } else request.Referer = referer; if (this.AllowAutoRedirect.HasValue) { request.AllowAutoRedirect = this.AllowAutoRedirect.Value; } if (requestHeaders != null) { foreach (string item in requestHeaders.Keys) { request.Headers[item] = requestHeaders[item]; } } if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase)) { ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(delegate { return true; }); request.Credentials = CredentialCache.DefaultCredentials; } return request; } HttpWebResponse GetResponse(string url, string referer, NameValueCollection requestHeaders) { return GetRequest(url, referer, requestHeaders).GetResponse() as HttpWebResponse; } /// /// Get请求 /// /// 地址 /// 前导页面 /// 附加的Http头,可以为NULL,如 var nvc= new NameValueCollection(); nvc["Test"]="TestValue"; /// public HttpResult Get(string url, string referer, NameValueCollection requestHeaders) { HttpResult result = new HttpResult(); HttpWebResponse response = null; try { response = (HttpWebResponse)GetRequest(url, referer, requestHeaders).GetResponse(); using (response) { if (response != null) { result.StatusCode = (int)response.StatusCode; result.ResponseHeader = response.Headers; } using (StreamReader reader = new StreamReader(response.GetResponseStream(), this.Encode)) { result.ResultHtml = reader.ReadToEnd(); } response.Close(); } } catch { result.StatusCode = -1; result.ResultHtml = string.Empty; if (response != null) result.StatusCode = (int)response.StatusCode; } finally { if (response != null) { response.Close(); } RequestUrlList.Add(url); } return result; } /// /// post请求 /// /// 地址 /// 前导页面 /// 要post的数据, var nvc= new NameValueCollection(); nvc["userName"]="userName"; /// public HttpResult Post(string url, string referer, NameValueCollection postData) { return Post(url, referer, postData, new NameValueCollection()); } /// /// Post请求 /// /// 地址 /// 要post的数据, /// public HttpResult Post(string url, NameValueCollection postData) { return Post(url, null, postData, new NameValueCollection()); } /// /// Post请求 /// /// 地址 /// 前导页 /// 要post的数据 /// 附件的http请求头 /// public HttpResult Post(string url, string referer, NameValueCollection postData, NameValueCollection requestHeaders) { string postStr = null; if (!(postData == null || postData.Count == 0)) { StringBuilder buffer = new StringBuilder(); foreach (string key in postData.Keys) { buffer.AppendFormat("&{0}={1}", key, TxtEncode(postData[key])); } postStr = buffer.ToString().Remove(0, 1); } return Post(url, referer, postStr, requestHeaders); } /// /// Post请求 /// /// 地址 /// 前导页面 /// String 类型的,Post的数据 /// 附件的http头 /// public HttpResult Post(string url, string referer, string postData, NameValueCollection requestHeaders) { HttpResult result = new HttpResult(); HttpWebRequest request = null; HttpWebResponse response = null; try { request = GetRequest(url, referer, requestHeaders); request.Method = "POST"; request.Accept = "*/*"; request.CookieContainer = CookieContainer; request.ContentType = "application/x-www-form-urlencoded; charset=" + this.Encode.WebName; request.ServicePoint.Expect100Continue = false; request.KeepAlive = this.KeepAlive; if (this.UserAgent == null) { request.UserAgent = _userAgentList[Guid.NewGuid().GetHashCode() % _userAgentList.Count]; } if (referer == null && RequestUrlList.Count > 0) { request.Referer = RequestUrlList[RequestUrlList.Count - 1]; } if (this.AllowAutoRedirect.HasValue && this.AllowAutoRedirect.Value) { request.AllowAutoRedirect = true; } if (requestHeaders != null) { foreach (string item in requestHeaders.Keys) { request.Headers[item] = requestHeaders[item]; } } if (postData != null && postData.Length > 0) { byte[] b = this.Encode.GetBytes(postData); request.ContentLength = b.Length; using (Stream stream = request.GetRequestStream()) { stream.Write(b, 0, b.Length); } } if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase)) { ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(delegate { return true; }); request.Credentials = CredentialCache.DefaultCredentials; } using (response = (HttpWebResponse)request.GetResponse()) { if (response != null) { result.StatusCode = (int)response.StatusCode; result.ResponseHeader = response.Headers; } using (StreamReader reader = new StreamReader(response.GetResponseStream(), this.Encode)) { result.ResultHtml = reader.ReadToEnd(); } response.Close(); } } catch { result.StatusCode = -1; result.ResultHtml = string.Empty; if (response != null) result.StatusCode = (int)response.StatusCode; } finally { if (response != null) { response.Close(); } RequestUrlList.Add(url); } return result; } public HttpResult PostData(string url, NameValueCollection nvc, string referUrl) { HttpResult result = new HttpResult(); string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x"); byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n"); HttpWebRequest wr = GetRequest(url, null, nvc); wr.ContentType = "multipart/form-data; boundary=" + boundary; wr.Method = "POST"; wr.Credentials = System.Net.CredentialCache.DefaultCredentials; Stream rs = wr.GetRequestStream(); string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}"; foreach (string key in nvc.Keys) { rs.Write(boundarybytes, 0, boundarybytes.Length); string formitem = string.Format(formdataTemplate, key, nvc[key]); byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem); rs.Write(formitembytes, 0, formitembytes.Length); } rs.Write(boundarybytes, 0, boundarybytes.Length); byte[] trailer = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n"); rs.Write(trailer, 0, trailer.Length); rs.Close(); HttpWebResponse wresp = null; try { wresp = (HttpWebResponse)wr.GetResponse(); Stream stream2 = wresp.GetResponseStream(); result.StatusCode = (int)wresp.StatusCode; using (StreamReader reader = new StreamReader(stream2, this.Encode)) { result.ResultHtml = reader.ReadToEnd(); } return result; } catch (Exception ex) { if (wresp != null) { result.StatusCode = (int)wresp.StatusCode; wresp.Close(); wresp = null; } else { result.StatusCode = -1; } return result; } finally { if (wr != null) wr.Abort(); if (wresp != null) { wresp.Close(); wresp = null; } } } /// /// Post文件,如果表单有Input File,则使用此方法 /// /// 地址 /// 文件地址 /// input file表单控件的name属性 /// Content-Type属性,如rar为: application/octet-stream /// 附件的表单数据 public HttpResult PostFile(string url, string filePath, string paramName, string contentType, NameValueCollection nvc) { string fileName = string.Empty; FileInfo file = new FileInfo(filePath); if (!file.Exists) fileName = ""; else fileName = file.Name; HttpResult result = new HttpResult(); string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x"); byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n"); HttpWebRequest wr = GetRequest(url, null, new NameValueCollection()); wr.ContentType = "multipart/form-data; boundary=" + boundary; wr.Method = "POST"; wr.Credentials = System.Net.CredentialCache.DefaultCredentials; Stream rs = wr.GetRequestStream(); string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}"; foreach (string key in nvc.Keys) { rs.Write(boundarybytes, 0, boundarybytes.Length); string formitem = string.Format(formdataTemplate, key, nvc[key]); byte[] formitembytes = this.Encode.GetBytes(formitem); rs.Write(formitembytes, 0, formitembytes.Length); } rs.Write(boundarybytes, 0, boundarybytes.Length); string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n"; string header = string.Format(headerTemplate, paramName, fileName, contentType); byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header); rs.Write(headerbytes, 0, headerbytes.Length); if (!string.IsNullOrEmpty(fileName)) { FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read); byte[] buffer = new byte[1024 * 1000]; int bytesRead = 0; while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0) { rs.Write(buffer, 0, bytesRead); } fileStream.Close(); } byte[] trailer = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n"); rs.Write(trailer, 0, trailer.Length); rs.Close(); HttpWebResponse wresp = null; try { wresp = (HttpWebResponse)wr.GetResponse(); Stream stream2 = wresp.GetResponseStream(); result.StatusCode = (int)wresp.StatusCode; using (StreamReader reader = new StreamReader(stream2, this.Encode)) { result.ResultHtml = reader.ReadToEnd(); } return result; } catch (Exception ex) { if (wresp != null) { result.StatusCode = (int)wresp.StatusCode; wresp.Close(); wresp = null; } else { result.StatusCode = -1; } return result; } finally { if (wr != null) wr.Abort(); if (wresp != null) { wresp.Close(); wresp = null; } } } /// /// Post文件,如果表单有Input File,则使用此方法 /// /// 地址 /// 文件地址 /// input file表单控件的name属性 /// Content-Type属性,如rar为: application/octet-stream /// 附件的表单数据 public HttpResult PostFile(string url, string filePath, string paramName, string contentType, string referUrl, NameValueCollection nvc) { FileInfo file = new FileInfo(filePath); if (!file.Exists) { throw new FileNotFoundException(); } HttpResult result = new HttpResult(); string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x"); byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n"); HttpWebRequest wr = GetRequest(url, referUrl, new NameValueCollection()); wr.ContentType = "multipart/form-data; boundary=" + boundary; wr.Method = "POST"; wr.Credentials = System.Net.CredentialCache.DefaultCredentials; Stream rs = wr.GetRequestStream(); string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}"; foreach (string key in nvc.Keys) { rs.Write(boundarybytes, 0, boundarybytes.Length); string formitem = string.Format(formdataTemplate, key, nvc[key]); byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem); rs.Write(formitembytes, 0, formitembytes.Length); } rs.Write(boundarybytes, 0, boundarybytes.Length); string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n"; string header = string.Format(headerTemplate, paramName, file.Name, contentType); byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header); rs.Write(headerbytes, 0, headerbytes.Length); FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read); byte[] buffer = new byte[4096]; int bytesRead = 0; while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0) { rs.Write(buffer, 0, bytesRead); } fileStream.Close(); byte[] trailer = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n"); rs.Write(trailer, 0, trailer.Length); rs.Close(); HttpWebResponse wresp = null; try { wresp = (HttpWebResponse)wr.GetResponse(); Stream stream2 = wresp.GetResponseStream(); result.StatusCode = (int)wresp.StatusCode; using (StreamReader reader = new StreamReader(stream2, this.Encode)) { result.ResultHtml = reader.ReadToEnd(); } return result; } catch (Exception ex) { if (wresp != null) { result.StatusCode = (int)wresp.StatusCode; wresp.Close(); wresp = null; } else { result.StatusCode = -1; } return result; } finally { if (wr != null) wr.Abort(); if (wresp != null) { wresp.Close(); wresp = null; } } } /// /// 根据地址获取图片,多用于验证码 /// /// /// public Image GetImage(string url) { Bitmap image = null; using (var response = (HttpWebResponse)GetRequest(url, null, null).GetResponse()) { image = new System.Drawing.Bitmap(response.GetResponseStream()); response.Close(); } return image; } public string TxtEncode(string str) { if (str != null) { byte[] byteStr = this.Encode.GetBytes(str); StringBuilder sb = new StringBuilder(byteStr.Length * 3); for (int i = 0; i < byteStr.Length; i++) { sb.AppendFormat(@"%{0}", Convert.ToString(byteStr[i], 16)); } return sb.ToString(); } else { return ""; } } } }