Commit bf4921a0 authored by justcoding121's avatar justcoding121

#231 Fix server count; don't dispose twice

parent fe08a1fb
...@@ -27,13 +27,15 @@ namespace Titanium.Web.Proxy ...@@ -27,13 +27,15 @@ namespace Titanium.Web.Proxy
//So for HTTPS requests client would send CONNECT header to negotiate a secure tcp tunnel via proxy //So for HTTPS requests client would send CONNECT header to negotiate a secure tcp tunnel via proxy
private async Task HandleClient(ExplicitProxyEndPoint endPoint, TcpClient tcpClient) private async Task HandleClient(ExplicitProxyEndPoint endPoint, TcpClient tcpClient)
{ {
CustomBufferedStream clientStream = new CustomBufferedStream(tcpClient.GetStream(), BufferSize); var disposed = false;
var clientStream = new CustomBufferedStream(tcpClient.GetStream(), BufferSize);
clientStream.ReadTimeout = ConnectionTimeOutSeconds * 1000; clientStream.ReadTimeout = ConnectionTimeOutSeconds * 1000;
clientStream.WriteTimeout = ConnectionTimeOutSeconds * 1000; clientStream.WriteTimeout = ConnectionTimeOutSeconds * 1000;
var clientStreamReader = new CustomBinaryReader(clientStream, BufferSize); var clientStreamReader = new CustomBinaryReader(clientStream, BufferSize);
var clientStreamWriter = new StreamWriter(clientStream) {NewLine = ProxyConstants.NewLine}; var clientStreamWriter = new StreamWriter(clientStream) { NewLine = ProxyConstants.NewLine };
Uri httpRemoteUri; Uri httpRemoteUri;
...@@ -120,7 +122,7 @@ namespace Titanium.Web.Proxy ...@@ -120,7 +122,7 @@ namespace Titanium.Web.Proxy
clientStreamReader.Dispose(); clientStreamReader.Dispose();
clientStreamReader = new CustomBinaryReader(clientStream, BufferSize); clientStreamReader = new CustomBinaryReader(clientStream, BufferSize);
clientStreamWriter = new StreamWriter(clientStream) {NewLine = ProxyConstants.NewLine}; clientStreamWriter = new StreamWriter(clientStream) { NewLine = ProxyConstants.NewLine };
} }
catch catch
{ {
...@@ -147,17 +149,23 @@ namespace Titanium.Web.Proxy ...@@ -147,17 +149,23 @@ namespace Titanium.Web.Proxy
return; return;
} }
//Now create the request //Now create the request
await HandleHttpSessionRequest(tcpClient, httpCmd, clientStream, clientStreamReader, clientStreamWriter, disposed = await HandleHttpSessionRequest(tcpClient, httpCmd, clientStream, clientStreamReader, clientStreamWriter,
httpRemoteUri.Scheme == Uri.UriSchemeHttps ? httpRemoteUri.Host : null, endPoint, httpRemoteUri.Scheme == Uri.UriSchemeHttps ? httpRemoteUri.Host : null, endPoint,
connectRequestHeaders); connectRequestHeaders);
} }
catch (Exception) catch (Exception e)
{ {
ExceptionFunc(new Exception("Error whilst authorizing request", e));
} }
finally finally
{ {
Dispose(clientStream, clientStreamReader, clientStreamWriter, null); if (!disposed)
{
Dispose(clientStream, clientStreamReader, clientStreamWriter, null);
}
} }
} }
...@@ -165,7 +173,9 @@ namespace Titanium.Web.Proxy ...@@ -165,7 +173,9 @@ namespace Titanium.Web.Proxy
//So for HTTPS requests we would start SSL negotiation right away without expecting a CONNECT request from client //So for HTTPS requests we would start SSL negotiation right away without expecting a CONNECT request from client
private async Task HandleClient(TransparentProxyEndPoint endPoint, TcpClient tcpClient) private async Task HandleClient(TransparentProxyEndPoint endPoint, TcpClient tcpClient)
{ {
CustomBufferedStream clientStream = new CustomBufferedStream(tcpClient.GetStream(), BufferSize); var disposed = false;
var clientStream = new CustomBufferedStream(tcpClient.GetStream(), BufferSize);
clientStream.ReadTimeout = ConnectionTimeOutSeconds * 1000; clientStream.ReadTimeout = ConnectionTimeOutSeconds * 1000;
clientStream.WriteTimeout = ConnectionTimeOutSeconds * 1000; clientStream.WriteTimeout = ConnectionTimeOutSeconds * 1000;
...@@ -188,7 +198,7 @@ namespace Titanium.Web.Proxy ...@@ -188,7 +198,7 @@ namespace Titanium.Web.Proxy
clientStream = new CustomBufferedStream(sslStream, BufferSize); clientStream = new CustomBufferedStream(sslStream, BufferSize);
clientStreamReader = new CustomBinaryReader(clientStream, BufferSize); clientStreamReader = new CustomBinaryReader(clientStream, BufferSize);
clientStreamWriter = new StreamWriter(clientStream) {NewLine = ProxyConstants.NewLine}; clientStreamWriter = new StreamWriter(clientStream) { NewLine = ProxyConstants.NewLine };
//HTTPS server created - we can now decrypt the client's traffic //HTTPS server created - we can now decrypt the client's traffic
} }
catch (Exception) catch (Exception)
...@@ -199,21 +209,27 @@ namespace Titanium.Web.Proxy ...@@ -199,21 +209,27 @@ namespace Titanium.Web.Proxy
clientStreamReader, clientStreamReader,
clientStreamWriter, null); clientStreamWriter, null);
disposed = true;
return; return;
} }
} }
else else
{ {
clientStreamReader = new CustomBinaryReader(clientStream, BufferSize); clientStreamReader = new CustomBinaryReader(clientStream, BufferSize);
clientStreamWriter = new StreamWriter(clientStream) {NewLine = ProxyConstants.NewLine}; clientStreamWriter = new StreamWriter(clientStream) { NewLine = ProxyConstants.NewLine };
} }
//now read the request line //now read the request line
var httpCmd = await clientStreamReader.ReadLineAsync(); var httpCmd = await clientStreamReader.ReadLineAsync();
//Now create the request //Now create the request
await HandleHttpSessionRequest(tcpClient, httpCmd, clientStream, clientStreamReader, clientStreamWriter, disposed = await HandleHttpSessionRequest(tcpClient, httpCmd, clientStream, clientStreamReader, clientStreamWriter,
endPoint.EnableSsl ? endPoint.GenericCertificateName : null, endPoint, null); endPoint.EnableSsl ? endPoint.GenericCertificateName : null, endPoint, null);
if (!disposed)
{
Dispose(clientStream, clientStreamReader, clientStreamWriter, null);
}
} }
/// <summary> /// <summary>
...@@ -271,7 +287,7 @@ namespace Titanium.Web.Proxy ...@@ -271,7 +287,7 @@ namespace Titanium.Web.Proxy
args.ProxyClient.ClientStreamWriter, args.ProxyClient.ClientStreamWriter,
args.WebSession.ServerConnection); args.WebSession.ServerConnection);
return false; return true;
} }
//if expect continue is enabled then send the headers first //if expect continue is enabled then send the headers first
...@@ -335,12 +351,12 @@ namespace Titanium.Web.Proxy ...@@ -335,12 +351,12 @@ namespace Titanium.Web.Proxy
//If not expectation failed response was returned by server then parse response //If not expectation failed response was returned by server then parse response
if (!args.WebSession.Request.ExpectationFailed) if (!args.WebSession.Request.ExpectationFailed)
{ {
var result = await HandleHttpSessionResponse(args); var disposed = await HandleHttpSessionResponse(args);
//already disposed inside above method //already disposed inside above method
if (result == false) if (disposed)
{ {
return false; return disposed;
} }
} }
...@@ -352,7 +368,7 @@ namespace Titanium.Web.Proxy ...@@ -352,7 +368,7 @@ namespace Titanium.Web.Proxy
args.ProxyClient.ClientStreamWriter, args.ProxyClient.ClientStreamWriter,
args.WebSession.ServerConnection); args.WebSession.ServerConnection);
return false; return true;
} }
} }
catch (Exception e) catch (Exception e)
...@@ -364,7 +380,7 @@ namespace Titanium.Web.Proxy ...@@ -364,7 +380,7 @@ namespace Titanium.Web.Proxy
args.ProxyClient.ClientStreamWriter, args.ProxyClient.ClientStreamWriter,
args.WebSession.ServerConnection); args.WebSession.ServerConnection);
return false; return true;
} }
if (closeConnection) if (closeConnection)
...@@ -375,10 +391,10 @@ namespace Titanium.Web.Proxy ...@@ -375,10 +391,10 @@ namespace Titanium.Web.Proxy
args.ProxyClient.ClientStreamWriter, args.ProxyClient.ClientStreamWriter,
args.WebSession.ServerConnection); args.WebSession.ServerConnection);
return false; return true;
} }
return true; return false;
} }
/// <summary> /// <summary>
...@@ -393,10 +409,12 @@ namespace Titanium.Web.Proxy ...@@ -393,10 +409,12 @@ namespace Titanium.Web.Proxy
/// <param name="endPoint"></param> /// <param name="endPoint"></param>
/// <param name="connectHeaders"></param> /// <param name="connectHeaders"></param>
/// <returns></returns> /// <returns></returns>
private async Task HandleHttpSessionRequest(TcpClient client, string httpCmd, Stream clientStream, private async Task<bool> HandleHttpSessionRequest(TcpClient client, string httpCmd, Stream clientStream,
CustomBinaryReader clientStreamReader, StreamWriter clientStreamWriter, string httpsHostName, CustomBinaryReader clientStreamReader, StreamWriter clientStreamWriter, string httpsHostName,
ProxyEndPoint endPoint, List<HttpHeader> connectHeaders) ProxyEndPoint endPoint, List<HttpHeader> connectHeaders)
{ {
var disposed = false;
TcpConnection connection = null; TcpConnection connection = null;
//Loop through each subsequest request on this particular client connection //Loop through each subsequest request on this particular client connection
...@@ -410,13 +428,14 @@ namespace Titanium.Web.Proxy ...@@ -410,13 +428,14 @@ namespace Titanium.Web.Proxy
clientStreamWriter, clientStreamWriter,
connection); connection);
disposed = true;
break; break;
} }
var args = new SessionEventArgs(BufferSize, HandleHttpSessionResponse) var args = new SessionEventArgs(BufferSize, HandleHttpSessionResponse)
{ {
ProxyClient = {TcpClient = client}, ProxyClient = { TcpClient = client },
WebSession = {ConnectHeaders = connectHeaders} WebSession = { ConnectHeaders = connectHeaders }
}; };
args.WebSession.ProcessId = new Lazy<int>(() => args.WebSession.ProcessId = new Lazy<int>(() =>
...@@ -476,6 +495,7 @@ namespace Titanium.Web.Proxy ...@@ -476,6 +495,7 @@ namespace Titanium.Web.Proxy
clientStreamWriter, clientStreamWriter,
connection); connection);
disposed = true;
break; break;
} }
...@@ -501,6 +521,7 @@ namespace Titanium.Web.Proxy ...@@ -501,6 +521,7 @@ namespace Titanium.Web.Proxy
clientStreamWriter, clientStreamWriter,
connection); connection);
disposed = true;
break; break;
} }
...@@ -510,9 +531,9 @@ namespace Titanium.Web.Proxy ...@@ -510,9 +531,9 @@ namespace Titanium.Web.Proxy
} }
//construct the web request that we are going to issue on behalf of the client. //construct the web request that we are going to issue on behalf of the client.
var result = await HandleHttpSessionRequestInternal(connection, args, false); disposed = await HandleHttpSessionRequestInternal(connection, args, false);
if (result == false) if (disposed)
{ {
//already disposed inside above method //already disposed inside above method
break; break;
...@@ -525,6 +546,7 @@ namespace Titanium.Web.Proxy ...@@ -525,6 +546,7 @@ namespace Titanium.Web.Proxy
clientStreamWriter, clientStreamWriter,
connection); connection);
disposed = true;
break; break;
} }
...@@ -536,6 +558,7 @@ namespace Titanium.Web.Proxy ...@@ -536,6 +558,7 @@ namespace Titanium.Web.Proxy
clientStreamWriter, clientStreamWriter,
connection); connection);
disposed = true;
break; break;
} }
...@@ -550,9 +573,13 @@ namespace Titanium.Web.Proxy ...@@ -550,9 +573,13 @@ namespace Titanium.Web.Proxy
clientStreamReader, clientStreamReader,
clientStreamWriter, clientStreamWriter,
connection); connection);
disposed = true;
break; break;
} }
} }
return disposed;
} }
/// <summary> /// <summary>
......
...@@ -23,7 +23,7 @@ namespace Titanium.Web.Proxy ...@@ -23,7 +23,7 @@ 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>true if no errors</returns> /// <returns>true if client/server connection was terminated (and disposed) </returns>
private async Task<bool> HandleHttpSessionResponse(SessionEventArgs args) private async Task<bool> HandleHttpSessionResponse(SessionEventArgs args)
{ {
try try
...@@ -130,12 +130,12 @@ namespace Titanium.Web.Proxy ...@@ -130,12 +130,12 @@ namespace Titanium.Web.Proxy
Dispose(args.ProxyClient.ClientStream, args.ProxyClient.ClientStreamReader, Dispose(args.ProxyClient.ClientStream, args.ProxyClient.ClientStreamReader,
args.ProxyClient.ClientStreamWriter, args.WebSession.ServerConnection); args.ProxyClient.ClientStreamWriter, args.WebSession.ServerConnection);
return false; return true;
} }
args.Dispose(); args.Dispose();
return true; return false;
} }
/// <summary> /// <summary>
...@@ -233,15 +233,18 @@ namespace Titanium.Web.Proxy ...@@ -233,15 +233,18 @@ namespace Titanium.Web.Proxy
StreamWriter clientStreamWriter, StreamWriter clientStreamWriter,
TcpConnection serverConnection) TcpConnection serverConnection)
{ {
Interlocked.Decrement(ref ServerConnectionCountField);
clientStream?.Close(); clientStream?.Close();
clientStream?.Dispose(); clientStream?.Dispose();
clientStreamReader?.Dispose(); clientStreamReader?.Dispose();
clientStreamWriter?.Dispose(); clientStreamWriter?.Dispose();
serverConnection?.Dispose(); if (serverConnection != null)
{
serverConnection.Dispose();
Interlocked.Decrement(ref ServerConnectionCountField);
}
} }
} }
} }
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