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;
}