Skip to content
This repository was archived by the owner on Jul 9, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .build/default.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ Task Restore-Packages {
}

Task Install-MSBuild {
if(!(Test-Path "${env:ProgramFiles(x86)}\MSBuild\12.0\Bin\msbuild.exe"))
if(!(Test-Path "${env:ProgramFiles(x86)}\MSBuild\14.0\Bin\msbuild.exe"))
{
cinst microsoft-build-tools -y
}
Expand Down
35 changes: 19 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ After installing nuget package mark following files to be copied to app director
Setup HTTP proxy:

```csharp
var ProxyServer = new ProxyServer();
var proxyServer = new ProxyServer();

ProxyServer.BeforeRequest += OnRequest;
ProxyServer.BeforeResponse += OnResponse;
ProxyServer.ServerCertificateValidationCallback += OnCertificateValidation;
ProxyServer.ClientCertificateSelectionCallback += OnCertificateSelection;
proxyServer.BeforeRequest += OnRequest;
proxyServer.BeforeResponse += OnResponse;
proxyServer.ServerCertificateValidationCallback += OnCertificateValidation;
proxyServer.ClientCertificateSelectionCallback += OnCertificateSelection;


//Exclude Https addresses you don't want to proxy
Expand All @@ -53,8 +53,8 @@ Setup HTTP proxy:

//An explicit endpoint is where the client knows about the existance of a proxy
//So client sends request in a proxy friendly manner
ProxyServer.AddEndPoint(explicitEndPoint);
ProxyServer.Start();
proxyServer.AddEndPoint(explicitEndPoint);
proxyServer.Start();


//Transparent endpoint is usefull for reverse proxying (client is not aware of the existance of proxy)
Expand All @@ -67,26 +67,29 @@ Setup HTTP proxy:
{
GenericCertificateName = "google.com"
};
ProxyServer.AddEndPoint(transparentEndPoint);
proxyServer.AddEndPoint(transparentEndPoint);

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

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

//Only explicit proxies can be set as system proxy!
ProxyServer.SetAsSystemHttpProxy(explicitEndPoint);
ProxyServer.SetAsSystemHttpsProxy(explicitEndPoint);
proxyServer.SetAsSystemHttpProxy(explicitEndPoint);
proxyServer.SetAsSystemHttpsProxy(explicitEndPoint);

//wait here (You can use something else as a wait function, I am using this as a demo)
Console.Read();

//Unsubscribe & Quit
ProxyServer.BeforeRequest -= OnRequest;
ProxyServer.BeforeResponse -= OnResponse;
ProxyServer.Stop();
proxyServer.BeforeRequest -= OnRequest;
proxyServer.BeforeResponse -= OnResponse;
proxyServer.ServerCertificateValidationCallback -= OnCertificateValidation;
proxyServer.ClientCertificateSelectionCallback -= OnCertificateSelection;

proxyServer.Stop();

```
Sample request and response event handlers
Expand Down
33 changes: 18 additions & 15 deletions Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,7 @@ internal SessionEventArgs(int bufferSize, Func<SessionEventArgs, Task> httpRespo
ProxyClient = new ProxyClient();
WebSession = new HttpWebClient();
}



/// <summary>
/// Read request body content as bytes[] for current session
/// </summary>
Expand Down Expand Up @@ -98,7 +97,7 @@ private async Task ReadRequestBody()
await this.ProxyClient.ClientStreamReader.CopyBytesToStream(bufferSize, requestBodyStream, WebSession.Request.ContentLength);

}
else if(WebSession.Request.HttpVersion.Major == 1 && WebSession.Request.HttpVersion.Minor == 0)
else if (WebSession.Request.HttpVersion.Major == 1 && WebSession.Request.HttpVersion.Minor == 0)
await WebSession.ServerConnection.StreamReader.CopyBytesToStream(bufferSize, requestBodyStream, long.MaxValue);
}
WebSession.Request.RequestBody = await GetDecompressedResponseBody(WebSession.Request.ContentEncoding, requestBodyStream.ToArray());
Expand All @@ -108,7 +107,7 @@ private async Task ReadRequestBody()
//So that next time we can deliver body from cache
WebSession.Request.RequestBodyRead = true;
}

}

/// <summary>
Expand All @@ -134,7 +133,7 @@ private async Task ReadResponseBody()
await WebSession.ServerConnection.StreamReader.CopyBytesToStream(bufferSize, responseBodyStream, WebSession.Response.ContentLength);

}
else if(WebSession.Response.HttpVersion.Major == 1 && WebSession.Response.HttpVersion.Minor == 0)
else if (WebSession.Response.HttpVersion.Major == 1 && WebSession.Response.HttpVersion.Minor == 0)
await WebSession.ServerConnection.StreamReader.CopyBytesToStream(bufferSize, responseBodyStream, long.MaxValue);
}

