项目作者: justcoding121

项目描述 :
A cross-platform asynchronous HTTP(S) proxy server in C#.
高级语言: C#
项目地址: git://github.com/justcoding121/titanium-web-proxy.git
创建时间: 2015-01-05T16:58:51Z
项目社区:https://github.com/justcoding121/titanium-web-proxy

开源协议:MIT License

下载


Titanium Web Proxy

A lightweight HTTP(S) proxy server written in C#.

.NET Core Join the chat at https://gitter.im/Titanium-Web-Proxy/Lobby

Report bugs or raise issues here. For programming help use StackOverflow with the tag Titanium-Web-Proxy.

Features

  • Multithreaded and asynchronous proxy employing server connection pooling, certificate cache, and buffer pooling
  • View, modify, redirect and block requests or responses
  • Supports mutual SSL authentication, proxy authentication & automatic upstream proxy detection
  • Supports kerberos, NTLM authentication over HTTP protocols on windows domain controlled networks
  • SOCKS4/5 Proxy support

Installation

Install by nuget

For beta releases on beta branch

  1. Install-Package Titanium.Web.Proxy -Pre

For stable releases on stable branch

  1. Install-Package Titanium.Web.Proxy

Supports

  • .NET Standard 2.0 or above
  • .NET Framework 4.5 or above

Note to contributors

Road map

  • Fix outstanding bugs
  • Support reading request and response body as stream #823
  • Stop throwing new exceptions #634
  • Support HTTP 2.0

Collaborators

The owner of this project, justcoding121, is considered to be inactive from this project due to his busy work schedule. However, we have a collaborator listed below who time and again shows up to maintain this project. Please create pull requests prioritizing bug fixes for the attention of collaborators.

Development environment

Windows

  • Visual Studio Code as IDE for .NET
  • Visual Studio 2022 as IDE for .NET Framework/.NET

Mac OS

  • Visual Studio Code as IDE for .NET
  • Visual Studio 2022 as IDE for Mono

Linux

  • Visual Studio Code as IDE for .NET
  • Mono develop as IDE for Mono

Usage

Refer the HTTP Proxy Server library in your project and look up the test project to learn usage.

Setup HTTP proxy:

  1. var proxyServer = new ProxyServer();
  2. // locally trust root certificate used by this proxy
  3. proxyServer.CertificateManager.TrustRootCertificate(true);
  4. // optionally set the Certificate Engine
  5. // Under Mono only BouncyCastle will be supported
  6. //proxyServer.CertificateManager.CertificateEngine = Network.CertificateEngine.BouncyCastle;
  7. proxyServer.BeforeRequest += OnRequest;
  8. proxyServer.BeforeResponse += OnResponse;
  9. proxyServer.ServerCertificateValidationCallback += OnCertificateValidation;
  10. proxyServer.ClientCertificateSelectionCallback += OnCertificateSelection;
  11. var explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, 8000, true)
  12. {
  13. // Use self-issued generic certificate on all https requests
  14. // Optimizes performance by not creating a certificate for each https-enabled domain
  15. // Useful when certificate trust is not required by proxy clients
  16. //GenericCertificate = new X509Certificate2(Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "genericcert.pfx"), "password")
  17. };
  18. // Fired when a CONNECT request is received
  19. explicitEndPoint.BeforeTunnelConnectRequest += OnBeforeTunnelConnectRequest;
  20. // An explicit endpoint is where the client knows about the existence of a proxy
  21. // So client sends request in a proxy friendly manner
  22. proxyServer.AddEndPoint(explicitEndPoint);
  23. proxyServer.Start();
  24. // Transparent endpoint is useful for reverse proxy (client is not aware of the existence of proxy)
  25. // A transparent endpoint usually requires a network router port forwarding HTTP(S) packets or DNS
  26. // to send data to this endPoint
  27. var transparentEndPoint = new TransparentProxyEndPoint(IPAddress.Any, 8001, true)
  28. {
  29. // Generic Certificate hostname to use
  30. // when SNI is disabled by client
  31. GenericCertificateName = "google.com"
  32. };
  33. proxyServer.AddEndPoint(transparentEndPoint);
  34. //proxyServer.UpStreamHttpProxy = new ExternalProxy() { HostName = "localhost", Port = 8888 };
  35. //proxyServer.UpStreamHttpsProxy = new ExternalProxy() { HostName = "localhost", Port = 8888 };
  36. foreach (var endPoint in proxyServer.ProxyEndPoints)
  37. Console.WriteLine("Listening on '{0}' endpoint at Ip {1} and port: {2} ",
  38. endPoint.GetType().Name, endPoint.IpAddress, endPoint.Port);
  39. // Only explicit proxies can be set as system proxy!
  40. proxyServer.SetAsSystemHttpProxy(explicitEndPoint);
  41. proxyServer.SetAsSystemHttpsProxy(explicitEndPoint);
  42. // wait here (You can use something else as a wait function, I am using this as a demo)
  43. Console.Read();
  44. // Unsubscribe & Quit
  45. explicitEndPoint.BeforeTunnelConnectRequest -= OnBeforeTunnelConnectRequest;
  46. proxyServer.BeforeRequest -= OnRequest;
  47. proxyServer.BeforeResponse -= OnResponse;
  48. proxyServer.ServerCertificateValidationCallback -= OnCertificateValidation;
  49. proxyServer.ClientCertificateSelectionCallback -= OnCertificateSelection;
  50. proxyServer.Stop();

