Commit c7b20f97 authored by titanium007's avatar titanium007

Cleanup connection manager

parent ee38be01
......@@ -8,7 +8,7 @@ using System.Net.Sockets;
using System.Text;
using Titanium.Web.Proxy.Exceptions;
using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Http;
using Titanium.Web.Proxy.Network;
using Titanium.Web.Proxy.Models;
namespace Titanium.Web.Proxy.EventArguments
......@@ -32,7 +32,7 @@ namespace Titanium.Web.Proxy.EventArguments
{
_bufferSize = bufferSize;
Client = new Client();
ProxySession = new Http.HttpWebSession();
ProxySession = new HttpWebSession();
}
public Client Client { get; set; }
......
using System.Net;
using System.Text;
using Titanium.Web.Proxy.Http;
using Titanium.Web.Proxy.Network;
namespace Titanium.Web.Proxy.Extensions
{
......
using System.Net;
using System.Text;
using Titanium.Web.Proxy.Http;
using Titanium.Web.Proxy.Network;
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;
using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Models;
namespace Titanium.Web.Proxy.Http
namespace Titanium.Web.Proxy.Network
{
public class Request
{
......@@ -127,7 +127,6 @@ namespace Titanium.Web.Proxy.Http
}
requestLines.AppendLine();
//requestLines.AppendLine();
string request = requestLines.ToString();
byte[] requestBytes = Encoding.ASCII.GetBytes(request);
......@@ -139,6 +138,10 @@ namespace Titanium.Web.Proxy.Http
{
var httpResult = ProxyClient.ServerStreamReader.ReadLine().Split(new char[] { ' ' }, 3);
if(string.IsNullOrEmpty(httpResult[0]))
{
var s = ProxyClient.ServerStreamReader.ReadLine();
}
var httpVersion = httpResult[0];
Version version;
......
......@@ -8,8 +8,9 @@ using System.Threading.Tasks;
using System.IO;
using System.Net.Security;
using Titanium.Web.Proxy.Helpers;
using System.Threading;
namespace Titanium.Web.Proxy.Http
namespace Titanium.Web.Proxy.Network
{
public class TcpConnection
{
......@@ -17,9 +18,16 @@ namespace Titanium.Web.Proxy.Http
public int port { get; set; }
public bool IsSecure { get; set; }
public TcpClient Client { get; set; }
public TcpClient TcpClient { get; set; }
public CustomBinaryReader ServerStreamReader { get; set; }
public Stream Stream { get; set; }
public DateTime LastAccess { get; set; }
public TcpConnection()
{
LastAccess = DateTime.Now;
}
}
internal class TcpConnectionManager
......@@ -28,15 +36,23 @@ namespace Titanium.Web.Proxy.Http
public static TcpConnection GetClient(string Hostname, int port, bool IsSecure)
{
while (true)
{
TcpConnection cached = null;
lock (ConnectionCache)
{
var cached = ConnectionCache.FirstOrDefault(x => x.HostName == Hostname && x.port == port && x.IsSecure == IsSecure && x.Client.Connected);
cached = ConnectionCache.FirstOrDefault(x => x.HostName == Hostname && x.port == port && x.IsSecure == IsSecure && x.TcpClient.Connected);
if (cached != null)
{
ConnectionCache.Remove(cached);
return cached;
}
if (cached != null && !cached.TcpClient.Client.IsConnected())
continue;
if (cached == null)
break;
}
return CreateClient(Hostname, port, IsSecure);
......@@ -69,7 +85,7 @@ namespace Titanium.Web.Proxy.Http
HostName = Hostname,
port = port,
IsSecure = IsSecure,
Client = client,
TcpClient = client,
ServerStreamReader = new CustomBinaryReader(stream, Encoding.ASCII),
Stream = stream
};
......@@ -77,8 +93,31 @@ namespace Titanium.Web.Proxy.Http
public static void ReleaseClient(TcpConnection Connection)
{
Connection.LastAccess = DateTime.Now;
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;
using System.Threading.Tasks;
using Titanium.Web.Proxy.EventArguments;
using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Network;
namespace Titanium.Web.Proxy
{
......@@ -79,6 +80,7 @@ namespace Titanium.Web.Proxy
//useUnsafeHeaderParsing
#endif
NetFrameworkHelper.ToggleAllowUnsafeHeaderParsing(true);
Task.Factory.StartNew(()=>TcpConnectionManager.ClearIdleConnections());
}
......
......@@ -13,7 +13,7 @@ using System.Threading.Tasks;
using Titanium.Web.Proxy.EventArguments;
using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Http;
using Titanium.Web.Proxy.Network;
using Titanium.Web.Proxy.Models;
namespace Titanium.Web.Proxy
......@@ -205,6 +205,7 @@ namespace Titanium.Web.Proxy
//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);
args.ProxySession.SetConnection(connection);
args.ProxySession.SendRequest();
//If request was modified by user
......@@ -228,7 +229,7 @@ namespace Titanium.Web.Proxy
//if connection is closing exit
if (args.ProxySession.Response.ResponseKeepAlive == false)
{
connection.Client.Close();
connection.TcpClient.Close();
Dispose(client, clientStream, clientStreamReader, clientStreamWriter, args);
return;
}
......
......@@ -10,7 +10,7 @@ using System.Threading.Tasks;
using Titanium.Web.Proxy.EventArguments;
using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Http;
using Titanium.Web.Proxy.Network;
using Titanium.Web.Proxy.Models;
namespace Titanium.Web.Proxy
......
......@@ -85,9 +85,10 @@
<Compile Include="Helpers\CertificateManager.cs" />
<Compile Include="Helpers\Firefox.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="Http\HttpWebClient.cs" />
<Compile Include="Network\HttpWebClient.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RequestHandler.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