11## Titanium Web Proxy
22
3- ### Note: This Project is no longer maintained. Any pull requests for fixes are welcome.
4-
53A lightweight HTTP(S) proxy server written in C#.
64
75<a href =" https://ci.appveyor.com/project/justcoding121/titanium-web-proxy " >![ Build Status] ( https://ci.appveyor.com/api/projects/status/p5vvtbpx9yp250ol?svg=true ) </a > [ ![ 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&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge )
@@ -32,7 +30,7 @@ For stable releases on [stable branch](https://github.com/justcoding121/Titanium
3230Supports
3331
3432 * .Net Standard 2.0 or above
35- * .Net Framework 4.5 or above
33+ * .Net Framework 4.6.1 or above
3634
3735### Development environment
3836
@@ -57,11 +55,11 @@ Setup HTTP proxy:
5755``` csharp
5856var proxyServer = new ProxyServer ();
5957
60- // locally trust root certificate used by this proxy
58+ // locally trust root certificate used by this proxy
6159proxyServer .CertificateManager .TrustRootCertificate = true ;
6260
63- // optionally set the Certificate Engine
64- // Under Mono only BouncyCastle will be supported
61+ // optionally set the Certificate Engine
62+ // Under Mono only BouncyCastle will be supported
6563// proxyServer.CertificateManager.CertificateEngine = Network.CertificateEngine.BouncyCastle;
6664
6765proxyServer .BeforeRequest += OnRequest ;
@@ -72,28 +70,28 @@ proxyServer.ClientCertificateSelectionCallback += OnCertificateSelection;
7270
7371var explicitEndPoint = new ExplicitProxyEndPoint (IPAddress .Any , 8000 , true )
7472{
75- // Use self-issued generic certificate on all https requests
76- // Optimizes performance by not creating a certificate for each https-enabled domain
77- // Useful when certificate trust is not required by proxy clients
78- // GenericCertificate = new X509Certificate2(Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "genericcert.pfx"), "password")
73+ // Use self-issued generic certificate on all https requests
74+ // Optimizes performance by not creating a certificate for each https-enabled domain
75+ // Useful when certificate trust is not required by proxy clients
76+ // GenericCertificate = new X509Certificate2(Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "genericcert.pfx"), "password")
7977 };
8078
81- // Fired when a CONNECT request is received
79+ // Fired when a CONNECT request is received
8280explicitEndPoint .BeforeTunnelConnect += OnBeforeTunnelConnect ;
8381
84- // An explicit endpoint is where the client knows about the existence of a proxy
85- // So client sends request in a proxy friendly manner
82+ // An explicit endpoint is where the client knows about the existence of a proxy
83+ // So client sends request in a proxy friendly manner
8684proxyServer .AddEndPoint (explicitEndPoint );
8785proxyServer .Start ();
8886
89- // Transparent endpoint is useful for reverse proxy (client is not aware of the existence of proxy)
90- // A transparent endpoint usually requires a network router port forwarding HTTP(S) packets or DNS
91- // to send data to this endPoint
87+ // Transparent endpoint is useful for reverse proxy (client is not aware of the existence of proxy)
88+ // A transparent endpoint usually requires a network router port forwarding HTTP(S) packets or DNS
89+ // to send data to this endPoint
9290var transparentEndPoint = new TransparentProxyEndPoint (IPAddress .Any , 8001 , true )
9391{
94- // Generic Certificate hostname to use
95- // when SNI is disabled by client
96- GenericCertificateName = " google.com"
92+ // Generic Certificate hostname to use
93+ // when SNI is disabled by client
94+ GenericCertificateName = " google.com"
9795};
9896
9997proxyServer .AddEndPoint (transparentEndPoint );
@@ -105,36 +103,36 @@ foreach (var endPoint in proxyServer.ProxyEndPoints)
105103Console .WriteLine (" Listening on '{0}' endpoint at Ip {1} and port: {2} " ,
106104 endPoint .GetType ().Name , endPoint .IpAddress , endPoint .Port );
107105
108- // Only explicit proxies can be set as system proxy!
106+ // Only explicit proxies can be set as system proxy!
109107proxyServer .SetAsSystemHttpProxy (explicitEndPoint );
110108proxyServer .SetAsSystemHttpsProxy (explicitEndPoint );
111109
112- // wait here (You can use something else as a wait function, I am using this as a demo)
110+ // wait here (You can use something else as a wait function, I am using this as a demo)
113111Console .Read ();
114112
115- // Unsubscribe & Quit
113+ // Unsubscribe & Quit
116114explicitEndPoint .BeforeTunnelConnect -= OnBeforeTunnelConnect ;
117115proxyServer .BeforeRequest -= OnRequest ;
118116proxyServer .BeforeResponse -= OnResponse ;
119117proxyServer .ServerCertificateValidationCallback -= OnCertificateValidation ;
120118proxyServer .ClientCertificateSelectionCallback -= OnCertificateSelection ;
121119
122120proxyServer .Stop ();
123-
121+
124122```
125123Sample request and response event handlers
126124
127- ``` csharp
125+ ``` csharp
128126
129127private async Task OnBeforeTunnelConnectRequest (object sender , TunnelConnectSessionEventArgs e )
130128{
131129 string hostname = e .HttpClient .Request .RequestUri .Host ;
132130
133131 if (hostname .Contains (" dropbox.com" ))
134132 {
135- // Exclude Https addresses you don't want to proxy
136- // Useful for clients that use certificate pinning
137- // for example dropbox.com
133+ // Exclude Https addresses you don't want to proxy
134+ // Useful for clients that use certificate pinning
135+ // for example dropbox.com
138136 e .DecryptSsl = false ;
139137 }
140138}
@@ -143,88 +141,88 @@ public async Task OnRequest(object sender, SessionEventArgs e)
143141{
144142 Console .WriteLine (e .HttpClient .Request .Url );
145143
146- // // read request headers
144+ // read request headers
147145 var requestHeaders = e .HttpClient .Request .RequestHeaders ;
148146
149147 var method = e .HttpClient .Request .Method .ToUpper ();
150148 if ((method == " POST" || method == " PUT" || method == " PATCH" ))
151149 {
152- // Get/Set request body bytes
153- byte [] bodyBytes = await e .GetRequestBody ();
154- await e .SetRequestBody (bodyBytes );
155-
156- // Get/Set request body as string
157- string bodyString = await e .GetRequestBodyAsString ();
158- await e .SetRequestBodyString (bodyString );
159-
160- // store request
161- // so that you can find it from response handler
162- e .UserData = e .HttpClient .Request ;
150+ // Get/Set request body bytes
151+ byte [] bodyBytes = await e .GetRequestBody ();
152+ await e .SetRequestBody (bodyBytes );
153+
154+ // Get/Set request body as string
155+ string bodyString = await e .GetRequestBodyAsString ();
156+ await e .SetRequestBodyString (bodyString );
157+
158+ // store request
159+ // so that you can find it from response handler
160+ e .UserData = e .HttpClient .Request ;
163161 }
164162
165- // To cancel a request with a custom HTML content
166- // Filter URL
163+ // To cancel a request with a custom HTML content
164+ // Filter URL
167165 if (e .HttpClient .Request .RequestUri .AbsoluteUri .Contains (" google.com" ))
168166 {
169- e .Ok (" <!DOCTYPE html>" +
170- " <html><body><h1>" +
171- " Website Blocked" +
172- " </h1>" +
173- " <p>Blocked by titanium web proxy.</p>" +
174- " </body>" +
175- " </html>" );
167+ e .Ok (" <!DOCTYPE html>" +
168+ " <html><body><h1>" +
169+ " Website Blocked" +
170+ " </h1>" +
171+ " <p>Blocked by titanium web proxy.</p>" +
172+ " </body>" +
173+ " </html>" );
176174 }
177- // Redirect example
175+
176+ // Redirect example
178177 if (e .HttpClient .Request .RequestUri .AbsoluteUri .Contains (" wikipedia.org" ))
179178 {
180- e .Redirect (" https://www.paypal.com" );
179+ e .Redirect (" https://www.paypal.com" );
181180 }
182181}
183182
184- // Modify response
183+ // Modify response
185184public async Task OnResponse (object sender , SessionEventArgs e )
186185{
187- // read response headers
186+ // read response headers
188187 var responseHeaders = e .HttpClient .Response .ResponseHeaders ;
189188
190189 // if (!e.ProxySession.Request.Host.Equals("medeczane.sgk.gov.tr")) return;
191190 if (e .HttpClient .Request .Method == " GET" || e .HttpClient .Request .Method == " POST" )
192191 {
193- if (e .HttpClient .Response .ResponseStatusCode == " 200" )
194- {
195- if (e .HttpClient .Response .ContentType != null && e .HttpClient .Response .ContentType .Trim ().ToLower ().Contains (" text/html" ))
196- {
197- byte [] bodyBytes = await e .GetResponseBody ();
198- await e .SetResponseBody (bodyBytes );
199-
200- string body = await e .GetResponseBodyAsString ();
201- await e .SetResponseBodyString (body );
202- }
203- }
192+ if (e .HttpClient .Response .ResponseStatusCode == " 200" )
193+ {
194+ if (e .HttpClient .Response .ContentType != null && e .HttpClient .Response .ContentType .Trim ().ToLower ().Contains (" text/html" ))
195+ {
196+ byte [] bodyBytes = await e .GetResponseBody ();
197+ await e .SetResponseBody (bodyBytes );
198+
199+ string body = await e .GetResponseBodyAsString ();
200+ await e .SetResponseBodyString (body );
201+ }
202+ }
204203 }
205204
206- if (e .UserData != null )
205+ if (e .UserData != null )
207206 {
208- // access request from UserData property where we stored it in RequestHandler
209- var request = (Request )e .UserData ;
207+ // access request from UserData property where we stored it in RequestHandler
208+ var request = (Request )e .UserData ;
210209 }
211-
212210}
213211
214- /// Allows overriding default certificate validation logic
212+ // Allows overriding default certificate validation logic
215213public Task OnCertificateValidation (object sender , CertificateValidationEventArgs e )
216214{
217- // set IsValid to true/false based on Certificate Errors
215+ // set IsValid to true/false based on Certificate Errors
218216 if (e .SslPolicyErrors == System .Net .Security .SslPolicyErrors .None )
219- e .IsValid = true ;
217+ e .IsValid = true ;
220218
221219 return Task .FromResult (0 );
222220}
223221
224- /// Allows overriding default client certificate selection logic during mutual authentication
222+ // Allows overriding default client certificate selection logic during mutual authentication
225223public Task OnCertificateSelection (object sender , CertificateSelectionEventArgs e )
226224{
227- // set e.clientCertificate to override
225+ // set e.clientCertificate to override
228226 return Task .FromResult (0 );
229227}
230228```
0 commit comments