@@ -18,26 +18,13 @@ public class ProxyTestController
1818
1919 private readonly ProxyServer proxyServer ;
2020
21- //keep track of request headers
22- private readonly IDictionary < Guid , HeaderCollection > requestHeaderHistory =
23- new ConcurrentDictionary < Guid , HeaderCollection > ( ) ;
24-
25- //keep track of response headers
26- private readonly IDictionary < Guid , HeaderCollection > responseHeaderHistory =
27- new ConcurrentDictionary < Guid , HeaderCollection > ( ) ;
28-
2921 private ExplicitProxyEndPoint explicitEndPoint ;
3022
31- //share requestBody outside handlers
32- //Using a dictionary is not a good idea since it can cause memory overflow
33- //ideally the data should be moved out of memory
34- //private readonly IDictionary<Guid, string> requestBodyHistory = new ConcurrentDictionary<Guid, string>();
35-
3623 public ProxyTestController ( )
3724 {
3825 proxyServer = new ProxyServer ( ) ;
3926
40- //generate root certificate without storing it in file system
27+ // generate root certificate without storing it in file system
4128 //proxyServer.CertificateManager.CreateRootCertificate(false);
4229
4330 //proxyServer.CertificateManager.TrustRootCertificate();
@@ -63,11 +50,12 @@ public ProxyTestController()
6350 } ;
6451 proxyServer . ForwardToUpstreamGateway = true ;
6552 proxyServer . CertificateManager . SaveFakeCertificates = true ;
66- //optionally set the Certificate Engine
67- //Under Mono or Non-Windows runtimes only BouncyCastle will be supported
53+
54+ // optionally set the Certificate Engine
55+ // Under Mono or Non-Windows runtimes only BouncyCastle will be supported
6856 //proxyServer.CertificateManager.CertificateEngine = Network.CertificateEngine.BouncyCastle;
6957
70- //optionally set the Root Certificate
58+ // optionally set the Root Certificate
7159 //proxyServer.CertificateManager.RootCertificate = new X509Certificate2("myCert.pfx", string.Empty, X509KeyStorageFlags.Exportable);
7260 }
7361
@@ -83,27 +71,26 @@ public void StartProxy()
8371
8472 explicitEndPoint = new ExplicitProxyEndPoint ( IPAddress . Any , 8000 ) ;
8573
86- //Fired when a CONNECT request is received
74+ // Fired when a CONNECT request is received
8775 explicitEndPoint . BeforeTunnelConnectRequest += OnBeforeTunnelConnectRequest ;
8876 explicitEndPoint . BeforeTunnelConnectResponse += OnBeforeTunnelConnectResponse ;
8977
90- //An explicit endpoint is where the client knows about the existence of a proxy
91- //So client sends request in a proxy friendly manner
78+ // An explicit endpoint is where the client knows about the existence of a proxy
79+ // So client sends request in a proxy friendly manner
9280 proxyServer . AddEndPoint ( explicitEndPoint ) ;
9381 proxyServer . Start ( ) ;
9482
95- //Transparent endpoint is useful for reverse proxy (client is not aware of the existence of proxy)
96- //A transparent endpoint usually requires a network router port forwarding HTTP(S) packets or DNS
97- //to send data to this endPoint
83+ // Transparent endpoint is useful for reverse proxy (client is not aware of the existence of proxy)
84+ // A transparent endpoint usually requires a network router port forwarding HTTP(S) packets or DNS
85+ // to send data to this endPoint
9886 //var transparentEndPoint = new TransparentProxyEndPoint(IPAddress.Any, 443, true)
99- //{
100- // //Generic Certificate hostname to use
101- // //When SNI is disabled by client
87+ //{
88+ // // Generic Certificate hostname to use
89+ // // When SNI is disabled by client
10290 // GenericCertificateName = "google.com"
10391 //};
10492
10593 //proxyServer.AddEndPoint(transparentEndPoint);
106-
10794 //proxyServer.UpStreamHttpProxy = new ExternalProxy() { HostName = "localhost", Port = 8888 };
10895 //proxyServer.UpStreamHttpsProxy = new ExternalProxy() { HostName = "localhost", Port = 8888 };
10996
@@ -117,7 +104,7 @@ public void StartProxy()
117104 if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) )
118105#endif
119106 {
120- //Only explicit proxies can be set as system proxy!
107+ // Only explicit proxies can be set as system proxy!
121108 //proxyServer.SetAsSystemHttpProxy(explicitEndPoint);
122109 //proxyServer.SetAsSystemHttpsProxy(explicitEndPoint);
123110 proxyServer . SetAsSystemProxy ( explicitEndPoint , ProxyProtocolType . AllHttp ) ;
@@ -135,8 +122,8 @@ public void Stop()
135122 proxyServer . ClientCertificateSelectionCallback -= OnCertificateSelection ;
136123
137124 proxyServer . Stop ( ) ;
138-
139- //remove the generated certificates
125+
126+ // remove the generated certificates
140127 //proxyServer.CertificateManager.RemoveTrustedRootCertificates();
141128 }
142129
@@ -147,9 +134,9 @@ private async Task OnBeforeTunnelConnectRequest(object sender, TunnelConnectSess
147134
148135 if ( hostname . Contains ( "dropbox.com" ) )
149136 {
150- //Exclude Https addresses you don't want to proxy
151- //Useful for clients that use certificate pinning
152- //for example dropbox.com
137+ // Exclude Https addresses you don't want to proxy
138+ // Useful for clients that use certificate pinning
139+ // for example dropbox.com
153140 e . DecryptSsl = false ;
154141 }
155142 }
@@ -158,55 +145,48 @@ private async Task OnBeforeTunnelConnectResponse(object sender, TunnelConnectSes
158145 {
159146 }
160147
161- //intecept & cancel redirect or update requests
148+ // intecept & cancel redirect or update requests
162149 private async Task OnRequest ( object sender , SessionEventArgs e )
163150 {
164151 WriteToConsole ( "Active Client Connections:" + ( ( ProxyServer ) sender ) . ClientConnectionCount ) ;
165152 WriteToConsole ( e . WebSession . Request . Url ) ;
166153
167- //read request headers
168- requestHeaderHistory [ e . Id ] = e . WebSession . Request . Headers ;
154+ // store it in the UserData property
155+ // It can be a simple integer, Guid, or any type
156+ //e.UserData = new CustomUserData()
157+ //{
158+ // RequestHeaders = e.WebSession.Request.Headers,
159+ // RequestBody = e.WebSession.Request.HasBody ? e.WebSession.Request.Body:null,
160+ // RequestBodyString = e.WebSession.Request.HasBody? e.WebSession.Request.BodyString:null
161+ //};
169162
170163 ////This sample shows how to get the multipart form data headers
171164 //if (e.WebSession.Request.Host == "mail.yahoo.com" && e.WebSession.Request.IsMultipartFormData)
172165 //{
173166 // e.MultipartRequestPartSent += MultipartRequestPartSent;
174167 //}
175168
176- //if (e.WebSession.Request.HasBody)
177- //{
178- // //Get/Set request body bytes
179- // var bodyBytes = await e.GetRequestBody();
180- // await e.SetRequestBody(bodyBytes);
181-
182- // //Get/Set request body as string
183- // string bodyString = await e.GetRequestBodyAsString();
184- // await e.SetRequestBodyString(bodyString);
185-
186- // //requestBodyHistory[e.Id] = bodyString;
187- //}
188-
189- //To cancel a request with a custom HTML content
190- //Filter URL
169+ // To cancel a request with a custom HTML content
170+ // Filter URL
191171 //if (e.WebSession.Request.RequestUri.AbsoluteUri.Contains("yahoo.com"))
192- //{
172+ //{
193173 // e.Ok("<!DOCTYPE html>" +
194174 // "<html><body><h1>" +
195175 // "Website Blocked" +
196176 // "</h1>" +
197177 // "<p>Blocked by titanium web proxy.</p>" +
198178 // "</body>" +
199179 // "</html>");
200- //}
180+ //}
201181
202182 ////Redirect example
203183 //if (e.WebSession.Request.RequestUri.AbsoluteUri.Contains("wikipedia.org"))
204- //{
184+ //{
205185 // e.Redirect("https://www.paypal.com");
206- //}
186+ //}
207187 }
208188
209- //Modify response
189+ // Modify response
210190 private void MultipartRequestPartSent ( object sender , MultipartRequestPartSentEventArgs e )
211191 {
212192 var session = ( SessionEventArgs ) sender ;
@@ -221,21 +201,34 @@ private async Task OnResponse(object sender, SessionEventArgs e)
221201 {
222202 WriteToConsole ( "Active Server Connections:" + ( ( ProxyServer ) sender ) . ServerConnectionCount ) ;
223203
224- //if (requestBodyHistory.ContainsKey(e.Id))
225- //{
226- // //access request body by looking up the shared dictionary using requestId
227- // var requestBody = requestBodyHistory[e.Id];
228- //}
204+ string ext = System . IO . Path . GetExtension ( e . WebSession . Request . RequestUri . AbsolutePath ) ;
229205
230- ////read response headers
231- //responseHeaderHistory[e.Id] = e.WebSession.Response.Headers;
206+ //access user data set in request to do something with it
207+ //var userData = e.WebSession.UserData as CustomUserData;
208+
209+ //if (ext == ".gif" || ext == ".png" || ext == ".jpg")
210+ //{
211+ // byte[] btBody = Encoding.UTF8.GetBytes("<!DOCTYPE html>" +
212+ // "<html><body><h1>" +
213+ // "Image is blocked" +
214+ // "</h1>" +
215+ // "<p>Blocked by Titanium</p>" +
216+ // "</body>" +
217+ // "</html>");
218+
219+ // var response = new OkResponse(btBody);
220+ // response.HttpVersion = e.WebSession.Request.HttpVersion;
221+
222+ // e.Respond(response);
223+ // e.TerminateServerConnection();
224+ //}
232225
233226 //// print out process id of current session
234227 ////WriteToConsole($"PID: {e.WebSession.ProcessId.Value}");
235228
236229 ////if (!e.ProxySession.Request.Host.Equals("medeczane.sgk.gov.tr")) return;
237230 //if (e.WebSession.Request.Method == "GET" || e.WebSession.Request.Method == "POST")
238- //{
231+ //{
239232 // if (e.WebSession.Response.StatusCode == (int)HttpStatusCode.OK)
240233 // {
241234 // if (e.WebSession.Response.ContentType != null && e.WebSession.Response.ContentType.Trim().ToLower().Contains("text/html"))
@@ -247,7 +240,7 @@ private async Task OnResponse(object sender, SessionEventArgs e)
247240 // await e.SetResponseBodyString(body);
248241 // }
249242 // }
250- //}
243+ //}
251244 }
252245
253246 /// <summary>
@@ -257,7 +250,7 @@ private async Task OnResponse(object sender, SessionEventArgs e)
257250 /// <param name="e"></param>
258251 public Task OnCertificateValidation ( object sender , CertificateValidationEventArgs e )
259252 {
260- //set IsValid to true/false based on Certificate Errors
253+ // set IsValid to true/false based on Certificate Errors
261254 if ( e . SslPolicyErrors == SslPolicyErrors . None )
262255 {
263256 e . IsValid = true ;
@@ -273,7 +266,7 @@ public Task OnCertificateValidation(object sender, CertificateValidationEventArg
273266 /// <param name="e"></param>
274267 public Task OnCertificateSelection ( object sender , CertificateSelectionEventArgs e )
275268 {
276- //set e.clientCertificate to override
269+ // set e.clientCertificate to override
277270
278271 return Task . FromResult ( 0 ) ;
279272 }
@@ -285,5 +278,16 @@ private void WriteToConsole(string message)
285278 Console . WriteLine ( message ) ;
286279 }
287280 }
281+
282+ ///// <summary>
283+ ///// User data object as defined by user.
284+ ///// User data can be set to each SessionEventArgs.WebSession.UserData property
285+ ///// </summary>
286+ //public class CustomUserData
287+ //{
288+ // public HeaderCollection RequestHeaders { get; set; }
289+ // public byte[] RequestBody { get; set; }
290+ // public string RequestBodyString { get; set; }
291+ //}
288292 }
289293}
0 commit comments