@@ -6,7 +6,7 @@ A light weight http(s) proxy server written in C#
6
6
7
7
Kindly 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.
8
8
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 )
10
10
11
11
Features
12
12
========
@@ -32,102 +32,135 @@ After installing nuget package mark following files to be copied to app director
32
32
Setup HTTP proxy:
33
33
34
34
``` 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 );
57
64
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 ();
60
78
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 ();
65
83
66
84
```
67
85
Sample request and response event handlers
68
86
69
87
``` csharp
70
88
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 )
74
91
{
75
- Console .WriteLine (e .ProxySession .Request .Url );
92
+ Console .WriteLine (e .WebSession .Request .Url );
76
93
77
- // read request headers
78
- var requestHeaders = e .ProxySession .Request .RequestHeaders ;
94
+ // // read request headers
95
+ var requestHeaders = e .WebSession .Request .RequestHeaders ;
79
96
80
- if ((e .RequestMethod . ToUpper () == " POST" || e .RequestMethod .ToUpper () == " PUT" ))
97
+ if ((e .WebSession . Request . Method . ToUpper () == " POST" || e .WebSession . Request . Method .ToUpper () == " PUT" ))
81
98
{
82
99
// 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 );
85
102
86
103
// 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 );
89
106
90
107
}
91
108
92
109
// To cancel a request with a custom HTML content
93
110
// Filter URL
94
-
95
- if (e .ProxySession .Request .RequestUri .AbsoluteUri .Contains (" google.com" ))
111
+ if (e .WebSession .Request .RequestUri .AbsoluteUri .Contains (" google.com" ))
96
112
{
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" );
104
125
}
105
126
}
106
127
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 )
110
130
{
111
-
112
131
// read response headers
113
- var responseHeaders = e .ProxySession .Response .ResponseHeaders ;
114
-
132
+ var responseHeaders = e .WebSession .Response .ResponseHeaders ;
115
133
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" )
117
136
{
118
- if (e .ProxySession .Response .ResponseStatusCode == " 200" )
137
+ if (e .WebSession .Response .ResponseStatusCode == " 200" )
119
138
{
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" ))
121
140
{
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 );
123
146
}
124
147
}
125
148
}
126
149
}
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
+ }
127
161
```
128
162
Future roadmap
129
163
============
130
- * Add callbacks for client/server certificate validation/selection
131
164
* Support mutual authentication
132
165
* Support Server Name Indication (SNI) for transparent endpoints
133
166
* Support HTTP 2.0
0 commit comments