@@ -6,7 +6,7 @@ A light weight http(s) proxy server written in C#
66
77Kindly report only issues/bugs here . For programming help or questions use [ StackOverflow] ( http://stackoverflow.com/questions/tagged/titanium-web-proxy ) with the tag Titanium-Web-Proxy.
88
9- ![ alt tag] ( https://raw.githubusercontent.com/titanium007 /Titanium/master/ Titanium.Web.Proxy.Test /Capture.PNG )
9+ ![ alt tag] ( https://raw.githubusercontent.com/justcoding121 /Titanium-Web-Proxy/release/Examples/ Titanium.Web.Proxy.Examples.Basic /Capture.PNG )
1010
1111Features
1212========
@@ -32,102 +32,135 @@ After installing nuget package mark following files to be copied to app director
3232Setup HTTP proxy:
3333
3434``` csharp
35- // listen to client request & server response events
36- ProxyServer .BeforeRequest += OnRequest ;
37- ProxyServer .BeforeResponse += OnResponse ;
38-
39- var explicitEndPoint = new ExplicitProxyEndPoint (IPAddress .Any , 8000 , true ){
40- // Exclude Https addresses you don't want to proxy/cannot be proxied
41- // for example exclude dropbox client which use certificate pinning
42- ExcludedHttpsHostNameRegex = new List <string >() { " dropbox.com" }
43- };
44-
45- // Add an explicit endpoint where the client is aware of the proxy
46- // So client would send request in a proxy friendly manner
47- ProxyServer .AddEndPoint (explicitEndPoint );
48- ProxyServer .Start ();
49-
50- // Only explicit proxies can be set as a system proxy!
51- ProxyServer .SetAsSystemHttpProxy (explicitEndPoint );
52- ProxyServer .SetAsSystemHttpsProxy (explicitEndPoint );
53-
54- foreach (var endPoint in ProxyServer .ProxyEndPoints )
55- Console .WriteLine (" Listening on '{0}' endpoint at Ip {1} and port: {2} " ,
56- endPoint .GetType ().Name , endPoint .IpAddress , endPoint .Port );
35+ ProxyServer .BeforeRequest += OnRequest ;
36+ ProxyServer .BeforeResponse += OnResponse ;
37+ ProxyServer .ServerCertificateValidationCallback += OnCertificateValidation ;
38+
39+ // Exclude Https addresses you don't want to proxy
40+ // Usefull for clients that use certificate pinning
41+ // for example dropbox.com
42+ var explicitEndPoint = new ExplicitProxyEndPoint (IPAddress .Any , 8000 , true )
43+ {
44+ // ExcludedHttpsHostNameRegex = new List<string>() { "google.com", "dropbox.com" }
45+ };
46+
47+ // An explicit endpoint is where the client knows about the existance of a proxy
48+ // So client sends request in a proxy friendly manner
49+ ProxyServer .AddEndPoint (explicitEndPoint );
50+ ProxyServer .Start ();
51+
52+
53+ // Transparent endpoint is usefull for reverse proxying (client is not aware of the existance of proxy)
54+ // A transparent endpoint usually requires a network router port forwarding HTTP(S) packets to this endpoint
55+ // Currently do not support Server Name Indication (It is not currently supported by SslStream class)
56+ // That means that the transparent endpoint will always provide the same Generic Certificate to all HTTPS requests
57+ // In this example only google.com will work for HTTPS requests
58+ // Other sites will receive a certificate mismatch warning on browser
59+ var transparentEndPoint = new TransparentProxyEndPoint (IPAddress .Any , 8001 , true )
60+ {
61+ GenericCertificateName = " google.com"
62+ };
63+ ProxyServer .AddEndPoint (transparentEndPoint );
5764
58- // wait here (You can use something else as a wait function, I am using this as a demo)
59- Console .Read ();
65+ // ProxyServer.UpStreamHttpProxy = new ExternalProxy() { HostName = "localhost", Port = 8888 };
66+ // ProxyServer.UpStreamHttpsProxy = new ExternalProxy() { HostName = "localhost", Port = 8888 };
67+
68+ foreach (var endPoint in ProxyServer .ProxyEndPoints )
69+ Console .WriteLine (" Listening on '{0}' endpoint at Ip {1} and port: {2} " ,
70+ endPoint .GetType ().Name , endPoint .IpAddress , endPoint .Port );
71+
72+ // Only explicit proxies can be set as system proxy!
73+ ProxyServer .SetAsSystemHttpProxy (explicitEndPoint );
74+ ProxyServer .SetAsSystemHttpsProxy (explicitEndPoint );
75+
76+ // wait here (You can use something else as a wait function, I am using this as a demo)
77+ Console .Read ();
6078
61- // Unsubscribe & Quit
62- ProxyServer .BeforeRequest -= OnRequest ;
63- ProxyServer .BeforeResponse -= OnResponse ;
64- ProxyServer .Stop ();
79+ // Unsubscribe & Quit
80+ ProxyServer .BeforeRequest -= OnRequest ;
81+ ProxyServer .BeforeResponse -= OnResponse ;
82+ ProxyServer .Stop ();
6583
6684```
6785Sample request and response event handlers
6886
6987``` csharp
7088
71- // Test On Request, intecept requests
72- // Read browser URL send back to proxy by the injection script in OnResponse event
73- public void OnRequest (object sender , SessionEventArgs e )
89+ // intecept & cancel, redirect or update requests
90+ public async Task OnRequest (object sender , SessionEventArgs e )
7491 {
75- Console .WriteLine (e .ProxySession .Request .Url );
92+ Console .WriteLine (e .WebSession .Request .Url );
7693
77- // read request headers
78- var requestHeaders = e .ProxySession .Request .RequestHeaders ;
94+ // // read request headers
95+ var requestHeaders = e .WebSession .Request .RequestHeaders ;
7996
80- if ((e .RequestMethod . ToUpper () == " POST" || e .RequestMethod .ToUpper () == " PUT" ))
97+ if ((e .WebSession . Request . Method . ToUpper () == " POST" || e .WebSession . Request . Method .ToUpper () == " PUT" ))
8198 {
8299 // Get/Set request body bytes
83- byte [] bodyBytes = e .GetRequestBody ();
84- e .SetRequestBody (bodyBytes );
100+ byte [] bodyBytes = await e .GetRequestBody ();
101+ await e .SetRequestBody (bodyBytes );
85102
86103 // Get/Set request body as string
87- string bodyString = e .GetRequestBodyAsString ();
88- e .SetRequestBodyString (bodyString );
104+ string bodyString = await e .GetRequestBodyAsString ();
105+ await e .SetRequestBodyString (bodyString );
89106
90107 }
91108
92109 // To cancel a request with a custom HTML content
93110 // Filter URL
94-
95- if (e .ProxySession .Request .RequestUri .AbsoluteUri .Contains (" google.com" ))
111+ if (e .WebSession .Request .RequestUri .AbsoluteUri .Contains (" google.com" ))
96112 {
97- e .Ok (" <!DOCTYPE html>" +
98- " <html><body><h1>" +
99- " Website Blocked" +
100- " </h1>" +
101- " <p>Blocked by titanium web proxy.</p>" +
102- " </body>" +
103- " </html>" );
113+ await e .Ok (" <!DOCTYPE html>" +
114+ " <html><body><h1>" +
115+ " Website Blocked" +
116+ " </h1>" +
117+ " <p>Blocked by titanium web proxy.</p>" +
118+ " </body>" +
119+ " </html>" );
120+ }
121+ // Redirect example
122+ if (e .WebSession .Request .RequestUri .AbsoluteUri .Contains (" wikipedia.org" ))
123+ {
124+ await e .Redirect (" https://www.paypal.com" );
104125 }
105126 }
106127
107- // Test script injection
108- // Insert script to read the Browser URL and send it back to proxy
109- public void OnResponse (object sender , SessionEventArgs e )
128+ // Modify response
129+ public async Task OnResponse (object sender , SessionEventArgs e )
110130 {
111-
112131 // read response headers
113- var responseHeaders = e .ProxySession .Response .ResponseHeaders ;
114-
132+ var responseHeaders = e .WebSession .Response .ResponseHeaders ;
115133
116- if (e .RequestMethod == " GET" || e .RequestMethod == " POST" )
134+ // if (!e.ProxySession.Request.Host.Equals("medeczane.sgk.gov.tr")) return;
135+ if (e .WebSession .Request .Method == " GET" || e .WebSession .Request .Method == " POST" )
117136 {
118- if (e .ProxySession .Response .ResponseStatusCode == " 200" )
137+ if (e .WebSession .Response .ResponseStatusCode == " 200" )
119138 {
120- if (e .ProxySession .Response .ContentType .Trim ().ToLower ().Contains (" text/html" ))
139+ if (e .WebSession . Response . ContentType != null && e . WebSession .Response .ContentType .Trim ().ToLower ().Contains (" text/html" ))
121140 {
122- string body = e .GetResponseBodyAsString ();
141+ byte [] bodyBytes = await e .GetResponseBody ();
142+ await e .SetResponseBody (bodyBytes );
143+
144+ string body = await e .GetResponseBodyAsString ();
145+ await e .SetResponseBodyString (body );
123146 }
124147 }
125148 }
126149 }
150+
151+
152+ /// Allows overriding default certificate validation logic
153+ public async Task OnCertificateValidation (object sender , CertificateValidationEventArgs e )
154+ {
155+ // set IsValid to true/false based on Certificate Errors
156+ if (e .SslPolicyErrors == System .Net .Security .SslPolicyErrors .None )
157+ e .IsValid = true ;
158+ else
159+ await e .Session .Ok (" Cannot validate server certificate! Not safe to proceed." );
160+ }
127161```
128162Future roadmap
129163============
130- * Add callbacks for client/server certificate validation/selection
131164* Support mutual authentication
132165* Support Server Name Indication (SNI) for transparent endpoints
133166* Support HTTP 2.0
0 commit comments