Expand All @@ -152,10 +151,13 @@ private async Task ReadResponseBody()
/// <returns></returns>
public async Task<byte[]> GetRequestBody()
{
if (WebSession.Request.RequestLocked)
throw new Exception("You cannot call this function after request is made to server.");
if (!WebSession.Request.RequestBodyRead)
{
if (WebSession.Request.RequestLocked)
throw new Exception("You cannot call this function after request is made to server.");

await ReadRequestBody();
await ReadRequestBody();
}
return WebSession.Request.RequestBody;
}
/// <summary>
Expand All @@ -164,12 +166,13 @@ public async Task<byte[]> GetRequestBody()
/// <returns></returns>
public async Task<string> GetRequestBodyAsString()
{
if (WebSession.Request.RequestLocked)
throw new Exception("You cannot call this function after request is made to server.");


await ReadRequestBody();
if (!WebSession.Request.RequestBodyRead)
{
if (WebSession.Request.RequestLocked)
throw new Exception("You cannot call this function after request is made to server.");

await ReadRequestBody();
}
//Use the encoding specified in request to decode the byte[] data to string
return WebSession.Request.RequestBodyString ?? (WebSession.Request.RequestBodyString = WebSession.Request.Encoding.GetString(WebSession.Request.RequestBody));
}
Expand Down Expand Up @@ -285,7 +288,7 @@ public async Task SetResponseBodyString(string body)
var bodyBytes = WebSession.Response.Encoding.GetBytes(body);

await SetResponseBody(bodyBytes);
}
}

private async Task<byte[]> GetDecompressedResponseBody(string encodingType, byte[] responseBodyStream)
{
Expand Down Expand Up @@ -345,7 +348,7 @@ public async Task Redirect(string url)

WebSession.Request.CancelRequest = true;
}

/// a generic responder method
public async Task Respond(Response response)
{
Expand Down
4 changes: 3 additions & 1 deletion Titanium.Web.Proxy/Http/HttpWebClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,10 @@ internal async Task ReceiveResponse()

if (string.IsNullOrEmpty(httpResult[0]))
{
await ServerConnection.StreamReader.ReadLineAsync();
//Empty content in first-line, try again
httpResult = (await ServerConnection.StreamReader.ReadLineAsync()).Split(ProxyConstants.SpaceSplit, 3);
}

var httpVersion = httpResult[0].Trim().ToLower();

var version = new Version(1,1);
Expand Down
2 changes: 1 addition & 1 deletion Titanium.Web.Proxy/ProxyServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ public void SetAsSystemHttpProxy(ExplicitProxyEndPoint endPoint)
#if !DEBUG
firefoxProxySettingsManager.AddFirefox();
#endif
Console.WriteLine("Set endpoint at Ip {1} and port: {2} as System HTTPS Proxy", endPoint.GetType().Name, endPoint.IpAddress, endPoint.Port);
Console.WriteLine("Set endpoint at Ip {1} and port: {2} as System HTTP Proxy", endPoint.GetType().Name, endPoint.IpAddress, endPoint.Port);

}

Expand Down
22 changes: 16 additions & 6 deletions Titanium.Web.Proxy/ResponseHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -181,14 +181,28 @@ private void FixResponseProxyHeaders(List<HttpHeader> headers)
/// <summary>
/// Handle dispose of a client/server session
/// </summary>
/// <param name="client"></param>
/// <param name="tcpClient"></param>
/// <param name="clientStream"></param>
/// <param name="clientStreamReader"></param>
/// <param name="clientStreamWriter"></param>
/// <param name="args"></param>
private void Dispose(TcpClient client, IDisposable clientStream, IDisposable clientStreamReader,
private void Dispose(TcpClient tcpClient, IDisposable clientStream, IDisposable clientStreamReader,
IDisposable clientStreamWriter, IDisposable args)
{

if (clientStream != null)
{
(clientStream as Stream).Close();
(clientStream as Stream).Dispose();
}

if (tcpClient != null)
{
tcpClient.Client.Close();
tcpClient.Close();
tcpClient.Client.Dispose();
}

if (args != null)
args.Dispose();

Expand All @@ -198,11 +212,7 @@ private void Dispose(TcpClient client, IDisposable clientStream, IDisposable cl
if (clientStreamWriter != null)
clientStreamWriter.Dispose();

if (clientStream != null)
clientStream.Dispose();

if (client != null)
client.Close();
}
}
}