using Newtonsoft.Json; using Serilog.Core; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Text; using System.Threading.Tasks; using Titanium.Web.Proxy; using Titanium.Web.Proxy.EventArguments; using Titanium.Web.Proxy.Http; using Titanium.Web.Proxy.Models; using XYY.Core.Standard.TitaniumWebProxy.Model; namespace XYY.Core.Standard.TitaniumWebProxy { public class TitaniumClient { #region 构造 private static Logger _logger; ProxyServer proxyServer; ExplicitProxyEndPoint explicitEndPoint; /// /// 不做使用,没有fiddler好用 /// 数据获取过程中需要做较多空值判断与处理 /// /// [Obsolete("没有fiddler好用")] public TitaniumClient(Logger logger) { _logger = logger; proxyServer = new ProxyServer(); explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, ListenPort, true) { // 在所有https请求上使用自颁发的通用证书 // 通过不为每个启用http的域创建证书来优化性能 // 当代理客户端不需要证书信任时非常有用 //GenericCertificate = new X509Certificate2(Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "genericcert.pfx"), "password") }; Startup(); } #endregion #region 私有 //监听端口,以及代理端口 private const ushort ListenPort = 8877; private static List _hosts = new List() { "services.frayun.com", "ws.fedex.com:443" }; /// /// 证书的处理 /// private void EnsureRootCertificate() { proxyServer.CertificateManager.CertificateEngine = Titanium.Web.Proxy.Network.CertificateEngine.DefaultWindows; proxyServer.CertificateManager.EnsureRootCertificate(); } /// /// 事件处理 /// private void AddAttachEventListeners() { proxyServer.BeforeRequest += OnRequest; proxyServer.BeforeResponse += OnResponse; proxyServer.ServerCertificateValidationCallback += OnCertificateValidation; proxyServer.ClientCertificateSelectionCallback += OnCertificateSelection; } private void CutAttachEventListeners() { proxyServer.BeforeRequest -= OnRequest; proxyServer.BeforeResponse -= OnResponse; proxyServer.ServerCertificateValidationCallback -= OnCertificateValidation; proxyServer.ClientCertificateSelectionCallback -= OnCertificateSelection; } /// /// 命中请求 /// 判断是否需要捕获 /// /// /// private bool isHitRequestFun(SessionEventArgs e) { var isHitRequest = false; if (_hosts.Any(x => x.Contains(e.HttpClient.Request.Host))) // url { isHitRequest = true; } return isHitRequest; } private async Task OnBeforeTunnelConnectRequest(object sender, TunnelConnectSessionEventArgs e) { //await Task.Run(() => //{ // string hostname = e.HttpClient.Request.RequestUri.Host; // if (hostname.Contains("fedex.com")) // { // // 排除不想代理的Https地址 // // 对于使用证书固定的客户端很有用 // // for example dropbox.com // e.DecryptSsl = false; // } //}); } /// /// 请求时发送 /// /// /// /// public async Task OnRequest(object sender, SessionEventArgs e) { //var requestHeaders = e.HttpClient.Request.Headers; //var method = e.HttpClient.Request.Method.ToUpper(); //if (isHitRequestFun(e))//(method == "POST" || method == "PUT" || method == "PATCH") //{ // //// Get/Set request body bytes // //byte[] bodyBytes = await e.GetRequestBody(); // //e.SetRequestBody(bodyBytes); // //// Get/Set request body as string // //string bodyString = await e.GetRequestBodyAsString(); // //e.SetRequestBodyString(bodyString); // // store request // // 这样你就能从响应处理器中找到它 // e.UserData = e.HttpClient.Request; //} //// 取消带有自定义HTML内容的请求 //// Filter URL //if (e.HttpClient.Request.RequestUri.AbsoluteUri.Contains("google.com")) //{ // e.Ok("" + // "

" + // "Website Blocked" + // "

" + // "

Blocked by titanium web proxy.

" + // "" + // ""); //} //// Redirect example //if (e.HttpClient.Request.RequestUri.AbsoluteUri.Contains("wikipedia.org")) //{ // e.Redirect("https://www.paypal.com"); //} } /// /// 返回数据处理 /// /// /// /// public async Task OnResponse(object sender, SessionEventArgs e) { if (isHitRequestFun(e)) { logData(e); } //// read response headers //var responseHeaders = e.HttpClient.Response.Headers; ////if (!e.ProxySession.Request.Host.Equals("medeczane.sgk.gov.tr")) return; //if (e.HttpClient.Request.Method == "GET" || e.HttpClient.Request.Method == "POST") //{ // if (e.HttpClient.Response.StatusCode == 200) // { // if (e.HttpClient.Response.ContentType != null && e.HttpClient.Response.ContentType.Trim().ToLower().Contains("text/html")) // { // byte[] bodyBytes = await e.GetResponseBody(); // e.SetResponseBody(bodyBytes); // string body = await e.GetResponseBodyAsString(); // e.SetResponseBodyString(body); // } // } //} //if (e.UserData != null) //{ // // 从存储在RequestHandler中的UserData属性的访问请求 // var request = (Request)e.UserData; //} } /// /// 允许重写默认的证书验证逻辑 /// /// /// /// public Task OnCertificateValidation(object sender, CertificateValidationEventArgs e) { // 根据证书错误,设置IsValid为真/假 if (e.SslPolicyErrors == System.Net.Security.SslPolicyErrors.None) e.IsValid = true; return Task.CompletedTask; } /// /// 允许在相互身份验证期间重写默认客户端证书选择逻辑 /// /// /// /// public Task OnCertificateSelection(object sender, CertificateSelectionEventArgs e) { // set e.clientCertificate to override return Task.CompletedTask; } #endregion /// /// 退出 /// public void Quit() { CutAttachEventListeners(); proxyServer.Stop(); } public void Startup() { EnsureRootCertificate(); AddAttachEventListeners(); proxyServer.AddEndPoint(explicitEndPoint); proxyServer.Start(); //设置系统代理 //proxyServer.SetAsSystemHttpProxy(explicitEndPoint); //proxyServer.SetAsSystemHttpsProxy(explicitEndPoint); } #region 数据落地 private static void logData(SessionEventArgs e) { TitaniumMessage titaniumMessage = new TitaniumMessage() { Methods = e.HttpClient.Request.Method.ToUpper(), FullUrl = e.HttpClient.Request.Url, ServerConnectionId = e.ServerConnectionId.ToString(), ClientConnectionId = e.ClientConnectionId.ToString(), HostName = e.HttpClient.Request.Host, RequestHeader = e.HttpClient.Request.HeaderText, RequestBody = e.HttpClient.Request.BodyString,//需要做空判断,否则报错 ResponseHeader = e.HttpClient.Response.HeaderText, ResponseBody = e.HttpClient.Response.BodyString, }; _logger.Warning(JsonConvert.SerializeObject(titaniumMessage)); } #endregion } }