Sample request and response event handlers

  1. private async Task OnBeforeTunnelConnectRequest(object sender, TunnelConnectSessionEventArgs e)
  2. {
  3. string hostname = e.HttpClient.Request.RequestUri.Host;
  4. if (hostname.Contains("dropbox.com"))
  5. {
  6. // Exclude Https addresses you don't want to proxy
  7. // Useful for clients that use certificate pinning
  8. // for example dropbox.com
  9. e.DecryptSsl = false;
  10. }
  11. }
  12. public async Task OnRequest(object sender, SessionEventArgs e)
  13. {
  14. Console.WriteLine(e.HttpClient.Request.Url);
  15. // read request headers
  16. var requestHeaders = e.HttpClient.Request.Headers;
  17. var method = e.HttpClient.Request.Method.ToUpper();
  18. if ((method == "POST" || method == "PUT" || method == "PATCH"))
  19. {
  20. // Get/Set request body bytes
  21. byte[] bodyBytes = await e.GetRequestBody();
  22. e.SetRequestBody(bodyBytes);
  23. // Get/Set request body as string
  24. string bodyString = await e.GetRequestBodyAsString();
  25. e.SetRequestBodyString(bodyString);
  26. // store request
  27. // so that you can find it from response handler
  28. e.UserData = e.HttpClient.Request;
  29. }
  30. // To cancel a request with a custom HTML content
  31. // Filter URL
  32. if (e.HttpClient.Request.RequestUri.AbsoluteUri.Contains("google.com"))
  33. {
  34. e.Ok("<!DOCTYPE html>" +
  35. "<html><body><h1>" +
  36. "Website Blocked" +
  37. "</h1>" +
  38. "<p>Blocked by titanium web proxy.</p>" +
  39. "</body>" +
  40. "</html>");
  41. }
  42. // Redirect example
  43. if (e.HttpClient.Request.RequestUri.AbsoluteUri.Contains("wikipedia.org"))
  44. {
  45. e.Redirect("https://www.paypal.com");
  46. }
  47. }
  48. // Modify response
  49. public async Task OnResponse(object sender, SessionEventArgs e)
  50. {
  51. // read response headers
  52. var responseHeaders = e.HttpClient.Response.Headers;
  53. //if (!e.ProxySession.Request.Host.Equals("medeczane.sgk.gov.tr")) return;
  54. if (e.HttpClient.Request.Method == "GET" || e.HttpClient.Request.Method == "POST")
  55. {
  56. if (e.HttpClient.Response.StatusCode == 200)
  57. {
  58. if (e.HttpClient.Response.ContentType != null && e.HttpClient.Response.ContentType.Trim().ToLower().Contains("text/html"))
  59. {
  60. byte[] bodyBytes = await e.GetResponseBody();
  61. e.SetResponseBody(bodyBytes);
  62. string body = await e.GetResponseBodyAsString();
  63. e.SetResponseBodyString(body);
  64. }
  65. }
  66. }
  67. if (e.UserData != null)
  68. {
  69. // access request from UserData property where we stored it in RequestHandler
  70. var request = (Request)e.UserData;
  71. }
  72. }
  73. // Allows overriding default certificate validation logic
  74. public Task OnCertificateValidation(object sender, CertificateValidationEventArgs e)
  75. {
  76. // set IsValid to true/false based on Certificate Errors
  77. if (e.SslPolicyErrors == System.Net.Security.SslPolicyErrors.None)
  78. e.IsValid = true;
  79. return Task.CompletedTask;
  80. }
  81. // Allows overriding default client certificate selection logic during mutual authentication
  82. public Task OnCertificateSelection(object sender, CertificateSelectionEventArgs e)
  83. {
  84. // set e.clientCertificate to override
  85. return Task.CompletedTask;
  86. }

Console example application screenshot

alt tag

GUI example application screenshot

alt tag