1
1
## Titanium Web Proxy
2
2
3
- ### Note: This Project is no longer maintained. Any pull requests for fixes are welcome.
4
-
5
3
A lightweight HTTP(S) proxy server written in C#.
6
4
7
5
<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
32
30
Supports
33
31
34
32
* .Net Standard 2.0 or above
35
- * .Net Framework 4.5 or above
33
+ * .Net Framework 4.6.1 or above
36
34
37
35
### Development environment
38
36
@@ -57,11 +55,11 @@ Setup HTTP proxy:
57
55
``` csharp
58
56
var proxyServer = new ProxyServer ();
59
57
60
- // locally trust root certificate used by this proxy
58
+ // locally trust root certificate used by this proxy
61
59
proxyServer .CertificateManager .TrustRootCertificate = true ;
62
60
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
65
63
// proxyServer.CertificateManager.CertificateEngine = Network.CertificateEngine.BouncyCastle;
66
64
67
65
proxyServer .BeforeRequest += OnRequest ;
@@ -72,28 +70,28 @@ proxyServer.ClientCertificateSelectionCallback += OnCertificateSelection;
72
70
73
71
var explicitEndPoint = new ExplicitProxyEndPoint (IPAddress .Any , 8000 , true )
74
72
{
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")
79
77
};
80
78
81
- // Fired when a CONNECT request is received
79
+ // Fired when a CONNECT request is received
82
80
explicitEndPoint .BeforeTunnelConnect += OnBeforeTunnelConnect ;
83
81
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
86
84
proxyServer .AddEndPoint (explicitEndPoint );
87
85
proxyServer .Start ();
88
86
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
92
90
var transparentEndPoint = new TransparentProxyEndPoint (IPAddress .Any , 8001 , true )
93
91
{
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"
97
95
};
98
96
99
97
proxyServer .AddEndPoint (transparentEndPoint );
@@ -105,36 +103,36 @@ foreach (var endPoint in proxyServer.ProxyEndPoints)
105
103
Console .WriteLine (" Listening on '{0}' endpoint at Ip {1} and port: {2} " ,
106
104
endPoint .GetType ().Name , endPoint .IpAddress , endPoint .Port );
107
105
108
- // Only explicit proxies can be set as system proxy!
106
+ // Only explicit proxies can be set as system proxy!
109
107
proxyServer .SetAsSystemHttpProxy (explicitEndPoint );
110
108
proxyServer .SetAsSystemHttpsProxy (explicitEndPoint );
111
109
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)
113
111
Console .Read ();
114
112
115
- // Unsubscribe & Quit
113
+ // Unsubscribe & Quit
116
114
explicitEndPoint .BeforeTunnelConnect -= OnBeforeTunnelConnect ;
117
115
proxyServer .BeforeRequest -= OnRequest ;
118
116
proxyServer .BeforeResponse -= OnResponse ;
119
117
proxyServer .ServerCertificateValidationCallback -= OnCertificateValidation ;
120
118
proxyServer .ClientCertificateSelectionCallback -= OnCertificateSelection ;
121
119
122
120
proxyServer .Stop ();
123
-
121
+
124
122
```
125
123
Sample request and response event handlers
126
124
127
- ``` csharp
125
+ ``` csharp
128
126
129
127
private async Task OnBeforeTunnelConnectRequest (object sender , TunnelConnectSessionEventArgs e )
130
128
{
131
129
string hostname = e .HttpClient .Request .RequestUri .Host ;
132
130
133
131
if (hostname .Contains (" dropbox.com" ))
134
132
{
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
138
136
e .DecryptSsl = false ;
139
137
}
140
138
}
@@ -143,88 +141,88 @@ public async Task OnRequest(object sender, SessionEventArgs e)
143
141
{
144
142
Console .WriteLine (e .HttpClient .Request .Url );
145
143
146
- // // read request headers
144
+ // read request headers
147
145
var requestHeaders = e .HttpClient .Request .RequestHeaders ;
148
146
149
147
var method = e .HttpClient .Request .Method .ToUpper ();
150
148
if ((method == " POST" || method == " PUT" || method == " PATCH" ))
151
149
{
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 ;
163
161
}
164
162
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
167
165
if (e .HttpClient .Request .RequestUri .AbsoluteUri .Contains (" google.com" ))
168
166
{
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>" );
176
174
}
177
- // Redirect example
175
+
176
+ // Redirect example
178
177
if (e .HttpClient .Request .RequestUri .AbsoluteUri .Contains (" wikipedia.org" ))
179
178
{
180
- e .Redirect (" https://www.paypal.com" );
179
+ e .Redirect (" https://www.paypal.com" );
181
180
}
182
181
}
183
182
184
- // Modify response
183
+ // Modify response
185
184
public async Task OnResponse (object sender , SessionEventArgs e )
186
185
{
187
- // read response headers
186
+ // read response headers
188
187
var responseHeaders = e .HttpClient .Response .ResponseHeaders ;
189
188
190
189
// if (!e.ProxySession.Request.Host.Equals("medeczane.sgk.gov.tr")) return;
191
190
if (e .HttpClient .Request .Method == " GET" || e .HttpClient .Request .Method == " POST" )
192
191
{
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
+ }
204
203
}
205
204
206
- if (e .UserData != null )
205
+ if (e .UserData != null )
207
206
{
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 ;
210
209
}
211
-
212
210
}
213
211
214
- /// Allows overriding default certificate validation logic
212
+ // Allows overriding default certificate validation logic
215
213
public Task OnCertificateValidation (object sender , CertificateValidationEventArgs e )
216
214
{
217
- // set IsValid to true/false based on Certificate Errors
215
+ // set IsValid to true/false based on Certificate Errors
218
216
if (e .SslPolicyErrors == System .Net .Security .SslPolicyErrors .None )
219
- e .IsValid = true ;
217
+ e .IsValid = true ;
220
218
221
219
return Task .FromResult (0 );
222
220
}
223
221
224
- /// Allows overriding default client certificate selection logic during mutual authentication
222
+ // Allows overriding default client certificate selection logic during mutual authentication
225
223
public Task OnCertificateSelection (object sender , CertificateSelectionEventArgs e )
226
224
{
227
- // set e.clientCertificate to override
225
+ // set e.clientCertificate to override
228
226
return Task .FromResult (0 );
229
227
}
230
228
```
0 commit comments