Titanium Web Proxy是一个强大的开源.NET库,用于截获、查看和修改HTTP/HTTPS流量。本文将详细介绍如何使用Titanium Web Proxy来截获系统中的所有HTTP通信,并提供多个实用示例。
首先,通过NuGet包管理器安装Titanium Web Proxy:
C#Install-Package Titanium.Web.Proxy
或者在你的项目文件中添加以下引用:
XML<PackageReference Include="Titanium.Web.Proxy" Version="3.1.1397" />
以下是一个基本的示例,展示如何设置Titanium Web Proxy并开始截获HTTP流量:
C#using System;
using System.Threading.Tasks;
using Titanium.Web.Proxy;
using Titanium.Web.Proxy.EventArguments;
using Titanium.Web.Proxy.Models;
class Program
{
static async Task Main(string[] args)
{
var proxyServer = new ProxyServer();
// 创建一个显式端点
var explicitEndPoint = new ExplicitProxyEndPoint(System.Net.IPAddress.Any, 8000, true);
// 添加端点
proxyServer.AddEndPoint(explicitEndPoint);
// 注册事件处理程序
proxyServer.BeforeRequest += OnRequest;
proxyServer.BeforeResponse += OnResponse;
// 启动代理服务器
proxyServer.Start();
// 将代理设置为系统代理
proxyServer.SetAsSystemHttpProxy(explicitEndPoint);
proxyServer.SetAsSystemHttpsProxy(explicitEndPoint);
Console.WriteLine("代理服务器已启动在端口 8000。按任意键退出...");
Console.ReadKey();
// 停止代理服务器
proxyServer.Stop();
}
private static Task OnRequest(object sender, SessionEventArgs e)
{
Console.WriteLine($"请求: {e.HttpClient.Request.Url}");
return Task.CompletedTask;
}
private static Task OnResponse(object sender, SessionEventArgs e)
{
Console.WriteLine($"响应: {e.HttpClient.Request.Url}, 状态码: {e.HttpClient.Response.StatusCode}");
return Task.CompletedTask;
}
}
这个基本示例设置了一个代理服务器,监听所有接口的8000端口,并将其设置为系统代理。它会打印出所有请求和响应的基本信息。
Titanium Web Proxy允许你修改请求和响应。以下是一个更复杂的示例:
C#private static async Task OnRequest(object sender, SessionEventArgs e)
{
Console.WriteLine($"请求: {e.HttpClient.Request.Method} {e.HttpClient.Request.Url}");
// 修改请求头
e.HttpClient.Request.Headers.AddHeader("X-Intercepted-By", "Titanium");
// 修改请求体 (如果是POST请求)
if (e.HttpClient.Request.Method == "POST")
{
string body = await e.GetRequestBodyAsString();
body = body.Replace("oldValue", "newValue");
e.SetRequestBodyString(body);
}
// 重定向请求
if (e.HttpClient.Request.RequestUri.Host.Contains("example.com"))
{
e.Redirect("https://google.com");
}
}
private static async Task OnResponse(object sender, SessionEventArgs e)
{
Console.WriteLine($"响应: {e.HttpClient.Request.Url}, 状态码: {e.HttpClient.Response.StatusCode}");
// 修改响应头
e.HttpClient.Response.Headers.AddHeader("X-Proxy-Modified", "True");
// 修改响应体
if (e.HttpClient.Response.ContentType != null && e.HttpClient.Response.ContentType.Trim().ToLower().Contains("text/html"))
{
string body = await e.GetResponseBodyAsString();
body = body.Replace("</body>", "<script>alert('Intercepted by Titanium!');</script></body>");
e.SetResponseBodyString(body);
}
}
Titanium Web Proxy可以解密HTTPS流量。默认情况下,它会为每个域生成一个自签名证书。你可以自定义这个行为:
TypeScript// 在Main方法中
proxyServer.CertificateManager.CreateRootCertificate(false);
proxyServer.CertificateManager.TrustRootCertificate(true);
// 可选:使用自定义证书
// var certificate = new X509Certificate2("path_to_pfx_file", "password");
// proxyServer.CertificateManager.RootCertificate = certificate;
// 设置服务器证书验证回调
proxyServer.ServerCertificateValidationCallback += OnCertificateValidation;
// ...
private static Task OnCertificateValidation(object sender, CertificateValidationEventArgs e)
{
// 总是信任远程证书
e.IsValid = true;
return Task.CompletedTask;
}
你可以实现自定义的证书验证逻辑:
C#private static Task OnCertificateValidation(object sender, CertificateValidationEventArgs e)
{
if (e.SslPolicyErrors == System.Net.Security.SslPolicyErrors.None)
{
e.IsValid = true;
}
else
{
// 自定义验证逻辑
if (e.ServerCertificate.Subject.Contains("trusted-domain.com"))
{
e.IsValid = true;
}
else
{
e.IsValid = false;
}
}
return Task.CompletedTask;
}
Titanium Web Proxy也支持拦截WebSocket连接:
C#private static async Task OnRequest(object sender, SessionEventArgs e)
{
if (e.HttpClient.Request.Method == "CONNECT" && e.HttpClient.ConnectRequest.TunnelType == TunnelType.Websocket)
{
Console.WriteLine($"WebSocket连接: {e.HttpClient.Request.Url}");
// 你可以在这里修改WebSocket握手请求
e.HttpClient.Request.Headers.AddHeader("X-WebSocket-Intercepted", "True");
// 如果你想拦截WebSocket消息,可以这样做:
e.DataReceived += OnWebSocketDataReceived;
e.DataSent += OnWebSocketDataSent;
}
}
private static void OnWebSocketDataReceived(object sender, DataEventArgs e)
{
Console.WriteLine($"接收到WebSocket数据: {e.Buffer.Length} 字节");
// 在这里处理接收到的WebSocket数据
}
private static void OnWebSocketDataSent(object sender, DataEventArgs e)
{
Console.WriteLine($"发送WebSocket数据: {e.Buffer.Length} 字节");
// 在这里处理发送的WebSocket数据
}
对于高流量场景,可以考虑以下优化:
异步处理:
C#private static async Task OnRequest(object sender, SessionEventArgs e)
{
// 对于耗时操作,使用Task.Run来避免阻塞
await Task.Run(async () =>
{
// 执行耗时操作
await SomeTimeConsumingOperation();
});
}
选择性拦截:
C#private static Task OnRequest(object sender, SessionEventArgs e)
{
// 只拦截特定域名的请求
if (e.HttpClient.Request.RequestUri.Host.Contains("example.com"))
{
// 执行拦截逻辑
}
else
{
// 对于其他请求,直接放行
}
return Task.CompletedTask;
}
C#private static async Task OnRequest(object sender, SessionEventArgs e)
{
try
{
// 处理请求
}
catch (Exception ex)
{
Console.WriteLine($"处理请求时发生错误: {ex.Message}");
// 可以选择让请求继续,或者返回一个错误响应
e.Ok();
}
}
C#proxyServer.OnServerConnectionCreate+= OnServerConnectionCreate;
private static void OnServerConnectionCreate(object sender, Socket e)
{
Console.WriteLine($"创建新连接,当前连接数: {proxyServer.ClientConnectionCount}");
}
通过遵循这些最佳实践和注意事项,你可以构建一个强大、高效且可靠的HTTP拦截系统。记住,拦截HTTP流量是一个强大的功能,应该谨慎使用,并始终考虑到安全性和隐私问题。
本文作者:rick
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!