123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 |
- 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;
- /// <summary>
- /// 不做使用,没有fiddler好用
- /// 数据获取过程中需要做较多空值判断与处理
- /// </summary>
- /// <param name="logger"></param>
- [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<string> _hosts = new List<string>() { "services.frayun.com", "ws.fedex.com:443" };
- /// <summary>
- /// 证书的处理
- /// </summary>
- private void EnsureRootCertificate()
- {
- proxyServer.CertificateManager.CertificateEngine = Titanium.Web.Proxy.Network.CertificateEngine.DefaultWindows;
- proxyServer.CertificateManager.EnsureRootCertificate();
- }
- /// <summary>
- /// 事件处理
- /// </summary>
- 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;
- }
- /// <summary>
- /// 命中请求
- /// 判断是否需要捕获
- /// </summary>
- /// <param name="oSession"></param>
- /// <returns></returns>
- 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;
- // }
- //});
- }
- /// <summary>
- /// 请求时发送
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- /// <returns></returns>
- 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("<!DOCTYPE html>" +
- // "<html><body><h1>" +
- // "Website Blocked" +
- // "</h1>" +
- // "<p>Blocked by titanium web proxy.</p>" +
- // "</body>" +
- // "</html>");
- //}
- //// Redirect example
- //if (e.HttpClient.Request.RequestUri.AbsoluteUri.Contains("wikipedia.org"))
- //{
- // e.Redirect("https://www.paypal.com");
- //}
- }
- /// <summary>
- /// 返回数据处理
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- /// <returns></returns>
- 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;
- //}
- }
- /// <summary>
- /// 允许重写默认的证书验证逻辑
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- /// <returns></returns>
- public Task OnCertificateValidation(object sender, CertificateValidationEventArgs e)
- {
- // 根据证书错误,设置IsValid为真/假
- if (e.SslPolicyErrors == System.Net.Security.SslPolicyErrors.None)
- e.IsValid = true;
- return Task.CompletedTask;
- }
- /// <summary>
- /// 允许在相互身份验证期间重写默认客户端证书选择逻辑
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- /// <returns></returns>
- public Task OnCertificateSelection(object sender, CertificateSelectionEventArgs e)
- {
- // set e.clientCertificate to override
- return Task.CompletedTask;
- }
- #endregion
- /// <summary>
- /// 退出
- /// </summary>
- 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
- }
- }
|