195 lines
7.5 KiB
C#
195 lines
7.5 KiB
C#
using CefSharp;
|
|
using CefSharp.Handler;
|
|
using CefSharp.ResponseFilter;
|
|
using CefSharp.WinForms;
|
|
using NaiBa.Util;
|
|
using NaiBa.Util.Extension;
|
|
using NaiBa.Util.Helper;
|
|
using System;
|
|
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
using System.Collections.Specialized;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Security.Cryptography.X509Certificates;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Web;
|
|
|
|
namespace LittleRabbit.Helper
|
|
{
|
|
//public event Action<string, string, string, IRequest> ResourceLoadCompleteEvent; // requestUrl, postData, responseData
|
|
|
|
public class BaseResourceRequestHandler : ResourceRequestHandler
|
|
{
|
|
public string UserAgent = string.Empty;
|
|
public Func<object, string, string, bool> BeforeResourceLoadEvent; // sender, requestUrl, postData, true(表示取消执行)
|
|
public Action<object, string, string, string, IRequest> ResourceLoadCompleteEvent; // sender, requestUrl, postData, responseData
|
|
public Action<object, string, string, string> ResourceRedirectEvent; // sender, requestUrl, postData, redirectUrl
|
|
public string[] ResourceContentTypeRegister = new string[] { "application/json", "javascript", "application/x-www-form-urlencoded", "text/html", "text/plain" };
|
|
|
|
public string GetCharSet(string charSet)
|
|
{
|
|
if (string.IsNullOrEmpty(charSet))
|
|
{
|
|
charSet = "UTF-8";
|
|
}
|
|
return charSet;
|
|
}
|
|
|
|
public string GetPostData(IRequest request)
|
|
{
|
|
string postData = string.Empty;
|
|
if (request.PostData != null && request.PostData.Elements.Any())
|
|
{
|
|
for (int i = 0; i < request.PostData.Elements.Count; i++)
|
|
{
|
|
try
|
|
{
|
|
string charset = GetCharSet(request.GetCharSet());
|
|
postData += request.PostData.Elements[i].GetBody(charset);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogHelper.WriteWithTime(ex);
|
|
}
|
|
}
|
|
}
|
|
return postData;
|
|
}
|
|
}
|
|
|
|
public class CustomResourceRequestHandlerLocal : BaseResourceRequestHandler
|
|
{
|
|
private ConcurrentDictionary<ulong, MemoryStream> responseDict = new ConcurrentDictionary<ulong, MemoryStream>();
|
|
|
|
protected override CefReturnValue OnBeforeResourceLoad(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IRequestCallback callback)
|
|
{
|
|
Uri url;
|
|
if (Uri.TryCreate(request.Url, UriKind.Absolute, out url) == false)
|
|
{
|
|
//If we're unable to parse the Uri then cancel the request
|
|
// avoid throwing any exceptions here as we're being called by unmanaged code
|
|
return CefReturnValue.Cancel;
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(UserAgent))
|
|
{
|
|
var headers = request.Headers;
|
|
headers["User-Agent"] = UserAgent;
|
|
request.Headers = headers;
|
|
}
|
|
|
|
//NOTE: If you do not wish to implement this method returning false is the default behaviour
|
|
// We also suggest you explicitly Dispose of the callback as it wraps an unmanaged resource.
|
|
//callback.Dispose();
|
|
//return false;
|
|
|
|
//NOTE: When executing the callback in an async fashion need to check to see if it's disposed
|
|
if (!callback.IsDisposed)
|
|
{
|
|
using (callback)
|
|
{
|
|
if (request.Method == "POST")
|
|
{
|
|
try
|
|
{
|
|
string postData = GetPostData(request);
|
|
bool? result = BeforeResourceLoadEvent?.Invoke(chromiumWebBrowser, request.Url, postData);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogHelper.WriteWithTime(ex);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return CefReturnValue.Continue;
|
|
}
|
|
|
|
protected override void OnResourceRedirect(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response, ref string newUrl)
|
|
{
|
|
try
|
|
{
|
|
if (ResourceRedirectEvent != null)
|
|
{
|
|
string postData = GetPostData(request);
|
|
ResourceRedirectEvent.Invoke(chromiumWebBrowser, request.Url, postData, newUrl);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogHelper.WriteWithTime(ex);
|
|
}
|
|
}
|
|
|
|
protected override bool OnProtocolExecution(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request)
|
|
{
|
|
return request.Url.StartsWith("mailto");
|
|
}
|
|
|
|
protected override bool OnResourceResponse(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response)
|
|
{
|
|
//NOTE: You cannot modify the response, only the request
|
|
// You can now access the headers
|
|
//var headers = response.Headers;
|
|
|
|
return false;
|
|
}
|
|
|
|
protected override IResponseFilter GetResourceResponseFilter(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response)
|
|
{
|
|
try
|
|
{
|
|
string contentType = response.Headers["Content-Type"];
|
|
if (string.IsNullOrEmpty(contentType))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
if (ResourceContentTypeRegister.Contains(contentType) || ResourceContentTypeRegister.Where(p => contentType.Contains(p)).Any())
|
|
{
|
|
if (ResourceLoadCompleteEvent != null)
|
|
{
|
|
MemoryStream memoryStream = new MemoryStream();
|
|
responseDict.TryAdd(request.Identifier, memoryStream);
|
|
return new StreamResponseFilter(memoryStream);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogHelper.WriteWithTime(ex);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
protected override void OnResourceLoadComplete(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response, UrlRequestStatus status, long receivedContentLength)
|
|
{
|
|
try
|
|
{
|
|
if (responseDict.ContainsKey(request.Identifier))
|
|
{
|
|
MemoryStream memoryStream = null;
|
|
responseDict.TryRemove(request.Identifier, out memoryStream);
|
|
|
|
if (memoryStream != null)
|
|
{
|
|
byte[] data = memoryStream.ToArray();
|
|
|
|
string charset = GetCharSet(response.Charset);
|
|
var responseData = Encoding.GetEncoding(charset).GetString(data);
|
|
|
|
string postData = GetPostData(request);
|
|
ResourceLoadCompleteEvent.Invoke(chromiumWebBrowser, request.Url, postData, responseData, request);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogHelper.WriteWithTime(ex);
|
|
}
|
|
}
|
|
}
|
|
}
|