Files
kami_itunes_june/DotNet.Utilities/HttpHelper.cs

784 lines
19 KiB
C#

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using AppleBatch_June;
using AppleBatch_June.Utils;
namespace DotNet.Utilities
{
public class HttpHelper : IDisposable
{
public class RequestState : IDisposable
{
private const int BUFFER_SIZE = 1024;
public byte[] BufferRead;
public List<byte[]> RequestData;
public HttpWebRequest request;
public HttpWebResponse response;
public Stream streamResponse;
public HttpResult result;
public HttpItem item;
public RequestState(HttpResult _result, HttpItem _item)
{
BufferRead = new byte[1024];
RequestData = new List<byte[]>();
result = _result;
item = _item;
request = null;
streamResponse = null;
}
public byte[] getDataBytes()
{
if (RequestData != null && RequestData.Count > 0)
{
byte[] array = new byte[RequestData.Sum((byte[] c) => c.Length)];
int num = 0;
foreach (byte[] requestDatum in RequestData)
{
foreach (byte b in requestDatum)
{
array[num] = b;
num++;
}
}
if (response.ContentEncoding != null && response.ContentEncoding.Equals("gzip", StringComparison.InvariantCultureIgnoreCase))
{
using (MemoryStream stream = new MemoryStream(array))
{
MemoryStream memoryStream = new MemoryStream();
new GZipStream(stream, CompressionMode.Decompress).CopyTo(memoryStream, 1024);
return memoryStream.ToArray();
}
}
return array;
}
return null;
}
public void Dispose()
{
Dispose(disposing: true);
}
protected virtual void Dispose(bool disposing)
{
if (!disposing)
{
return;
}
try
{
if (BufferRead != null)
{
Array.Clear(BufferRead, 0, BufferRead.Length);
BufferRead = null;
}
if (RequestData == null)
{
return;
}
foreach (byte[] requestDatum in RequestData)
{
Array.Clear(requestDatum, 0, requestDatum.Length);
}
RequestData.Clear();
RequestData = null;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
private class RequestStreamStae : IDisposable
{
private bool m_disposed;
public HttpWebRequest request { get; set; }
public byte[] buffer { get; set; }
public bool WriteState { get; set; } = true;
public string WriteErrMessage { get; set; } = "";
public void Dispose()
{
Dispose(disposing: true);
}
protected virtual void Dispose(bool disposing)
{
if (m_disposed)
{
return;
}
if (disposing)
{
try
{
if (buffer != null)
{
Array.Clear(buffer, 0, buffer.Length);
buffer = null;
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
m_disposed = true;
}
}
private Encoding encoding = Encoding.Default;
private Encoding postencoding = Encoding.Default;
private HttpWebRequest request;
private HttpWebResponse response;
private IPEndPoint _IPEndPoint;
private ManualResetEvent allDone;
private const int BUFFER_SIZE = 1024;
public void SetHeaderValue(WebHeaderCollection header, string name, string value)
{
try
{
PropertyInfo property = typeof(WebHeaderCollection).GetProperty("InnerCollection", BindingFlags.Instance | BindingFlags.NonPublic);
if (property != null)
{
NameValueCollection nameValueCollection = property.GetValue(header, null) as NameValueCollection;
if (nameValueCollection.AllKeys.Contains(name))
{
nameValueCollection[name] = value;
}
else
{
nameValueCollection.Add(name, value);
}
}
}
catch (Exception)
{
}
}
public HttpResult GetHtml(HttpItem item)
{
allDone = new ManualResetEvent(initialState: false);
if (allDone != null && !allDone.SafeWaitHandle.IsClosed)
{
allDone.Reset();
}
HttpResult httpResult = new HttpResult();
RequestState requestState = null;
try
{
SetRequest(item);
}
catch (Exception ex)
{
return new HttpResult
{
Cookie = string.Empty,
Header = null,
Html = ex.Message,
StatusDescription = "配置参数时出错:" + ex.Message
};
}
try
{
if (allDone != null && !allDone.SafeWaitHandle.IsClosed)
{
allDone.Reset();
}
requestState = new RequestState(httpResult, item);
requestState.request = request;
requestState.RequestData.Clear();
ThreadPool.RegisterWaitForSingleObject(request.BeginGetResponse(RespCallback, requestState).AsyncWaitHandle, TimeoutCallback, request, item.Timeout, executeOnlyOnce: true);
if (allDone != null && !allDone.SafeWaitHandle.IsClosed)
{
allDone.WaitOne(item.Timeout + 1000);
}
request.Abort();
}
catch (WebException ex2)
{
if (ex2.Response != null)
{
using (response = (HttpWebResponse)ex2.Response)
{
GetData(item, httpResult);
}
}
else
{
httpResult.Html = ex2.Message;
}
}
catch (Exception ex3)
{
httpResult.Html = ex3.Message;
}
if (item.IsToLower)
{
httpResult.Html = httpResult.Html.ToLower();
}
if (item.IsReset)
{
request = null;
response = null;
}
if (requestState != null)
{
requestState.response?.Close();
requestState.streamResponse?.Dispose();
requestState.Dispose();
requestState = null;
}
return httpResult;
}
private void RespCallback(IAsyncResult asynchronousResult)
{
RequestState requestState = null;
try
{
requestState = (RequestState)asynchronousResult.AsyncState;
HttpWebRequest httpWebRequest = requestState.request;
requestState.response = (HttpWebResponse)httpWebRequest.EndGetResponse(asynchronousResult);
Stream stream = (requestState.streamResponse = requestState.response.GetResponseStream());
if (requestState != null && requestState.BufferRead != null)
{
stream.BeginRead(requestState.BufferRead, 0, 1024, ReadCallBack, requestState);
}
return;
}
catch (WebException ex)
{
if (ex.Response != null && requestState != null)
{
requestState.response = (HttpWebResponse)ex.Response;
Stream stream2 = (requestState.streamResponse = requestState.response.GetResponseStream());
if (requestState != null && requestState.BufferRead != null)
{
stream2.BeginRead(requestState.BufferRead, 0, 1024, ReadCallBack, requestState);
}
return;
}
if (requestState != null)
{
requestState.result.Html = ex.Message;
}
}
catch (Exception ex2)
{
if (requestState != null)
{
requestState.result.Html = ex2.Message;
}
}
if (allDone != null && !allDone.SafeWaitHandle.IsClosed)
{
allDone.Set();
}
}
private void ReadCallBack(IAsyncResult asyncResult)
{
RequestState requestState = (RequestState)asyncResult.AsyncState;
try
{
Stream streamResponse = requestState.streamResponse;
int num = streamResponse.EndRead(asyncResult);
if (num > 0)
{
byte[] array = new byte[num];
Array.Copy(requestState.BufferRead, array, num);
requestState.RequestData.Add(array);
streamResponse.BeginRead(requestState.BufferRead, 0, 1024, ReadCallBack, requestState);
return;
}
streamResponse.Close();
GetData(requestState.item, requestState.result, requestState);
}
catch (WebException ex)
{
Console.WriteLine("\nReadCallBack Exception raised!");
Console.WriteLine("\nMessage:{0}", ex.Message);
Console.WriteLine("\nStatus:{0}", ex.Status);
}
catch (Exception ex2)
{
requestState.result.Html = ex2.Message;
Console.WriteLine("\nReadCallBack Exception raised!");
}
if (allDone != null && !allDone.SafeWaitHandle.IsClosed)
{
allDone.Set();
}
}
private void TimeoutCallback(object state, bool timedOut)
{
try
{
if (timedOut && state is HttpWebRequest httpWebRequest)
{
httpWebRequest.Abort();
}
}
catch (Exception)
{
}
}
private void GetData(HttpItem item, HttpResult result)
{
if (response != null)
{
result.StatusCode = response.StatusCode;
result.StatusDescription = response.StatusDescription;
result.Header = response.Headers;
result.ResponseUri = response.ResponseUri.ToString();
if (response.Cookies != null)
{
result.CookieCollection = response.Cookies;
}
if (response.Headers["set-cookie"] != null)
{
result.Cookie = response.Headers["set-cookie"];
}
byte[] @byte = GetByte();
if (@byte != null && @byte.Length != 0)
{
SetEncoding(item, result, @byte);
result.Html = encoding.GetString(@byte);
}
else
{
result.Html = string.Empty;
}
}
}
private void GetData(HttpItem item, HttpResult result, RequestState myRequestState)
{
response = myRequestState.response;
if (response != null)
{
result.StatusCode = response.StatusCode;
result.StatusDescription = response.StatusDescription;
result.Header = response.Headers;
result.ResponseUri = response.ResponseUri.ToString();
if (response.Cookies != null)
{
result.CookieCollection = response.Cookies;
}
if (response.Headers["set-cookie"] != null)
{
result.Cookie = response.Headers["set-cookie"];
}
byte[] dataBytes = myRequestState.getDataBytes();
if (dataBytes != null && dataBytes.Length != 0)
{
SetEncoding(item, result, dataBytes);
result.Html = encoding.GetString(dataBytes);
}
else
{
result.Html = string.Empty;
}
}
}
private void SetEncoding(HttpItem item, HttpResult result, byte[] ResponseByte)
{
if (item.ResultType == ResultType.Byte)
{
result.ResultByte = ResponseByte;
}
if (encoding != null)
{
return;
}
Match match = Regex.Match(Encoding.Default.GetString(ResponseByte), "<meta[^<]*charset=([^<]*)[\"']", RegexOptions.IgnoreCase);
string text = string.Empty;
if (match != null && match.Groups.Count > 0)
{
text = match.Groups[1].Value.ToLower().Trim();
}
string text2 = string.Empty;
if (!string.IsNullOrWhiteSpace(response.CharacterSet))
{
text2 = response.CharacterSet.Trim().Replace("\"", "").Replace("'", "");
}
else
{
string text3 = response.ContentType.ToLower().Trim();
if (!string.IsNullOrEmpty(text3))
{
int num = text3.IndexOf("charset=");
if (num != -1)
{
text2 = text3.Substring(num + 8);
}
}
}
if (text.Length > 2)
{
try
{
encoding = Encoding.GetEncoding(text.Replace("\"", string.Empty).Replace("'", "").Replace(";", "")
.Replace("iso-8859-1", "gbk")
.Trim());
return;
}
catch
{
if (string.IsNullOrEmpty(text2))
{
encoding = Encoding.UTF8;
}
else
{
encoding = Encoding.GetEncoding(text2);
}
return;
}
}
if (string.IsNullOrEmpty(text2))
{
encoding = Encoding.UTF8;
}
else
{
encoding = Encoding.GetEncoding(text2);
}
}
private byte[] GetByte()
{
using MemoryStream memoryStream = new MemoryStream();
if (response.ContentEncoding != null && response.ContentEncoding.Equals("gzip", StringComparison.InvariantCultureIgnoreCase))
{
new GZipStream(response.GetResponseStream(), CompressionMode.Decompress).CopyTo(memoryStream, 1024);
}
else
{
response.GetResponseStream().CopyTo(memoryStream, 1024);
}
return memoryStream.ToArray();
}
private void SetRequest(HttpItem item)
{
SetCer(item);
if (item.IPEndPoint != null)
{
_IPEndPoint = item.IPEndPoint;
request.ServicePoint.BindIPEndPointDelegate = BindIPEndPointCallback;
}
if (item.Header != null && item.Header.Count > 0)
{
string[] allKeys = item.Header.AllKeys;
foreach (string name in allKeys)
{
request.Headers.Add(name, item.Header[name]);
}
}
// SetProxy(item);
if (item.ProtocolVersion != null)
{
request.ProtocolVersion = item.ProtocolVersion;
}
request.ServicePoint.Expect100Continue = item.Expect100Continue;
request.Method = item.Method;
request.Timeout = item.Timeout;
request.KeepAlive = item.KeepAlive;
request.ReadWriteTimeout = item.ReadWriteTimeout;
if (!string.IsNullOrWhiteSpace(item.Host))
{
request.Host = item.Host;
}
if (item.IfModifiedSince.HasValue)
{
request.IfModifiedSince = Convert.ToDateTime(item.IfModifiedSince);
}
if (item.Date.HasValue)
{
request.Date = Convert.ToDateTime(item.Date);
}
request.Accept = item.Accept;
request.ContentType = item.ContentType;
request.UserAgent = item.UserAgent;
encoding = item.Encoding;
request.Credentials = item.ICredentials;
SetCookie(item);
request.Referer = item.Referer;
request.AllowAutoRedirect = item.Allowautoredirect;
if (item.MaximumAutomaticRedirections > 0)
{
request.MaximumAutomaticRedirections = item.MaximumAutomaticRedirections;
}
SetPostData(item);
if (item.Connectionlimit > 0)
{
request.ServicePoint.ConnectionLimit = item.Connectionlimit;
}
}
private void SetCer(HttpItem item)
{
if (!string.IsNullOrWhiteSpace(item.CerPath))
{
ServicePointManager.ServerCertificateValidationCallback = CheckValidationResult;
request = (HttpWebRequest)WebRequest.Create(item.URL);
SetCerList(item);
request.ClientCertificates.Add(new X509Certificate(item.CerPath));
return;
}
request = (HttpWebRequest)WebRequest.Create(item.URL);
if (item.KeepAlive)
{
request.Headers.GetType().InvokeMember("ChangeInternal", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.InvokeMethod, Type.DefaultBinder, request.Headers, new object[2] { "Connection", "keep-alive" });
}
SetCerList(item);
}
private void SetCerList(HttpItem item)
{
if (item.ClentCertificates == null || item.ClentCertificates.Count <= 0)
{
return;
}
foreach (X509Certificate clentCertificate in item.ClentCertificates)
{
request.ClientCertificates.Add(clentCertificate);
}
}
private void SetCookie(HttpItem item)
{
if (!string.IsNullOrEmpty(item.Cookie))
{
request.Headers[HttpRequestHeader.Cookie] = item.Cookie;
}
if (item.ResultCookieType != ResultCookieType.CookieCollection)
{
return;
}
request.CookieContainer = new CookieContainer();
if (item.CookieCollection != null && item.CookieCollection.Count > 0)
{
if (item.CookieCollection.Count > 20)
{
request.CookieContainer.PerDomainCapacity = item.CookieCollection.Count;
}
request.CookieContainer.Add(item.CookieCollection);
}
}
private void SetPostData(HttpItem item)
{
if (request.Method.Trim().ToLower().Contains("get"))
{
return;
}
if (item.PostEncoding != null)
{
postencoding = item.PostEncoding;
}
byte[] array = null;
if (item.PostDataType == PostDataType.Byte && item.PostdataByte != null && item.PostdataByte.Length != 0)
{
array = new byte[item.PostdataByte.Length];
Array.Copy(item.PostdataByte, array, array.Length);
}
else if (item.PostDataType == PostDataType.FilePath && !string.IsNullOrWhiteSpace(item.Postdata))
{
StreamReader streamReader = new StreamReader(item.Postdata, postencoding);
array = postencoding.GetBytes(streamReader.ReadToEnd());
streamReader.Close();
}
else if (!string.IsNullOrWhiteSpace(item.Postdata))
{
array = postencoding.GetBytes(item.Postdata);
}
if (array != null)
{
request.ContentLength = array.Length;
RequestStreamStae requestStreamStae = new RequestStreamStae();
requestStreamStae.buffer = array;
requestStreamStae.request = request;
ThreadPool.RegisterWaitForSingleObject(request.BeginGetRequestStream(ReadCallback, requestStreamStae).AsyncWaitHandle, TimeoutCallback, request, item.Timeout, executeOnlyOnce: true);
if (allDone != null && !allDone.SafeWaitHandle.IsClosed)
{
allDone.WaitOne(item.Timeout + 1000);
}
if (!requestStreamStae.WriteState)
{
throw new Exception(requestStreamStae.WriteErrMessage);
}
requestStreamStae.Dispose();
}
else
{
request.ContentLength = 0L;
}
}
private void ReadCallback(IAsyncResult asynchronousResult)
{
RequestStreamStae requestStreamStae = null;
try
{
requestStreamStae = (RequestStreamStae)asynchronousResult.AsyncState;
HttpWebRequest httpWebRequest = requestStreamStae.request;
byte[] buffer = requestStreamStae.buffer;
if (buffer != null)
{
using (Stream stream = httpWebRequest.EndGetRequestStream(asynchronousResult))
{
stream.Write(buffer, 0, buffer.Length);
requestStreamStae.WriteState = true;
stream.Close();
return;
}
}
}
catch (Exception ex)
{
if (requestStreamStae != null)
{
requestStreamStae.WriteState = false;
requestStreamStae.WriteErrMessage = ex.Message;
}
}
finally
{
if (allDone != null && !allDone.SafeWaitHandle.IsClosed)
{
allDone.Set();
}
}
}
private void SetProxy(HttpItem item)
{
bool flag = false;
if (!string.IsNullOrWhiteSpace(item.ProxyIp))
{
flag = item.ProxyIp.ToLower().Contains("ieproxy");
}
if (!string.IsNullOrWhiteSpace(item.ProxyIp) && !flag)
{
if (item.ProxyIp.Contains(":"))
{
string[] array = item.ProxyIp.Split(':');
WebProxy webProxy = new WebProxy(array[0].Trim(), Convert.ToInt32(array[1].Trim()));
webProxy.Credentials = new NetworkCredential(item.ProxyUserName, item.ProxyPwd);
request.Proxy = webProxy;
}
else
{
WebProxy webProxy2 = new WebProxy(item.ProxyIp, BypassOnLocal: false);
webProxy2.Credentials = new NetworkCredential(item.ProxyUserName, item.ProxyPwd);
request.Proxy = webProxy2;
}
}
else if (!flag)
{
request.Proxy = item.WebProxy;
if (item.WebProxy is WebProxy)
{
WebProxy webProxy3 = item.WebProxy as WebProxy;
if (webProxy3.Address != null)
{
bool flag2 = false;
if (AppSysConfig.getConfig("LanIPCheck") == "1")
{
flag2 = CheckNetIP(webProxy3.Address.Host);
}
if (!flag2)
{
if (!string.IsNullOrEmpty(webProxy3.Address.UserInfo))
{
Uri address = new Uri(webProxy3.Address.Scheme + "://" + webProxy3.Address.Authority);
string[] array2 = webProxy3.Address.UserInfo.Split(':');
NetworkCredential credentials = new NetworkCredential(array2[0], array2[1]);
request.Proxy = new WebProxy(address, BypassOnLocal: false, null, credentials);
}
}
else
{
request.Proxy = null;
}
}
}
}
if (AppSysConfig.getConfig("LanIPCheck") == "1" && request.Proxy != null && request.Proxy == WebRequest.DefaultWebProxy)
{
request.Proxy = null;
}
}
public bool CheckNetIP(string clientIp)
{
if (long.TryParse(clientIp.Replace(".", ""), out var _))
{
return IpIsRange.TheIpIsRange(clientIp);
}
return false;
}
private bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{
return true;
}
private IPEndPoint BindIPEndPointCallback(ServicePoint servicePoint, IPEndPoint remoteEndPoint, int retryCount)
{
return _IPEndPoint;
}
public void Dispose()
{
if (allDone != null)
{
allDone.Dispose();
}
request = null;
response = null;
}
}
}