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

Commit 5f3e8d4

Browse files
Merge pull request #84 from justcoding121/release
Release
2 parents 703f521 + a954c57 commit 5f3e8d4

23 files changed

+324
-262
lines changed

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

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
using System;
2-
using System.Collections.Generic;
32
using System.Net;
4-
using System.Text.RegularExpressions;
53
using System.Threading.Tasks;
64
using Titanium.Web.Proxy.EventArguments;
75
using Titanium.Web.Proxy.Models;
@@ -10,12 +8,19 @@ namespace Titanium.Web.Proxy.Examples.Basic
108
{
119
public class ProxyTestController
1210
{
11+
private ProxyServer proxyServer;
12+
13+
public ProxyTestController()
14+
{
15+
proxyServer = new ProxyServer();
16+
}
17+
1318
public void StartProxy()
1419
{
15-
ProxyServer.BeforeRequest += OnRequest;
16-
ProxyServer.BeforeResponse += OnResponse;
17-
ProxyServer.ServerCertificateValidationCallback += OnCertificateValidation;
18-
ProxyServer.ClientCertificateSelectionCallback += OnCertificateSelection;
20+
proxyServer.BeforeRequest += OnRequest;
21+
proxyServer.BeforeResponse += OnResponse;
22+
proxyServer.ServerCertificateValidationCallback += OnCertificateValidation;
23+
proxyServer.ClientCertificateSelectionCallback += OnCertificateSelection;
1924

2025
//Exclude Https addresses you don't want to proxy
2126
//Usefull for clients that use certificate pinning
@@ -27,8 +32,8 @@ public void StartProxy()
2732

2833
//An explicit endpoint is where the client knows about the existance of a proxy
2934
//So client sends request in a proxy friendly manner
30-
ProxyServer.AddEndPoint(explicitEndPoint);
31-
ProxyServer.Start();
35+
proxyServer.AddEndPoint(explicitEndPoint);
36+
proxyServer.Start();
3237

3338

3439
//Transparent endpoint is usefull for reverse proxying (client is not aware of the existance of proxy)
@@ -41,26 +46,28 @@ public void StartProxy()
4146
{
4247
GenericCertificateName = "google.com"
4348
};
44-
ProxyServer.AddEndPoint(transparentEndPoint);
49+
proxyServer.AddEndPoint(transparentEndPoint);
4550

4651
//ProxyServer.UpStreamHttpProxy = new ExternalProxy() { HostName = "localhost", Port = 8888 };
4752
//ProxyServer.UpStreamHttpsProxy = new ExternalProxy() { HostName = "localhost", Port = 8888 };
4853

49-
foreach (var endPoint in ProxyServer.ProxyEndPoints)
54+
foreach (var endPoint in proxyServer.ProxyEndPoints)
5055
Console.WriteLine("Listening on '{0}' endpoint at Ip {1} and port: {2} ",
5156
endPoint.GetType().Name, endPoint.IpAddress, endPoint.Port);
5257

5358
//Only explicit proxies can be set as system proxy!
54-
ProxyServer.SetAsSystemHttpProxy(explicitEndPoint);
55-
ProxyServer.SetAsSystemHttpsProxy(explicitEndPoint);
59+
proxyServer.SetAsSystemHttpProxy(explicitEndPoint);
60+
proxyServer.SetAsSystemHttpsProxy(explicitEndPoint);
5661
}
5762

5863
public void Stop()
5964
{
60-
ProxyServer.BeforeRequest -= OnRequest;
61-
ProxyServer.BeforeResponse -= OnResponse;
65+
proxyServer.BeforeRequest -= OnRequest;
66+
proxyServer.BeforeResponse -= OnResponse;
67+
proxyServer.ServerCertificateValidationCallback -= OnCertificateValidation;
68+
proxyServer.ClientCertificateSelectionCallback -= OnCertificateSelection;
6269

63-
ProxyServer.Stop();
70+
proxyServer.Stop();
6471
}
6572

6673
//intecept & cancel, redirect or update requests

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ After installing nuget package mark following files to be copied to app director
3535
Setup HTTP proxy:
3636

3737
```csharp
38+
var ProxyServer = new ProxyServer();
39+
3840
ProxyServer.BeforeRequest += OnRequest;
3941
ProxyServer.BeforeResponse += OnResponse;
4042
ProxyServer.ServerCertificateValidationCallback += OnCertificateValidation;

Titanium.Web.Proxy/CertificateHandler.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public partial class ProxyServer
1717
/// <param name="chain"></param>
1818
/// <param name="sslPolicyErrors"></param>
1919
/// <returns></returns>
20-
internal static bool ValidateServerCertificate(
20+
internal bool ValidateServerCertificate(
2121
object sender,
2222
X509Certificate certificate,
2323
X509Chain chain,
@@ -62,7 +62,7 @@ internal static bool ValidateServerCertificate(
6262
/// <param name="chain"></param>
6363
/// <param name="sslPolicyErrors"></param>
6464
/// <returns></returns>
65-
internal static X509Certificate SelectClientCertificate(
65+
internal X509Certificate SelectClientCertificate(
6666
object sender,
6767
string targetHost,
6868
X509CertificateCollection localCertificates,

Titanium.Web.Proxy/Decompression/DefaultDecompression.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace Titanium.Web.Proxy.Decompression
88
/// </summary>
99
internal class DefaultDecompression : IDecompression
1010
{
11-
public Task<byte[]> Decompress(byte[] compressedArray)
11+
public Task<byte[]> Decompress(byte[] compressedArray, int bufferSize)
1212
{
1313
return Task.FromResult(compressedArray);
1414
}

Titanium.Web.Proxy/Decompression/DeflateDecompression.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ namespace Titanium.Web.Proxy.Decompression
1010
/// </summary>
1111
internal class DeflateDecompression : IDecompression
1212
{
13-
public async Task<byte[]> Decompress(byte[] compressedArray)
13+
public async Task<byte[]> Decompress(byte[] compressedArray, int bufferSize)
1414
{
1515
var stream = new MemoryStream(compressedArray);
1616

1717
using (var decompressor = new DeflateStream(stream, CompressionMode.Decompress))
1818
{
19-
var buffer = new byte[ProxyConstants.BUFFER_SIZE];
19+
var buffer = new byte[bufferSize];
2020

2121
using (var output = new MemoryStream())
2222
{

Titanium.Web.Proxy/Decompression/GZipDecompression.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ namespace Titanium.Web.Proxy.Decompression
1010
/// </summary>
1111
internal class GZipDecompression : IDecompression
1212
{
13-
public async Task<byte[]> Decompress(byte[] compressedArray)
13+
public async Task<byte[]> Decompress(byte[] compressedArray, int bufferSize)
1414
{
1515
using (var decompressor = new GZipStream(new MemoryStream(compressedArray), CompressionMode.Decompress))
1616
{
17-
var buffer = new byte[ProxyConstants.BUFFER_SIZE];
17+
var buffer = new byte[bufferSize];
1818
using (var output = new MemoryStream())
1919
{
2020
int read;

Titanium.Web.Proxy/Decompression/IDecompression.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ namespace Titanium.Web.Proxy.Decompression
77
/// </summary>
88
internal interface IDecompression
99
{
10-
Task<byte[]> Decompress(byte[] compressedArray);
10+
Task<byte[]> Decompress(byte[] compressedArray, int bufferSize);
1111
}
1212
}

Titanium.Web.Proxy/Decompression/ZlibDecompression.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ namespace Titanium.Web.Proxy.Decompression
1010
/// </summary>
1111
internal class ZlibDecompression : IDecompression
1212
{
13-
public async Task<byte[]> Decompress(byte[] compressedArray)
13+
public async Task<byte[]> Decompress(byte[] compressedArray, int bufferSize)
1414
{
1515
var memoryStream = new MemoryStream(compressedArray);
1616
using (var decompressor = new ZlibStream(memoryStream, CompressionMode.Decompress))
1717
{
18-
var buffer = new byte[ProxyConstants.BUFFER_SIZE];
18+
var buffer = new byte[bufferSize];
1919

2020
using (var output = new MemoryStream())
2121
{

Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,16 @@ namespace Titanium.Web.Proxy.EventArguments
2020
/// </summary>
2121
public class SessionEventArgs : EventArgs, IDisposable
2222
{
23+
2324
/// <summary>
24-
/// Constructor to initialize the proxy
25+
/// Size of Buffers used by this object
2526
/// </summary>
26-
internal SessionEventArgs()
27-
{
28-
ProxyClient = new ProxyClient();
29-
WebSession = new HttpWebClient();
30-
}
27+
private readonly int bufferSize;
28+
29+
/// <summary>
30+
/// Holds a reference to proxy response handler method
31+
/// </summary>
32+
private readonly Func<SessionEventArgs, Task> httpResponseHandler;
3133

3234
/// <summary>
3335
/// Holds a reference to client
@@ -50,13 +52,18 @@ internal SessionEventArgs()
5052

5153

5254
/// <summary>
53-
/// implement any cleanup here
55+
/// Constructor to initialize the proxy
5456
/// </summary>
55-
public void Dispose()
57+
internal SessionEventArgs(int bufferSize, Func<SessionEventArgs, Task> httpResponseHandler)
5658
{
59+
this.bufferSize = bufferSize;
60+
this.httpResponseHandler = httpResponseHandler;
5761

62+
ProxyClient = new ProxyClient();
63+
WebSession = new HttpWebClient();
5864
}
5965

66+
6067
/// <summary>
6168
/// Read request body content as bytes[] for current session
6269
/// </summary>
@@ -80,19 +87,19 @@ private async Task ReadRequestBody()
8087
//For chunked request we need to read data as they arrive, until we reach a chunk end symbol
8188
if (WebSession.Request.IsChunked)
8289
{
83-
await this.ProxyClient.ClientStreamReader.CopyBytesToStreamChunked(requestBodyStream);
90+
await this.ProxyClient.ClientStreamReader.CopyBytesToStreamChunked(bufferSize, requestBodyStream);
8491
}
8592
else
8693
{
8794
//If not chunked then its easy just read the whole body with the content length mentioned in the request header
8895
if (WebSession.Request.ContentLength > 0)
8996
{
9097
//If not chunked then its easy just read the amount of bytes mentioned in content length header of response
91-
await this.ProxyClient.ClientStreamReader.CopyBytesToStream(requestBodyStream, WebSession.Request.ContentLength);
98+
await this.ProxyClient.ClientStreamReader.CopyBytesToStream(bufferSize, requestBodyStream, WebSession.Request.ContentLength);
9299

93100
}
94101
else if(WebSession.Request.HttpVersion.Major == 1 && WebSession.Request.HttpVersion.Minor == 0)
95-
await WebSession.ServerConnection.StreamReader.CopyBytesToStream(requestBodyStream, long.MaxValue);
102+
await WebSession.ServerConnection.StreamReader.CopyBytesToStream(bufferSize, requestBodyStream, long.MaxValue);
96103
}
97104
WebSession.Request.RequestBody = await GetDecompressedResponseBody(WebSession.Request.ContentEncoding, requestBodyStream.ToArray());
98105
}
@@ -117,18 +124,18 @@ private async Task ReadResponseBody()
117124
//If chuncked the read chunk by chunk until we hit chunk end symbol
118125
if (WebSession.Response.IsChunked)
119126
{
120-
await WebSession.ServerConnection.StreamReader.CopyBytesToStreamChunked(responseBodyStream);
127+
await WebSession.ServerConnection.StreamReader.CopyBytesToStreamChunked(bufferSize, responseBodyStream);
121128
}
122129
else
123130
{
124131
if (WebSession.Response.ContentLength > 0)
125132
{
126133
//If not chunked then its easy just read the amount of bytes mentioned in content length header of response
127-
await WebSession.ServerConnection.StreamReader.CopyBytesToStream(responseBodyStream, WebSession.Response.ContentLength);
134+
await WebSession.ServerConnection.StreamReader.CopyBytesToStream(bufferSize, responseBodyStream, WebSession.Response.ContentLength);
128135

129136
}
130137
else if(WebSession.Response.HttpVersion.Major == 1 && WebSession.Response.HttpVersion.Minor == 0)
131-
await WebSession.ServerConnection.StreamReader.CopyBytesToStream(responseBodyStream, long.MaxValue);
138+
await WebSession.ServerConnection.StreamReader.CopyBytesToStream(bufferSize, responseBodyStream, long.MaxValue);
132139
}
133140

134141
WebSession.Response.ResponseBody = await GetDecompressedResponseBody(WebSession.Response.ContentEncoding, responseBodyStream.ToArray());
@@ -285,7 +292,7 @@ private async Task<byte[]> GetDecompressedResponseBody(string encodingType, byte
285292
var decompressionFactory = new DecompressionFactory();
286293
var decompressor = decompressionFactory.Create(encodingType);
287294

288-
return await decompressor.Decompress(responseBodyStream);
295+
return await decompressor.Decompress(responseBodyStream, bufferSize);
289296
}
290297

291298

@@ -338,7 +345,7 @@ public async Task Redirect(string url)
338345

339346
WebSession.Request.CancelRequest = true;
340347
}
341-
348+
342349
/// a generic responder method
343350
public async Task Respond(Response response)
344351
{
@@ -349,8 +356,15 @@ public async Task Respond(Response response)
349356

350357
WebSession.Response = response;
351358

352-
await ProxyServer.HandleHttpSessionResponse(this);
359+
await httpResponseHandler(this);
353360
}
354361

362+
/// <summary>
363+
/// implement any cleanup here
364+
/// </summary>
365+
public void Dispose()
366+
{
367+
368+
}
355369
}
356370
}

Titanium.Web.Proxy/Extensions/StreamExtensions.cs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,22 +35,22 @@ internal static async Task CopyToAsync(this Stream input, string initialData, St
3535
/// <param name="stream"></param>
3636
/// <param name="totalBytesToRead"></param>
3737
/// <returns></returns>
38-
internal static async Task CopyBytesToStream(this CustomBinaryReader streamReader, Stream stream, long totalBytesToRead)
38+
internal static async Task CopyBytesToStream(this CustomBinaryReader streamReader, int bufferSize, Stream stream, long totalBytesToRead)
3939
{
4040
var totalbytesRead = 0;
4141

4242
long bytesToRead;
43-
if (totalBytesToRead < ProxyConstants.BUFFER_SIZE)
43+
if (totalBytesToRead < bufferSize)
4444
{
4545
bytesToRead = totalBytesToRead;
4646
}
4747
else
48-
bytesToRead = ProxyConstants.BUFFER_SIZE;
48+
bytesToRead = bufferSize;
4949

5050

5151
while (totalbytesRead < totalBytesToRead)
5252
{
53-
var buffer = await streamReader.ReadBytesAsync(bytesToRead);
53+
var buffer = await streamReader.ReadBytesAsync(bufferSize, bytesToRead);
5454

5555
if (buffer.Length == 0)
5656
break;
@@ -72,7 +72,7 @@ internal static async Task CopyBytesToStream(this CustomBinaryReader streamReade
7272
/// <param name="clientStreamReader"></param>
7373
/// <param name="stream"></param>
7474
/// <returns></returns>
75-
internal static async Task CopyBytesToStreamChunked(this CustomBinaryReader clientStreamReader, Stream stream)
75+
internal static async Task CopyBytesToStreamChunked(this CustomBinaryReader clientStreamReader, int bufferSize, Stream stream)
7676
{
7777
while (true)
7878
{
@@ -81,7 +81,7 @@ internal static async Task CopyBytesToStreamChunked(this CustomBinaryReader clie
8181

8282
if (chunkSize != 0)
8383
{
84-
var buffer = await clientStreamReader.ReadBytesAsync(chunkSize);
84+
var buffer = await clientStreamReader.ReadBytesAsync(bufferSize, chunkSize);
8585
await stream.WriteAsync(buffer, 0, buffer.Length);
8686
//chunk trail
8787
await clientStreamReader.ReadLineAsync();
@@ -118,20 +118,20 @@ internal static async Task WriteResponseBody(this Stream clientStream, byte[] da
118118
/// <param name="isChunked"></param>
119119
/// <param name="ContentLength"></param>
120120
/// <returns></returns>
121-
internal static async Task WriteResponseBody(this CustomBinaryReader inStreamReader, Stream outStream, bool isChunked, long ContentLength)
121+
internal static async Task WriteResponseBody(this CustomBinaryReader inStreamReader, int bufferSize, Stream outStream, bool isChunked, long ContentLength)
122122
{
123123
if (!isChunked)
124124
{
125125
//http 1.0
126126
if (ContentLength == -1)
127127
ContentLength = long.MaxValue;
128128

129-
int bytesToRead = ProxyConstants.BUFFER_SIZE;
129+
int bytesToRead = bufferSize;
130130

131-
if (ContentLength < ProxyConstants.BUFFER_SIZE)
131+
if (ContentLength < bufferSize)
132132
bytesToRead = (int)ContentLength;
133133

134-
var buffer = new byte[ProxyConstants.BUFFER_SIZE];
134+
var buffer = new byte[bufferSize];
135135

136136
var bytesRead = 0;
137137
var totalBytesRead = 0;
@@ -146,11 +146,11 @@ internal static async Task WriteResponseBody(this CustomBinaryReader inStreamRea
146146

147147
bytesRead = 0;
148148
var remainingBytes = (ContentLength - totalBytesRead);
149-
bytesToRead = remainingBytes > (long)ProxyConstants.BUFFER_SIZE ? ProxyConstants.BUFFER_SIZE : (int)remainingBytes;
149+
bytesToRead = remainingBytes > (long)bufferSize ? bufferSize : (int)remainingBytes;
150150
}
151151
}
152152
else
153-
await WriteResponseBodyChunked(inStreamReader, outStream);
153+
await WriteResponseBodyChunked(inStreamReader, bufferSize, outStream);
154154
}
155155

156156
/// <summary>
@@ -159,7 +159,7 @@ internal static async Task WriteResponseBody(this CustomBinaryReader inStreamRea
159159
/// <param name="inStreamReader"></param>
160160
/// <param name="outStream"></param>
161161
/// <returns></returns>
162-
internal static async Task WriteResponseBodyChunked(this CustomBinaryReader inStreamReader, Stream outStream)
162+
internal static async Task WriteResponseBodyChunked(this CustomBinaryReader inStreamReader, int bufferSize, Stream outStream)
163163
{
164164
while (true)
165165
{
@@ -168,7 +168,7 @@ internal static async Task WriteResponseBodyChunked(this CustomBinaryReader inSt
168168

169169
if (chunkSize != 0)
170170
{
171-
var buffer = await inStreamReader.ReadBytesAsync(chunkSize);
171+
var buffer = await inStreamReader.ReadBytesAsync(bufferSize, chunkSize);
172172

173173
var chunkHeadBytes = Encoding.ASCII.GetBytes(chunkSize.ToString("x2"));
174174

0 commit comments

Comments
 (0)