Commit 5faaa0b2 authored by justcoding121's avatar justcoding121

#184 add connection count; TODO: Find out why large number of client connections are active

parent 4047a006
...@@ -106,6 +106,7 @@ namespace Titanium.Web.Proxy.Examples.Basic ...@@ -106,6 +106,7 @@ namespace Titanium.Web.Proxy.Examples.Basic
//intecept & cancel redirect or update requests //intecept & cancel redirect or update requests
public async Task OnRequest(object sender, SessionEventArgs e) public async Task OnRequest(object sender, SessionEventArgs e)
{ {
Console.WriteLine("Active Connections:" + (sender as ProxyServer).ClientConnectionCount);
Console.WriteLine(e.WebSession.Request.Url); Console.WriteLine(e.WebSession.Request.Url);
//read request headers //read request headers
......
...@@ -55,10 +55,11 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -55,10 +55,11 @@ namespace Titanium.Web.Proxy.Network.Tcp
{ {
Stream?.Close(); Stream?.Close();
Stream?.Dispose(); Stream?.Dispose();
StreamReader?.Dispose(); StreamReader?.Dispose();
TcpClient.LingerState = new LingerOption(true, 0); TcpClient.LingerState = new LingerOption(true, 0);
TcpClient.Close(); TcpClient?.Close();
} }
} }
} }
...@@ -133,10 +133,6 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -133,10 +133,6 @@ namespace Titanium.Web.Proxy.Network.Tcp
client.ReceiveTimeout = connectionTimeOutSeconds * 1000; client.ReceiveTimeout = connectionTimeOutSeconds * 1000;
client.SendTimeout = connectionTimeOutSeconds * 1000; client.SendTimeout = connectionTimeOutSeconds * 1000;
stream.ReadTimeout = connectionTimeOutSeconds * 1000;
stream.WriteTimeout = connectionTimeOutSeconds * 1000;
return new TcpConnection return new TcpConnection
{ {
UpStreamHttpProxy = externalHttpProxy, UpStreamHttpProxy = externalHttpProxy,
......
...@@ -226,6 +226,8 @@ namespace Titanium.Web.Proxy ...@@ -226,6 +226,8 @@ namespace Titanium.Web.Proxy
public SslProtocols SupportedSslProtocols { get; set; } = SslProtocols.Tls public SslProtocols SupportedSslProtocols { get; set; } = SslProtocols.Tls
| SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Ssl3; | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Ssl3;
public int ClientConnectionCount { get; private set; }
/// <summary> /// <summary>
/// Constructor /// Constructor
/// </summary> /// </summary>
...@@ -495,7 +497,7 @@ namespace Titanium.Web.Proxy ...@@ -495,7 +497,7 @@ namespace Titanium.Web.Proxy
endPoint.Listener = new TcpListener(endPoint.IpAddress, endPoint.Port); endPoint.Listener = new TcpListener(endPoint.IpAddress, endPoint.Port);
endPoint.Listener.Start(); endPoint.Listener.Start();
endPoint.Port = ((IPEndPoint) endPoint.Listener.LocalEndpoint).Port; endPoint.Port = ((IPEndPoint)endPoint.Listener.LocalEndpoint).Port;
// accept clients asynchronously // accept clients asynchronously
endPoint.Listener.BeginAcceptTcpClient(OnAcceptConnection, endPoint); endPoint.Listener.BeginAcceptTcpClient(OnAcceptConnection, endPoint);
} }
...@@ -560,7 +562,7 @@ namespace Titanium.Web.Proxy ...@@ -560,7 +562,7 @@ namespace Titanium.Web.Proxy
/// <param name="asyn"></param> /// <param name="asyn"></param>
private void OnAcceptConnection(IAsyncResult asyn) private void OnAcceptConnection(IAsyncResult asyn)
{ {
var endPoint = (ProxyEndPoint) asyn.AsyncState; var endPoint = (ProxyEndPoint)asyn.AsyncState;
TcpClient tcpClient = null; TcpClient tcpClient = null;
...@@ -586,6 +588,8 @@ namespace Titanium.Web.Proxy ...@@ -586,6 +588,8 @@ namespace Titanium.Web.Proxy
{ {
Task.Run(async () => Task.Run(async () =>
{ {
ClientConnectionCount++;
try try
{ {
if (endPoint.GetType() == typeof(TransparentProxyEndPoint)) if (endPoint.GetType() == typeof(TransparentProxyEndPoint))
...@@ -599,15 +603,14 @@ namespace Titanium.Web.Proxy ...@@ -599,15 +603,14 @@ namespace Titanium.Web.Proxy
} }
finally finally
{ {
if (tcpClient != null) //This line is important!
{ //contributors please don't remove it without discussion
//This line is important! //It helps to avoid eventual deterioration of performance due to TCP port exhaustion
//contributors please don't remove it without discussion //due to default TCP CLOSE_WAIT timeout for 4 minutes
//It helps to avoid eventual deterioration of performance due to TCP port exhaustion tcpClient.LingerState = new LingerOption(true, 0);
//due to default TCP CLOSE_WAIT timeout for 4 minutes tcpClient?.Close();
tcpClient.LingerState = new LingerOption(true, 0);
tcpClient.Close(); ClientConnectionCount--;
}
} }
}); });
} }
......
This diff is collapsed.
...@@ -9,6 +9,8 @@ using Titanium.Web.Proxy.Exceptions; ...@@ -9,6 +9,8 @@ using Titanium.Web.Proxy.Exceptions;
using Titanium.Web.Proxy.Extensions; using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Http; using Titanium.Web.Proxy.Http;
using Titanium.Web.Proxy.Helpers; using Titanium.Web.Proxy.Helpers;
using System.Net.Sockets;
using Titanium.Web.Proxy.Network.Tcp;
namespace Titanium.Web.Proxy namespace Titanium.Web.Proxy
{ {
...@@ -21,14 +23,14 @@ namespace Titanium.Web.Proxy ...@@ -21,14 +23,14 @@ namespace Titanium.Web.Proxy
/// Called asynchronously when a request was successfully and we received the response /// Called asynchronously when a request was successfully and we received the response
/// </summary> /// </summary>
/// <param name="args"></param> /// <param name="args"></param>
/// <returns></returns> /// <returns>true if no errors</returns>
private async Task HandleHttpSessionResponse(SessionEventArgs args) private async Task<bool> HandleHttpSessionResponse(SessionEventArgs args)
{ {
//read response & headers from server
await args.WebSession.ReceiveResponse();
try try
{ {
//read response & headers from server
await args.WebSession.ReceiveResponse();
if (!args.WebSession.Response.ResponseBodyRead) if (!args.WebSession.Response.ResponseBodyRead)
{ {
args.WebSession.Response.ResponseStream = args.WebSession.ServerConnection.Stream; args.WebSession.Response.ResponseStream = args.WebSession.ServerConnection.Stream;
...@@ -44,7 +46,7 @@ namespace Titanium.Web.Proxy ...@@ -44,7 +46,7 @@ namespace Titanium.Web.Proxy
for (int i = 0; i < invocationList.Length; i++) for (int i = 0; i < invocationList.Length; i++)
{ {
handlerTasks[i] = ((Func<object, SessionEventArgs, Task>) invocationList[i])(this, args); handlerTasks[i] = ((Func<object, SessionEventArgs, Task>)invocationList[i])(this, args);
} }
await Task.WhenAll(handlerTasks); await Task.WhenAll(handlerTasks);
...@@ -53,7 +55,7 @@ namespace Titanium.Web.Proxy ...@@ -53,7 +55,7 @@ namespace Titanium.Web.Proxy
if (args.ReRequest) if (args.ReRequest)
{ {
await HandleHttpSessionRequestInternal(null, args, null, null, true); await HandleHttpSessionRequestInternal(null, args, null, null, true);
return; return true;
} }
args.WebSession.Response.ResponseLocked = true; args.WebSession.Response.ResponseLocked = true;
...@@ -125,14 +127,16 @@ namespace Titanium.Web.Proxy ...@@ -125,14 +127,16 @@ namespace Titanium.Web.Proxy
} }
catch (Exception e) catch (Exception e)
{ {
ExceptionFunc(new ProxyHttpException("Error occured wilst handling session response", e, args)); ExceptionFunc(new ProxyHttpException("Error occured whilst handling session response", e, args));
Dispose(args.ProxyClient.ClientStream, args.ProxyClient.ClientStreamReader, Dispose(args.ProxyClient.ClientStream, args.ProxyClient.ClientStreamReader,
args.ProxyClient.ClientStreamWriter, args); args.ProxyClient.ClientStreamWriter, args.WebSession.ServerConnection);
}
finally return false;
{
args.Dispose();
} }
args.Dispose();
return true;
} }
/// <summary> /// <summary>
...@@ -219,24 +223,24 @@ namespace Titanium.Web.Proxy ...@@ -219,24 +223,24 @@ namespace Titanium.Web.Proxy
} }
/// <summary> /// <summary>
/// Handle dispose of a client/server session /// Handle dispose of a client/server session
/// </summary> /// </summary>
/// <param name="clientStream"></param> /// <param name="clientStream"></param>
/// <param name="clientStreamReader"></param> /// <param name="clientStreamReader"></param>
/// <param name="clientStreamWriter"></param> /// <param name="clientStreamWriter"></param>
/// <param name="args"></param> /// <param name="serverConnection"></param>
private void Dispose(Stream clientStream, CustomBinaryReader clientStreamReader, private void Dispose(Stream clientStream,
StreamWriter clientStreamWriter, IDisposable args) CustomBinaryReader clientStreamReader,
StreamWriter clientStreamWriter,
TcpConnection serverConnection)
{ {
clientStream?.Close(); clientStream?.Close();
clientStream?.Dispose(); clientStream?.Dispose();
clientStreamReader?.Dispose(); clientStreamReader?.Dispose();
clientStreamWriter?.Close();
clientStreamWriter?.Dispose(); clientStreamWriter?.Dispose();
args?.Dispose(); serverConnection?.Dispose();
} }
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment