Skip to content
This repository was archived by the owner on Jul 9, 2023. It is now read-only.

Commit 35cd23b

Browse files
Merge pull request #430 from justcoding121/beta
Stable
2 parents 741d1d8 + d3ad2f8 commit 35cd23b

File tree

111 files changed

+1499
-1396
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

111 files changed

+1499
-1396
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,4 +205,4 @@ FakesAssemblies/
205205
*.opt
206206

207207
# Docfx
208-
docs/manifest.json
208+
docs/manifest.json

Examples/Titanium.Web.Proxy.Examples.Basic/Program.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ public class Program
99

1010
public static void Main(string[] args)
1111
{
12-
//fix console hang due to QuickEdit mode
12+
// fix console hang due to QuickEdit mode
1313
ConsoleHelper.DisableQuickEditMode();
1414

15-
//Start proxy controller
15+
// Start proxy controller
1616
controller.StartProxy();
1717

1818
Console.WriteLine("Hit any key to exit..");

Examples/Titanium.Web.Proxy.Examples.Basic/ProxyTestController.cs

Lines changed: 71 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -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
}

Examples/Titanium.Web.Proxy.Examples.Wpf/MainWindow.xaml.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
using System.Windows.Controls;
1010
using System.Windows.Input;
1111
using Titanium.Web.Proxy.EventArguments;
12-
using Titanium.Web.Proxy.Helpers;
1312
using Titanium.Web.Proxy.Http;
1413
using Titanium.Web.Proxy.Models;
1514

Examples/Titanium.Web.Proxy.Examples.Wpf/Titanium.Web.Proxy.Examples.Wpf.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@
5151
<WarningLevel>4</WarningLevel>
5252
</PropertyGroup>
5353
<ItemGroup>
54-
<Reference Include="StreamExtended, Version=1.0.147.0, Culture=neutral, PublicKeyToken=bbfa0f1d54f50043, processorArchitecture=MSIL">
55-
<HintPath>..\..\packages\StreamExtended.1.0.147-beta\lib\net45\StreamExtended.dll</HintPath>
54+
<Reference Include="StreamExtended, Version=1.0.164.0, Culture=neutral, PublicKeyToken=bbfa0f1d54f50043, processorArchitecture=MSIL">
55+
<HintPath>..\..\packages\StreamExtended.1.0.164\lib\net45\StreamExtended.dll</HintPath>
5656
</Reference>
5757
<Reference Include="System" />
5858
<Reference Include="System.Data" />
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
32
<packages>
4-
<package id="StreamExtended" version="1.0.147-beta" targetFramework="net45" />
3+
<package id="StreamExtended" version="1.0.164" targetFramework="net45" />
54
</packages>

README.md

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -121,10 +121,6 @@ Sample request and response event handlers
121121

122122
```csharp
123123

124-
//To access requestBody from OnResponse handler
125-
private IDictionary<Guid, string> requestBodyHistory
126-
= new ConcurrentDictionary<Guid, string>();
127-
128124
private async Task OnBeforeTunnelConnectRequest(object sender, TunnelConnectSessionEventArgs e)
129125
{
130126
string hostname = e.WebSession.Request.RequestUri.Host;
@@ -156,9 +152,9 @@ public async Task OnRequest(object sender, SessionEventArgs e)
156152
string bodyString = await e.GetRequestBodyAsString();
157153
await e.SetRequestBodyString(bodyString);
158154

159-
//store request Body/request headers etc with request Id as key
160-
//so that you can find it from response handler using request Id
161-
requestBodyHistory[e.Id] = bodyString;
155+
//store request
156+
//so that you can find it from response handler
157+
e.UserData = e.WebSession.Request;
162158
}
163159

164160
//To cancel a request with a custom HTML content
@@ -202,11 +198,12 @@ public async Task OnResponse(object sender, SessionEventArgs e)
202198
}
203199
}
204200

205-
//access request body/request headers etc by looking up using requestId
206-
if(requestBodyHistory.ContainsKey(e.Id))
201+
if(e.UserData!=null)
207202
{
208-
var requestBody = requestBodyHistory[e.Id];
203+
//access request from UserData property where we stored it in RequestHandler
204+
var request = (Request)e.UserData;
209205
}
206+
210207
}
211208

212209
/// Allows overriding default certificate validation logic

0 commit comments

Comments
 (0)