1、安装引用Titanium.Web.Proxy
Titanium Web Proxy:https://github.com/justcoding121/Titanium-Web-Proxy
通过NuGet获取Titanium.Web.Proxy
1)使用Nuget管理控制台
将Titanium.Web.Proxy
集成到项目中的最简单方法是使用NuGet。您可以通过打开包管理器控制台(PM)并键入以下语句来安装Titanium.Web.Proxy
:
Install-Package Titanium.Web.Proxy
2)使用Nuget图形管理器
使用Nuget的界面的管理器搜索"Titanium.Web.Proxy"
=> 找到点出点击"安装"
。
3)使用.NET CLI命令安装
> dotnet add TodoApi.csproj package Titanium.Web.Proxy
相关文档:VS(Visual Studio)中Nuget的使用
2、使用示例代码
1)安装配置HTTP proxy
var proxyServer = new ProxyServer(); // 此代理使用的本地信任根证书 //proxyServer.CertificateManager.TrustRootCertificate = true;
//proxyServer.CertificateManager.TrustRootCertificate(true); proxyServer.CertificateManager.CertificateEngine = Titanium.Web.Proxy.Network.CertificateEngine.DefaultWindows; proxyServer.CertificateManager.EnsureRootCertificate(); // 可选地设置证书引擎 // 在Mono之下,只有BouncyCastle将得到支持 //proxyServer.CertificateManager.CertificateEngine = Network.CertificateEngine.BouncyCastle; proxyServer.BeforeRequest += OnRequest; proxyServer.BeforeResponse += OnResponse; proxyServer.ServerCertificateValidationCallback += OnCertificateValidation; proxyServer.ClientCertificateSelectionCallback += OnCertificateSelection; var explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, 8000, true) { // 在所有https请求上使用自颁发的通用证书 // 通过不为每个启用http的域创建证书来优化性能 // 当代理客户端不需要证书信任时非常有用 //GenericCertificate = new X509Certificate2(Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "genericcert.pfx"), "password") }; // 当接收到连接请求时触发 explicitEndPoint.BeforeTunnelConnect += OnBeforeTunnelConnect; // explicit endpoint 是客户端知道代理存在的地方 // 因此,客户端以代理友好的方式发送请求 proxyServer.AddEndPoint(explicitEndPoint); proxyServer.Start(); // 透明endpoint 对于反向代理很有用(客户端不知道代理的存在) // 透明endpoint 通常需要一个网络路由器端口来转发HTTP(S)包或DNS // 发送数据到此endpoint var transparentEndPoint = new TransparentProxyEndPoint(IPAddress.Any, 8001, true) { // 要使用的通用证书主机名 // 当SNI被客户端禁用时 GenericCertificateName = "google.com" }; proxyServer.AddEndPoint(transparentEndPoint); //proxyServer.UpStreamHttpProxy = new ExternalProxy() { HostName = "localhost", Port = 8888 }; //proxyServer.UpStreamHttpsProxy = new ExternalProxy() { HostName = "localhost", Port = 8888 }; foreach (var endPoint in proxyServer.ProxyEndPoints) Console.WriteLine("Listening on '{0}' endpoint at Ip {1} and port: {2} ", endPoint.GetType().Name, endPoint.IpAddress, endPoint.Port); // 只有显式代理可以设置为系统代理! proxyServer.SetAsSystemHttpProxy(explicitEndPoint); proxyServer.SetAsSystemHttpsProxy(explicitEndPoint); // 在这里等待(你可以使用其他的函数作为等待函数,我用这个作为演示) Console.Read();
2) 停止退出
// Unsubscribe & Quit explicitEndPoint.BeforeTunnelConnect -= OnBeforeTunnelConnect; proxyServer.BeforeRequest -= OnRequest; proxyServer.BeforeResponse -= OnResponse; proxyServer.ServerCertificateValidationCallback -= OnCertificateValidation; proxyServer.ClientCertificateSelectionCallback -= OnCertificateSelection; proxyServer.Stop();
3)请求和响应事件处理
private async Task OnBeforeTunnelConnectRequest(object sender, TunnelConnectSessionEventArgs e) { await Task.Run(() => { string hostname = e.HttpClient.Request.RequestUri.Host; if (hostname.Contains("dropbox.com")) { // 排除您不想代理的Https地址 // 对于使用证书固定的客户端很有用 // for example dropbox.com e.DecryptSsl = false; } }); } public async Task OnRequest(object sender, SessionEventArgs e) { Console.WriteLine(e.HttpClient.Request.Url); // read request headers var requestHeaders = e.HttpClient.Request.Headers; var method = e.HttpClient.Request.Method.ToUpper(); if ((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"); } } // Modify response public async Task OnResponse(object sender, SessionEventArgs 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; }