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)
{ {
while (true)
{
TcpConnection cached = null;
lock (ConnectionCache) 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) if (cached != null)
{
ConnectionCache.Remove(cached); ConnectionCache.Remove(cached);
return 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
...@@ -205,6 +205,7 @@ 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. //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