{"id":13539412,"url":"https://github.com/justcoding121/titanium-web-proxy","last_synced_at":"2025-09-28T20:30:32.401Z","repository":{"id":25393484,"uuid":"28822114","full_name":"justcoding121/titanium-web-proxy","owner":"justcoding121","description":"A cross-platform asynchronous HTTP(S) proxy server in C#.","archived":true,"fork":false,"pushed_at":"2023-06-29T02:39:51.000Z","size":7850,"stargazers_count":1923,"open_issues_count":134,"forks_count":610,"subscribers_count":77,"default_branch":"develop","last_synced_at":"2024-09-21T20:32:25.365Z","etag":null,"topics":["c-sharp","http","http-server","https","proxy-server"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/justcoding121.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2015-01-05T16:58:51.000Z","updated_at":"2024-09-17T04:39:24.000Z","dependencies_parsed_at":"2023-01-14T02:40:14.458Z","dependency_job_id":"1723b802-9b9d-45d1-852c-9bc727309c9a","html_url":"https://github.com/justcoding121/titanium-web-proxy","commit_stats":null,"previous_names":[],"tags_count":152,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/justcoding121%2Ftitanium-web-proxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/justcoding121%2Ftitanium-web-proxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/justcoding121%2Ftitanium-web-proxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/justcoding121%2Ftitanium-web-proxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/justcoding121","download_url":"https://codeload.github.com/justcoding121/titanium-web-proxy/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":219873869,"owners_count":16554521,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c-sharp","http","http-server","https","proxy-server"],"created_at":"2024-08-01T09:01:25.379Z","updated_at":"2025-09-28T20:30:31.777Z","avatar_url":"https://github.com/justcoding121.png","language":"C#","readme":"## Titanium Web Proxy\n\nA lightweight HTTP(S) proxy server written in C#.\n\n[![.NET Core](https://github.com/justcoding121/titanium-web-proxy/actions/workflows/dotnetcore.yml/badge.svg?branch=develop)](https://github.com/justcoding121/titanium-web-proxy/actions/workflows/dotnetcore.yml) [![Join the chat at https://gitter.im/Titanium-Web-Proxy/Lobby](https://badges.gitter.im/Titanium-Web-Proxy/Lobby.svg)](https://gitter.im/Titanium-Web-Proxy/Lobby?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n\nReport bugs or raise issues here. For programming help use [StackOverflow](http://stackoverflow.com/questions/tagged/titanium-web-proxy) with the tag Titanium-Web-Proxy.\n\n* [API Documentation](https://justcoding121.github.io/titanium-web-proxy/docs/api/Titanium.Web.Proxy.ProxyServer.html)\n* [Wiki \u0026 Contribution guidelines](https://github.com/justcoding121/Titanium-Web-Proxy/wiki)\n\n### Features\n\n* Multithreaded and asynchronous proxy employing server connection pooling, certificate cache, and buffer pooling\n* View, modify, redirect and block requests or responses\n* Supports mutual SSL authentication, proxy authentication \u0026 automatic upstream proxy detection\n* Supports kerberos, NTLM authentication over HTTP protocols on windows domain controlled networks\n* SOCKS4/5 Proxy support\n\n### Installation\nInstall by [nuget](https://www.nuget.org/packages/Titanium.Web.Proxy)\n\nFor beta releases on [beta branch](https://github.com/justcoding121/Titanium-Web-Proxy/tree/beta)\n\n    Install-Package Titanium.Web.Proxy -Pre\n\nFor stable releases on [stable branch](https://github.com/justcoding121/Titanium-Web-Proxy/tree/stable)\n\n    Install-Package Titanium.Web.Proxy\n\nSupports\n\n * .NET Standard 2.0 or above\n * .NET Framework 4.5 or above\n\n###  Note to contributors\n\n#### Road map\n\n* Fix [outstanding bugs](https://github.com/justcoding121/Titanium-Web-Proxy/issues?q=is%3Aopen+is%3Aissue+label%3Abug)\n* Support reading request and response body as stream [#823](https://github.com/justcoding121/Titanium-Web-Proxy/issues/823)\n* Stop throwing new exceptions [#634](https://github.com/justcoding121/Titanium-Web-Proxy/issues/634)\n* Support HTTP 2.0 \n\n#### Collaborators\n\nThe owner of this project, [justcoding121](https://github.com/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.\n\n* [honfika](https://github.com/honfika)\n \n### Development environment\n\n#### Windows\n* Visual Studio Code as IDE for .NET\n* Visual Studio 2022 as IDE for .NET Framework/.NET\n\n#### Mac OS\n* Visual Studio Code as IDE for .NET\n* Visual Studio 2022 as IDE for Mono\n\n#### Linux\n* Visual Studio Code as IDE for .NET\n* Mono develop as IDE for Mono\n\n### Usage\n\nRefer the HTTP Proxy Server library in your project and look up the test project to learn usage. \n \nSetup HTTP proxy:\n\n```csharp\nvar proxyServer = new ProxyServer();\n\n// locally trust root certificate used by this proxy \nproxyServer.CertificateManager.TrustRootCertificate(true);\n\n// optionally set the Certificate Engine\n// Under Mono only BouncyCastle will be supported\n//proxyServer.CertificateManager.CertificateEngine = Network.CertificateEngine.BouncyCastle;\n\nproxyServer.BeforeRequest += OnRequest;\nproxyServer.BeforeResponse += OnResponse;\nproxyServer.ServerCertificateValidationCallback += OnCertificateValidation;\nproxyServer.ClientCertificateSelectionCallback += OnCertificateSelection;\n\n\nvar explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, 8000, true)\n{\n    // Use self-issued generic certificate on all https requests\n    // Optimizes performance by not creating a certificate for each https-enabled domain\n    // Useful when certificate trust is not required by proxy clients\n   //GenericCertificate = new X509Certificate2(Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), \"genericcert.pfx\"), \"password\")\n};\n\n// Fired when a CONNECT request is received\nexplicitEndPoint.BeforeTunnelConnectRequest += OnBeforeTunnelConnectRequest;\n\n// An explicit endpoint is where the client knows about the existence of a proxy\n// So client sends request in a proxy friendly manner\nproxyServer.AddEndPoint(explicitEndPoint);\nproxyServer.Start();\n\n// Transparent endpoint is useful for reverse proxy (client is not aware of the existence of proxy)\n// A transparent endpoint usually requires a network router port forwarding HTTP(S) packets or DNS\n// to send data to this endPoint\nvar transparentEndPoint = new TransparentProxyEndPoint(IPAddress.Any, 8001, true)\n{\n    // Generic Certificate hostname to use\n    // when SNI is disabled by client\n    GenericCertificateName = \"google.com\"\n};\n\nproxyServer.AddEndPoint(transparentEndPoint);\n\n//proxyServer.UpStreamHttpProxy = new ExternalProxy() { HostName = \"localhost\", Port = 8888 };\n//proxyServer.UpStreamHttpsProxy = new ExternalProxy() { HostName = \"localhost\", Port = 8888 };\n\nforeach (var endPoint in proxyServer.ProxyEndPoints)\nConsole.WriteLine(\"Listening on '{0}' endpoint at Ip {1} and port: {2} \",\n    endPoint.GetType().Name, endPoint.IpAddress, endPoint.Port);\n\n// Only explicit proxies can be set as system proxy!\nproxyServer.SetAsSystemHttpProxy(explicitEndPoint);\nproxyServer.SetAsSystemHttpsProxy(explicitEndPoint);\n\n// wait here (You can use something else as a wait function, I am using this as a demo)\nConsole.Read();\n\n// Unsubscribe \u0026 Quit\nexplicitEndPoint.BeforeTunnelConnectRequest -= OnBeforeTunnelConnectRequest;\nproxyServer.BeforeRequest -= OnRequest;\nproxyServer.BeforeResponse -= OnResponse;\nproxyServer.ServerCertificateValidationCallback -= OnCertificateValidation;\nproxyServer.ClientCertificateSelectionCallback -= OnCertificateSelection;\n\nproxyServer.Stop();\n    \n```\nSample request and response event handlers\n\n```csharp        \n\nprivate async Task OnBeforeTunnelConnectRequest(object sender, TunnelConnectSessionEventArgs e)\n{\n    string hostname = e.HttpClient.Request.RequestUri.Host;\n\n    if (hostname.Contains(\"dropbox.com\"))\n    {\n         // Exclude Https addresses you don't want to proxy\n         // Useful for clients that use certificate pinning\n         // for example dropbox.com\n         e.DecryptSsl = false;\n    }\n}\n\npublic async Task OnRequest(object sender, SessionEventArgs e)\n{\n    Console.WriteLine(e.HttpClient.Request.Url);\n\n    // read request headers\n    var requestHeaders = e.HttpClient.Request.Headers;\n\n    var method = e.HttpClient.Request.Method.ToUpper();\n    if ((method == \"POST\" || method == \"PUT\" || method == \"PATCH\"))\n    {\n        // Get/Set request body bytes\n        byte[] bodyBytes = await e.GetRequestBody();\n        e.SetRequestBody(bodyBytes);\n\n        // Get/Set request body as string\n        string bodyString = await e.GetRequestBodyAsString();\n        e.SetRequestBodyString(bodyString);\n    \n        // store request \n        // so that you can find it from response handler \n        e.UserData = e.HttpClient.Request;\n    }\n\n    // To cancel a request with a custom HTML content\n    // Filter URL\n    if (e.HttpClient.Request.RequestUri.AbsoluteUri.Contains(\"google.com\"))\n    {\n        e.Ok(\"\u003c!DOCTYPE html\u003e\" +\n            \"\u003chtml\u003e\u003cbody\u003e\u003ch1\u003e\" +\n            \"Website Blocked\" +\n            \"\u003c/h1\u003e\" +\n            \"\u003cp\u003eBlocked by titanium web proxy.\u003c/p\u003e\" +\n            \"\u003c/body\u003e\" +\n            \"\u003c/html\u003e\");\n    }\n\n    // Redirect example\n    if (e.HttpClient.Request.RequestUri.AbsoluteUri.Contains(\"wikipedia.org\"))\n    {\n        e.Redirect(\"https://www.paypal.com\");\n    }\n}\n\n// Modify response\npublic async Task OnResponse(object sender, SessionEventArgs e)\n{\n    // read response headers\n    var responseHeaders = e.HttpClient.Response.Headers;\n\n    //if (!e.ProxySession.Request.Host.Equals(\"medeczane.sgk.gov.tr\")) return;\n    if (e.HttpClient.Request.Method == \"GET\" || e.HttpClient.Request.Method == \"POST\")\n    {\n        if (e.HttpClient.Response.StatusCode == 200)\n        {\n            if (e.HttpClient.Response.ContentType != null \u0026\u0026 e.HttpClient.Response.ContentType.Trim().ToLower().Contains(\"text/html\"))\n            {\n                byte[] bodyBytes = await e.GetResponseBody();\n                e.SetResponseBody(bodyBytes);\n\n                string body = await e.GetResponseBodyAsString();\n                e.SetResponseBodyString(body);\n            }\n        }\n    }\n    \n    if (e.UserData != null)\n    {\n        // access request from UserData property where we stored it in RequestHandler\n        var request = (Request)e.UserData;\n    }\n}\n\n// Allows overriding default certificate validation logic\npublic Task OnCertificateValidation(object sender, CertificateValidationEventArgs e)\n{\n    // set IsValid to true/false based on Certificate Errors\n    if (e.SslPolicyErrors == System.Net.Security.SslPolicyErrors.None)\n        e.IsValid = true;\n\n    return Task.CompletedTask;\n}\n\n// Allows overriding default client certificate selection logic during mutual authentication\npublic Task OnCertificateSelection(object sender, CertificateSelectionEventArgs e)\n{\n    // set e.clientCertificate to override\n    return Task.CompletedTask;\n}\n```\n\n**Console example application screenshot**\n\n![alt tag](https://raw.githubusercontent.com/justcoding121/Titanium-Web-Proxy/develop/examples/Titanium.Web.Proxy.Examples.Basic/Capture.PNG)\n\n**GUI example application screenshot**\n\n![alt tag](https://raw.githubusercontent.com/justcoding121/Titanium-Web-Proxy/develop/examples/Titanium.Web.Proxy.Examples.Wpf/Capture.PNG)\n","funding_links":["https://www.paypal.com"],"categories":["C\\#","C#","\u003ca id=\"d03d494700077f6a65092985c06bf8e8\"\u003e\u003c/a\u003e工具","\u003ca id=\"1a9934198e37d6d06b881705b863afc8\"\u003e\u003c/a\u003e通信\u0026\u0026代理\u0026\u0026反向代理\u0026\u0026隧道"],"sub_categories":["\u003ca id=\"b6f25145e99ea944cbb528a24afaa0be\"\u003e\u003c/a\u003eHTTP\u0026\u0026HTTPS","\u003ca id=\"56acb7c49c828d4715dce57410d490d1\"\u003e\u003c/a\u003e未分类-Proxy"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjustcoding121%2Ftitanium-web-proxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjustcoding121%2Ftitanium-web-proxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjustcoding121%2Ftitanium-web-proxy/lists"}