Commit c7b20f97 authored by titanium007's avatar titanium007

Cleanup connection manager

parent ee38be01
...@@ -8,7 +8,7 @@ using System.Net.Sockets; ...@@ -8,7 +8,7 @@ using System.Net.Sockets;
using System.Text; using System.Text;
using Titanium.Web.Proxy.Exceptions; using Titanium.Web.Proxy.Exceptions;
using Titanium.Web.Proxy.Helpers; using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Http; using Titanium.Web.Proxy.Network;
using Titanium.Web.Proxy.Models; using Titanium.Web.Proxy.Models;
namespace Titanium.Web.Proxy.EventArguments namespace Titanium.Web.Proxy.EventArguments
...@@ -32,7 +32,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -32,7 +32,7 @@ namespace Titanium.Web.Proxy.EventArguments
{ {
_bufferSize = bufferSize; _bufferSize = bufferSize;
Client = new Client(); Client = new Client();
ProxySession = new Http.HttpWebSession(); ProxySession = new HttpWebSession();
} }
public Client Client { get; set; } public Client Client { get; set; }
......
using System.Net; using System.Net;
using System.Text; using System.Text;
using Titanium.Web.Proxy.Http; using Titanium.Web.Proxy.Network;
namespace Titanium.Web.Proxy.Extensions namespace Titanium.Web.Proxy.Extensions
{ {
......
using System.Net; using System.Net;
using System.Text; using System.Text;
using Titanium.Web.Proxy.Http; using Titanium.Web.Proxy.Network;
namespace Titanium.Web.Proxy.Extensions namespace Titanium.Web.Proxy.Extensions
{ {
......
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Titanium.Web.Proxy.Http
{
//public class HttpStreamReader
//{
// public static async Task<string> ReadLine(Stream stream)
// {
// var readBuffer = new StringBuilder();
// try
// {
// var lastChar = default(char);
// var buffer = new byte[1];
// while ((await stream.ReadAsync(buffer, 0, 1)) > 0)
// {
// if (lastChar == '\r' && buffer[0] == '\n')
// {
// return readBuffer.Remove(readBuffer.Length - 1, 1).ToString();
// }
// if (buffer[0] == '\0')
// {
// return readBuffer.ToString();
// }
// readBuffer.Append(Encoding.ASCII.GetString(buffer));
// lastChar = Encoding.ASCII.GetChars(buffer)[0];
// }
// return readBuffer.ToString();
// }
// catch (IOException)
// {
// return readBuffer.ToString();
// }
// }
// public static async Task<List<string>> ReadAllLines(Stream stream)
// {
// string tmpLine;
// var requestLines = new List<string>();
// while (!string.IsNullOrEmpty(tmpLine = await ReadLine(stream)))
// {
// requestLines.Add(tmpLine);
// }
// return requestLines;
// }
//}
}
...@@ -10,7 +10,7 @@ using System.Threading.Tasks; ...@@ -10,7 +10,7 @@ using System.Threading.Tasks;
using Titanium.Web.Proxy.Helpers; using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Models; using Titanium.Web.Proxy.Models;
namespace Titanium.Web.Proxy.Http namespace Titanium.Web.Proxy.Network
{ {
public class Request public class Request
{ {
...@@ -127,7 +127,6 @@ namespace Titanium.Web.Proxy.Http ...@@ -127,7 +127,6 @@ namespace Titanium.Web.Proxy.Http
} }
requestLines.AppendLine(); requestLines.AppendLine();
//requestLines.AppendLine();
string request = requestLines.ToString(); string request = requestLines.ToString();
byte[] requestBytes = Encoding.ASCII.GetBytes(request); byte[] requestBytes = Encoding.ASCII.GetBytes(request);
...@@ -139,6 +138,10 @@ namespace Titanium.Web.Proxy.Http ...@@ -139,6 +138,10 @@ namespace Titanium.Web.Proxy.Http
{ {
var httpResult = ProxyClient.ServerStreamReader.ReadLine().Split(new char[] { ' ' }, 3); var httpResult = ProxyClient.ServerStreamReader.ReadLine().Split(new char[] { ' ' }, 3);
if(string.IsNullOrEmpty(httpResult[0]))
{
var s = ProxyClient.ServerStreamReader.ReadLine();
}
var httpVersion = httpResult[0]; var httpVersion = httpResult[0];
Version version; Version version;
......
...@@ -8,8 +8,9 @@ using System.Threading.Tasks; ...@@ -8,8 +8,9 @@ using System.Threading.Tasks;
using System.IO; using System.IO;
using System.Net.Security; using System.Net.Security;
using Titanium.Web.Proxy.Helpers; using Titanium.Web.Proxy.Helpers;
using System.Threading;
namespace Titanium.Web.Proxy.Http namespace Titanium.Web.Proxy.Network
{ {
public class TcpConnection public class TcpConnection
{ {
...@@ -17,9 +18,16 @@ namespace Titanium.Web.Proxy.Http ...@@ -17,9 +18,16 @@ namespace Titanium.Web.Proxy.Http
public int port { get; set; } public int port { get; set; }
public bool IsSecure { get; set; } public bool IsSecure { get; set; }
public TcpClient Client { get; set; } public TcpClient TcpClient { get; set; }
public CustomBinaryReader ServerStreamReader { get; set; } public CustomBinaryReader ServerStreamReader { get; set; }
public Stream Stream { get; set; } public Stream Stream { get; set; }
public DateTime LastAccess { get; set; }
public TcpConnection()
{
LastAccess = DateTime.Now;
}
} }
internal class TcpConnectionManager internal class TcpConnectionManager
...@@ -28,15 +36,23 @@ namespace Titanium.Web.Proxy.Http ...@@ -28,15 +36,23 @@ namespace Titanium.Web.Proxy.Http
public static TcpConnection GetClient(string Hostname, int port, bool IsSecure) public static TcpConnection GetClient(string Hostname, int port, bool IsSecure)
{ {
lock (ConnectionCache)
{
var cached = ConnectionCache.FirstOrDefault(x => x.HostName == Hostname && x.port == port && x.IsSecure == IsSecure && x.Client.Connected);
if (cached != null) while (true)
{
TcpConnection cached = null;
lock (ConnectionCache)
{ {
ConnectionCache.Remove(cached); cached = ConnectionCache.FirstOrDefault(x => x.HostName == Hostname && x.port == port && x.IsSecure == IsSecure && x.TcpClient.Connected);
return cached;
if (cached != null)
ConnectionCache.Remove(cached);
} }
if (cached != null && !cached.TcpClient.Client.IsConnected())
continue;
if (cached == null)
break;
} }
return CreateClient(Hostname, port, IsSecure); return CreateClient(Hostname, port, IsSecure);
...@@ -69,7 +85,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -69,7 +85,7 @@ namespace Titanium.Web.Proxy.Http
HostName = Hostname, HostName = Hostname,
port = port, port = port,
IsSecure = IsSecure, IsSecure = IsSecure,
Client = client, TcpClient = client,
ServerStreamReader = new CustomBinaryReader(stream, Encoding.ASCII), ServerStreamReader = new CustomBinaryReader(stream, Encoding.ASCII),
Stream = stream Stream = stream
}; };
...@@ -77,8 +93,31 @@ namespace Titanium.Web.Proxy.Http ...@@ -77,8 +93,31 @@ namespace Titanium.Web.Proxy.Http
public static void ReleaseClient(TcpConnection Connection) public static void ReleaseClient(TcpConnection Connection)
{ {
Connection.LastAccess = DateTime.Now;
ConnectionCache.Add(Connection); ConnectionCache.Add(Connection);
} }
public static void ClearIdleConnections()
{
while (true)
{
lock (ConnectionCache)
{
var cutOff = DateTime.Now.AddSeconds(-60);
ConnectionCache
.Where(x => x.LastAccess < cutOff)
.ToList()
.ForEach(x => x.TcpClient.Close());
ConnectionCache.RemoveAll(x => x.LastAccess < cutOff);
}
Thread.Sleep(1000 * 60 * 3);
}
}
} }
} }
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace Titanium.Web.Proxy.Network
{
internal static class TcpExtensions
{
public static bool IsConnected(this Socket client)
{
// This is how you can determine whether a socket is still connected.
bool blockingState = client.Blocking;
try
{
byte[] tmp = new byte[1];
client.Blocking = false;
client.Send(tmp, 0, 0);
return true;
}
catch (SocketException e)
{
// 10035 == WSAEWOULDBLOCK
if (e.NativeErrorCode.Equals(10035))
return true;
else
{
return false;
}
}
finally
{
client.Blocking = blockingState;
}
}
}
}
...@@ -9,6 +9,7 @@ using System.Text.RegularExpressions; ...@@ -9,6 +9,7 @@ using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using Titanium.Web.Proxy.EventArguments; using Titanium.Web.Proxy.EventArguments;
using Titanium.Web.Proxy.Helpers; using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Network;
namespace Titanium.Web.Proxy namespace Titanium.Web.Proxy
{ {
...@@ -79,6 +80,7 @@ namespace Titanium.Web.Proxy ...@@ -79,6 +80,7 @@ namespace Titanium.Web.Proxy
//useUnsafeHeaderParsing //useUnsafeHeaderParsing
#endif #endif
NetFrameworkHelper.ToggleAllowUnsafeHeaderParsing(true); NetFrameworkHelper.ToggleAllowUnsafeHeaderParsing(true);
Task.Factory.StartNew(()=>TcpConnectionManager.ClearIdleConnections());
} }
......
...@@ -13,7 +13,7 @@ using System.Threading.Tasks; ...@@ -13,7 +13,7 @@ using System.Threading.Tasks;
using Titanium.Web.Proxy.EventArguments; using Titanium.Web.Proxy.EventArguments;
using Titanium.Web.Proxy.Extensions; using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Helpers; using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Http; using Titanium.Web.Proxy.Network;
using Titanium.Web.Proxy.Models; using Titanium.Web.Proxy.Models;
namespace Titanium.Web.Proxy namespace Titanium.Web.Proxy
...@@ -115,7 +115,7 @@ namespace Titanium.Web.Proxy ...@@ -115,7 +115,7 @@ namespace Titanium.Web.Proxy
private static void HandleHttpSessionRequest(TcpClient client, string httpCmd, Stream clientStream, private static void HandleHttpSessionRequest(TcpClient client, string httpCmd, Stream clientStream,
CustomBinaryReader clientStreamReader, StreamWriter clientStreamWriter, string secureTunnelHostName) CustomBinaryReader clientStreamReader, StreamWriter clientStreamWriter, string secureTunnelHostName)
{ {
while (true) while (true)
{ {
if (string.IsNullOrEmpty(httpCmd)) if (string.IsNullOrEmpty(httpCmd))
...@@ -201,10 +201,11 @@ namespace Titanium.Web.Proxy ...@@ -201,10 +201,11 @@ namespace Titanium.Web.Proxy
return; return;
} }
//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 connection = TcpConnectionManager.GetClient(args.ProxySession.Request.RequestUri.Host, args.ProxySession.Request.RequestUri.Port, args.IsHttps); var connection = TcpConnectionManager.GetClient(args.ProxySession.Request.RequestUri.Host, args.ProxySession.Request.RequestUri.Port, args.IsHttps);
args.ProxySession.SetConnection(connection); args.ProxySession.SetConnection(connection);
args.ProxySession.SendRequest(); args.ProxySession.SendRequest();
//If request was modified by user //If request was modified by user
...@@ -228,7 +229,7 @@ namespace Titanium.Web.Proxy ...@@ -228,7 +229,7 @@ namespace Titanium.Web.Proxy
//if connection is closing exit //if connection is closing exit
if (args.ProxySession.Response.ResponseKeepAlive == false) if (args.ProxySession.Response.ResponseKeepAlive == false)
{ {
connection.Client.Close(); connection.TcpClient.Close();
Dispose(client, clientStream, clientStreamReader, clientStreamWriter, args); Dispose(client, clientStream, clientStreamReader, clientStreamWriter, args);
return; return;
} }
......
...@@ -10,7 +10,7 @@ using System.Threading.Tasks; ...@@ -10,7 +10,7 @@ using System.Threading.Tasks;
using Titanium.Web.Proxy.EventArguments; using Titanium.Web.Proxy.EventArguments;
using Titanium.Web.Proxy.Extensions; using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Helpers; using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Http; using Titanium.Web.Proxy.Network;
using Titanium.Web.Proxy.Models; using Titanium.Web.Proxy.Models;
namespace Titanium.Web.Proxy namespace Titanium.Web.Proxy
......
...@@ -85,9 +85,10 @@ ...@@ -85,9 +85,10 @@
<Compile Include="Helpers\CertificateManager.cs" /> <Compile Include="Helpers\CertificateManager.cs" />
<Compile Include="Helpers\Firefox.cs" /> <Compile Include="Helpers\Firefox.cs" />
<Compile Include="Helpers\SystemProxy.cs" /> <Compile Include="Helpers\SystemProxy.cs" />
<Compile Include="Http\TcpConnectionManager.cs" /> <Compile Include="Network\TcpExtensions.cs" />
<Compile Include="Network\TcpConnectionManager.cs" />
<Compile Include="Models\HttpHeader.cs" /> <Compile Include="Models\HttpHeader.cs" />
<Compile Include="Http\HttpWebClient.cs" /> <Compile Include="Network\HttpWebClient.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RequestHandler.cs" /> <Compile Include="RequestHandler.cs" />
<Compile Include="ResponseHandler.cs" /> <Compile Include="ResponseHandler.cs" />
......
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