Commit 48051d22 authored by justcoding121's avatar justcoding121

asyncify

add async for client/server ssl authentication
parent 90c53a54
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Net.Security;
using System.Net.Sockets;
using System.Text; using System.Text;
using Titanium.Web.Proxy.Network;
using Titanium.Web.Proxy.Shared;
namespace Titanium.Web.Proxy.Helpers namespace Titanium.Web.Proxy.Helpers
{ {
...@@ -9,13 +14,19 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -9,13 +14,19 @@ namespace Titanium.Web.Proxy.Helpers
/// using the specified encoding /// using the specified encoding
/// as well as to read bytes as required /// as well as to read bytes as required
/// </summary> /// </summary>
public class CustomBinaryReader : BinaryReader public class CustomBinaryReader : IDisposable
{ {
internal CustomBinaryReader(Stream stream, Encoding encoding) private Stream stream;
: base(stream, encoding)
internal CustomBinaryReader(Stream stream)
{ {
this.stream = stream;
} }
public Stream BaseStream => stream;
/// <summary> /// <summary>
/// Read a line from the byte stream /// Read a line from the byte stream
/// </summary> /// </summary>
...@@ -27,9 +38,9 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -27,9 +38,9 @@ namespace Titanium.Web.Proxy.Helpers
try try
{ {
var lastChar = default(char); var lastChar = default(char);
var buffer = new char[1]; var buffer = new byte[1];
while (Read(buffer, 0, 1) > 0) while (this.stream.Read(buffer, 0, 1) > 0)
{ {
if (lastChar == '\r' && buffer[0] == '\n') if (lastChar == '\r' && buffer[0] == '\n')
{ {
...@@ -39,8 +50,8 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -39,8 +50,8 @@ namespace Titanium.Web.Proxy.Helpers
{ {
return readBuffer.ToString(); return readBuffer.ToString();
} }
readBuffer.Append(buffer); readBuffer.Append((char)buffer[0]);
lastChar = buffer[0]; lastChar = (char)buffer[0];
} }
return readBuffer.ToString(); return readBuffer.ToString();
...@@ -65,5 +76,42 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -65,5 +76,42 @@ namespace Titanium.Web.Proxy.Helpers
} }
return requestLines; return requestLines;
} }
internal byte[] ReadBytes(long totalBytesToRead)
{
int bytesToRead = Constants.BUFFER_SIZE;
if (totalBytesToRead < Constants.BUFFER_SIZE)
bytesToRead = (int)totalBytesToRead;
var buffer = new byte[Constants.BUFFER_SIZE];
var bytesRead = 0;
var totalBytesRead = 0;
using (var outStream = new MemoryStream())
{
while ((bytesRead += this.stream.Read(buffer, 0, bytesToRead)) > 0)
{
outStream.Write(buffer, 0, bytesRead);
totalBytesRead += bytesRead;
if (totalBytesRead == totalBytesToRead)
break;
bytesRead = 0;
var remainingBytes = (totalBytesToRead - totalBytesRead);
bytesToRead = remainingBytes > (long)Constants.BUFFER_SIZE ? Constants.BUFFER_SIZE : (int)remainingBytes;
}
return outStream.ToArray();
}
}
public void Dispose()
{
}
} }
} }
\ No newline at end of file
...@@ -39,7 +39,7 @@ namespace Titanium.Web.Proxy.Network ...@@ -39,7 +39,7 @@ namespace Titanium.Web.Proxy.Network
{ {
static List<TcpConnection> ConnectionCache = new List<TcpConnection>(); static List<TcpConnection> ConnectionCache = new List<TcpConnection>();
internal static TcpConnection GetClient(SessionEventArgs sessionArgs, string hostname, int port, bool isSecure, Version version) internal static async Task<TcpConnection> GetClient(SessionEventArgs sessionArgs, string hostname, int port, bool isSecure, Version version)
{ {
TcpConnection cached = null; TcpConnection cached = null;
while (true) while (true)
...@@ -61,18 +61,18 @@ namespace Titanium.Web.Proxy.Network ...@@ -61,18 +61,18 @@ namespace Titanium.Web.Proxy.Network
} }
if (cached == null) if (cached == null)
cached = CreateClient(sessionArgs,hostname, port, isSecure, version); cached = await CreateClient(sessionArgs,hostname, port, isSecure, version);
if (ConnectionCache.Where(x => x.HostName == hostname && x.port == port && //if (ConnectionCache.Where(x => x.HostName == hostname && x.port == port &&
x.IsSecure == isSecure && x.TcpClient.Connected && x.Version.Equals(version)).Count() < 2) //x.IsSecure == isSecure && x.TcpClient.Connected && x.Version.Equals(version)).Count() < 2)
{ //{
Task.Factory.StartNew(() => CreateClient(sessionArgs, hostname, port, isSecure, version)); // Task.Factory.StartNew(() => CreateClient(sessionArgs, hostname, port, isSecure, version));
} //}
return cached; return cached;
} }
private static TcpConnection CreateClient(SessionEventArgs sessionArgs, string hostname, int port, bool isSecure, Version version) private static async Task<TcpConnection> CreateClient(SessionEventArgs sessionArgs, string hostname, int port, bool isSecure, Version version)
{ {
TcpClient client; TcpClient client;
Stream stream; Stream stream;
...@@ -86,7 +86,7 @@ namespace Titanium.Web.Proxy.Network ...@@ -86,7 +86,7 @@ namespace Titanium.Web.Proxy.Network
client = new TcpClient(ProxyServer.UpStreamHttpsProxy.HostName, ProxyServer.UpStreamHttpsProxy.Port); client = new TcpClient(ProxyServer.UpStreamHttpsProxy.HostName, ProxyServer.UpStreamHttpsProxy.Port);
stream = (Stream)client.GetStream(); stream = (Stream)client.GetStream();
var writer = new StreamWriter(stream); var writer = new StreamWriter(stream,Encoding.ASCII, Constants.BUFFER_SIZE, true);
writer.WriteLine(string.Format("CONNECT {0}:{1} {2}", sessionArgs.WebSession.Request.RequestUri.Host, sessionArgs.WebSession.Request.RequestUri.Port, sessionArgs.WebSession.Request.HttpVersion)); writer.WriteLine(string.Format("CONNECT {0}:{1} {2}", sessionArgs.WebSession.Request.RequestUri.Host, sessionArgs.WebSession.Request.RequestUri.Port, sessionArgs.WebSession.Request.HttpVersion));
writer.WriteLine(string.Format("Host: {0}:{1}", sessionArgs.WebSession.Request.RequestUri.Host, sessionArgs.WebSession.Request.RequestUri.Port)); writer.WriteLine(string.Format("Host: {0}:{1}", sessionArgs.WebSession.Request.RequestUri.Host, sessionArgs.WebSession.Request.RequestUri.Port));
...@@ -94,7 +94,7 @@ namespace Titanium.Web.Proxy.Network ...@@ -94,7 +94,7 @@ namespace Titanium.Web.Proxy.Network
writer.WriteLine(); writer.WriteLine();
writer.Flush(); writer.Flush();
var reader = new CustomBinaryReader(stream, Encoding.ASCII); var reader = new CustomBinaryReader(stream);
var result = reader.ReadLine(); var result = reader.ReadLine();
if (!result.ToLower().Contains("200 connection established")) if (!result.ToLower().Contains("200 connection established"))
...@@ -112,7 +112,7 @@ namespace Titanium.Web.Proxy.Network ...@@ -112,7 +112,7 @@ namespace Titanium.Web.Proxy.Network
{ {
sslStream = new CustomSslStream(stream, true, ProxyServer.ValidateServerCertificate); sslStream = new CustomSslStream(stream, true, ProxyServer.ValidateServerCertificate);
sslStream.Session = sessionArgs; sslStream.Session = sessionArgs;
sslStream.AuthenticateAsClient(hostname, null, Constants.SupportedProtocols, false); await sslStream.AuthenticateAsClientAsync(hostname, null, Constants.SupportedProtocols, false);
stream = (Stream)sslStream; stream = (Stream)sslStream;
} }
catch catch
...@@ -142,7 +142,7 @@ namespace Titanium.Web.Proxy.Network ...@@ -142,7 +142,7 @@ namespace Titanium.Web.Proxy.Network
port = port, port = port,
IsSecure = isSecure, IsSecure = isSecure,
TcpClient = client, TcpClient = client,
ServerStreamReader = new CustomBinaryReader(stream, Encoding.ASCII), ServerStreamReader = new CustomBinaryReader(stream),
Stream = stream, Stream = stream,
Version = version Version = version
}; };
......
...@@ -16,16 +16,17 @@ using System.Security.Cryptography.X509Certificates; ...@@ -16,16 +16,17 @@ using System.Security.Cryptography.X509Certificates;
using Titanium.Web.Proxy.Shared; using Titanium.Web.Proxy.Shared;
using Titanium.Web.Proxy.Http; using Titanium.Web.Proxy.Http;
using Titanium.Web.Proxy.Extensions; using Titanium.Web.Proxy.Extensions;
using System.Threading.Tasks;
namespace Titanium.Web.Proxy namespace Titanium.Web.Proxy
{ {
partial class ProxyServer partial class ProxyServer
{ {
//This is called when client is aware of proxy //This is called when client is aware of proxy
private static void HandleClient(ExplicitProxyEndPoint endPoint, TcpClient client) private static async void HandleClient(ExplicitProxyEndPoint endPoint, TcpClient client)
{ {
Stream clientStream = client.GetStream(); Stream clientStream = client.GetStream();
var clientStreamReader = new CustomBinaryReader(clientStream, Encoding.ASCII); var clientStreamReader = new CustomBinaryReader(clientStream);
var clientStreamWriter = new StreamWriter(clientStream); var clientStreamWriter = new StreamWriter(clientStream);
Uri httpRemoteUri; Uri httpRemoteUri;
...@@ -75,10 +76,10 @@ namespace Titanium.Web.Proxy ...@@ -75,10 +76,10 @@ namespace Titanium.Web.Proxy
sslStream = new SslStream(clientStream, true); sslStream = new SslStream(clientStream, true);
//Successfully managed to authenticate the client using the fake certificate //Successfully managed to authenticate the client using the fake certificate
sslStream.AuthenticateAsServer(certificate, false, await sslStream.AuthenticateAsServerAsync(certificate, false,
Constants.SupportedProtocols, false); Constants.SupportedProtocols, false);
clientStreamReader = new CustomBinaryReader(sslStream, Encoding.ASCII); clientStreamReader = new CustomBinaryReader(sslStream);
clientStreamWriter = new StreamWriter(sslStream); clientStreamWriter = new StreamWriter(sslStream);
//HTTPS server created - we can now decrypt the client's traffic //HTTPS server created - we can now decrypt the client's traffic
clientStream = sslStream; clientStream = sslStream;
...@@ -111,7 +112,7 @@ namespace Titanium.Web.Proxy ...@@ -111,7 +112,7 @@ namespace Titanium.Web.Proxy
//Now create the request //Now create the request
HandleHttpSessionRequest(client, httpCmd, clientStream, clientStreamReader, clientStreamWriter, await HandleHttpSessionRequest(client, httpCmd, clientStream, clientStreamReader, clientStreamWriter,
httpRemoteUri.Scheme == Uri.UriSchemeHttps ? true : false); httpRemoteUri.Scheme == Uri.UriSchemeHttps ? true : false);
} }
catch catch
...@@ -122,7 +123,7 @@ namespace Titanium.Web.Proxy ...@@ -122,7 +123,7 @@ namespace Titanium.Web.Proxy
//This is called when requests are routed through router to this endpoint //This is called when requests are routed through router to this endpoint
//For ssl requests //For ssl requests
private static void HandleClient(TransparentProxyEndPoint endPoint, TcpClient tcpClient) private static async Task HandleClient(TransparentProxyEndPoint endPoint, TcpClient tcpClient)
{ {
Stream clientStream = tcpClient.GetStream(); Stream clientStream = tcpClient.GetStream();
CustomBinaryReader clientStreamReader = null; CustomBinaryReader clientStreamReader = null;
...@@ -146,7 +147,7 @@ namespace Titanium.Web.Proxy ...@@ -146,7 +147,7 @@ namespace Titanium.Web.Proxy
sslStream.AuthenticateAsServer(certificate, false, sslStream.AuthenticateAsServer(certificate, false,
SslProtocols.Tls, false); SslProtocols.Tls, false);
clientStreamReader = new CustomBinaryReader(sslStream, Encoding.ASCII); clientStreamReader = new CustomBinaryReader(sslStream);
clientStreamWriter = new StreamWriter(sslStream); clientStreamWriter = new StreamWriter(sslStream);
//HTTPS server created - we can now decrypt the client's traffic //HTTPS server created - we can now decrypt the client's traffic
...@@ -163,17 +164,17 @@ namespace Titanium.Web.Proxy ...@@ -163,17 +164,17 @@ namespace Titanium.Web.Proxy
} }
else else
{ {
clientStreamReader = new CustomBinaryReader(clientStream, Encoding.ASCII); clientStreamReader = new CustomBinaryReader(clientStream);
} }
var httpCmd = clientStreamReader.ReadLine(); var httpCmd = clientStreamReader.ReadLine();
//Now create the request //Now create the request
HandleHttpSessionRequest(tcpClient, httpCmd, clientStream, clientStreamReader, clientStreamWriter, await HandleHttpSessionRequest(tcpClient, httpCmd, clientStream, clientStreamReader, clientStreamWriter,
true); true);
} }
private static void HandleHttpSessionRequest(TcpClient client, string httpCmd, Stream clientStream, private static async Task HandleHttpSessionRequest(TcpClient client, string httpCmd, Stream clientStream,
CustomBinaryReader clientStreamReader, StreamWriter clientStreamWriter, bool IsHttps) CustomBinaryReader clientStreamReader, StreamWriter clientStreamWriter, bool IsHttps)
{ {
TcpConnection connection = null; TcpConnection connection = null;
...@@ -244,8 +245,8 @@ namespace Titanium.Web.Proxy ...@@ -244,8 +245,8 @@ 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.
connection = connection == null ? connection = connection == null ?
TcpConnectionManager.GetClient(args, args.WebSession.Request.RequestUri.Host, args.WebSession.Request.RequestUri.Port, args.IsHttps, version) await TcpConnectionManager.GetClient(args, args.WebSession.Request.RequestUri.Host, args.WebSession.Request.RequestUri.Port, args.IsHttps, version)
: lastRequestHostName != args.WebSession.Request.RequestUri.Host ? TcpConnectionManager.GetClient(args, args.WebSession.Request.RequestUri.Host, args.WebSession.Request.RequestUri.Port, args.IsHttps, version) : lastRequestHostName != args.WebSession.Request.RequestUri.Host ? await TcpConnectionManager.GetClient(args, args.WebSession.Request.RequestUri.Host, args.WebSession.Request.RequestUri.Port, args.IsHttps, version)
: connection; : connection;
lastRequestHostName = args.WebSession.Request.RequestUri.Host; lastRequestHostName = args.WebSession.Request.RequestUri.Host;
...@@ -288,7 +289,7 @@ namespace Titanium.Web.Proxy ...@@ -288,7 +289,7 @@ namespace Titanium.Web.Proxy
if (args.WebSession.Request.RequestBodyRead) if (args.WebSession.Request.RequestBodyRead)
{ {
args.WebSession.Request.ContentLength = args.WebSession.Request.RequestBody.Length; args.WebSession.Request.ContentLength = args.WebSession.Request.RequestBody.Length;
var newStream = args.WebSession.ProxyClient.ServerStreamReader.BaseStream; var newStream = args.WebSession.ProxyClient.Stream;
newStream.Write(args.WebSession.Request.RequestBody, 0, args.WebSession.Request.RequestBody.Length); newStream.Write(args.WebSession.Request.RequestBody, 0, args.WebSession.Request.RequestBody.Length);
} }
else else
......
...@@ -23,7 +23,7 @@ namespace Titanium.Web.Proxy ...@@ -23,7 +23,7 @@ namespace Titanium.Web.Proxy
try try
{ {
if (!args.WebSession.Response.ResponseBodyRead) if (!args.WebSession.Response.ResponseBodyRead)
args.WebSession.Response.ResponseStream = args.WebSession.ProxyClient.ServerStreamReader.BaseStream; args.WebSession.Response.ResponseStream = args.WebSession.ProxyClient.Stream;
if (BeforeResponse != null && !args.WebSession.Response.ResponseLocked) if (BeforeResponse != null && !args.WebSession.Response.ResponseLocked)
......
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