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.Net.Security;
using System.Net.Sockets;
using System.Text;
using Titanium.Web.Proxy.Network;
using Titanium.Web.Proxy.Shared;
namespace Titanium.Web.Proxy.Helpers
{
......@@ -9,13 +14,19 @@ namespace Titanium.Web.Proxy.Helpers
/// using the specified encoding
/// as well as to read bytes as required
/// </summary>
public class CustomBinaryReader : BinaryReader
public class CustomBinaryReader : IDisposable
{
internal CustomBinaryReader(Stream stream, Encoding encoding)
: base(stream, encoding)
private Stream stream;
internal CustomBinaryReader(Stream stream)
{
this.stream = stream;
}
public Stream BaseStream => stream;
/// <summary>
/// Read a line from the byte stream
/// </summary>
......@@ -27,9 +38,9 @@ namespace Titanium.Web.Proxy.Helpers
try
{
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')
{
......@@ -39,8 +50,8 @@ namespace Titanium.Web.Proxy.Helpers
{
return readBuffer.ToString();
}
readBuffer.Append(buffer);
lastChar = buffer[0];
readBuffer.Append((char)buffer[0]);
lastChar = (char)buffer[0];
}
return readBuffer.ToString();
......@@ -65,5 +76,42 @@ namespace Titanium.Web.Proxy.Helpers
}
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
{
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;
while (true)
......@@ -61,18 +61,18 @@ namespace Titanium.Web.Proxy.Network
}
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 &&
x.IsSecure == isSecure && x.TcpClient.Connected && x.Version.Equals(version)).Count() < 2)
{
Task.Factory.StartNew(() => CreateClient(sessionArgs, hostname, port, isSecure, version));
}
//if (ConnectionCache.Where(x => x.HostName == hostname && x.port == port &&
//x.IsSecure == isSecure && x.TcpClient.Connected && x.Version.Equals(version)).Count() < 2)
//{
// Task.Factory.StartNew(() => CreateClient(sessionArgs, hostname, port, isSecure, version));
//}
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;
Stream stream;
......@@ -86,7 +86,7 @@ namespace Titanium.Web.Proxy.Network
client = new TcpClient(ProxyServer.UpStreamHttpsProxy.HostName, ProxyServer.UpStreamHttpsProxy.Port);
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("Host: {0}:{1}", sessionArgs.WebSession.Request.RequestUri.Host, sessionArgs.WebSession.Request.RequestUri.Port));
......@@ -94,7 +94,7 @@ namespace Titanium.Web.Proxy.Network
writer.WriteLine();
writer.Flush();
var reader = new CustomBinaryReader(stream, Encoding.ASCII);
var reader = new CustomBinaryReader(stream);
var result = reader.ReadLine();
if (!result.ToLower().Contains("200 connection established"))
......@@ -112,7 +112,7 @@ namespace Titanium.Web.Proxy.Network
{
sslStream = new CustomSslStream(stream, true, ProxyServer.ValidateServerCertificate);
sslStream.Session = sessionArgs;
sslStream.AuthenticateAsClient(hostname, null, Constants.SupportedProtocols, false);
await sslStream.AuthenticateAsClientAsync(hostname, null, Constants.SupportedProtocols, false);
stream = (Stream)sslStream;
}
catch
......@@ -142,7 +142,7 @@ namespace Titanium.Web.Proxy.Network
port = port,
IsSecure = isSecure,
TcpClient = client,
ServerStreamReader = new CustomBinaryReader(stream, Encoding.ASCII),
ServerStreamReader = new CustomBinaryReader(stream),
Stream = stream,
Version = version
};
......
......@@ -16,16 +16,17 @@ using System.Security.Cryptography.X509Certificates;
using Titanium.Web.Proxy.Shared;
using Titanium.Web.Proxy.Http;
using Titanium.Web.Proxy.Extensions;
using System.Threading.Tasks;
namespace Titanium.Web.Proxy
{
partial class ProxyServer
{
//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();
var clientStreamReader = new CustomBinaryReader(clientStream, Encoding.ASCII);
var clientStreamReader = new CustomBinaryReader(clientStream);
var clientStreamWriter = new StreamWriter(clientStream);
Uri httpRemoteUri;
......@@ -75,10 +76,10 @@ namespace Titanium.Web.Proxy
sslStream = new SslStream(clientStream, true);
//Successfully managed to authenticate the client using the fake certificate
sslStream.AuthenticateAsServer(certificate, false,
await sslStream.AuthenticateAsServerAsync(certificate, false,
Constants.SupportedProtocols, false);
clientStreamReader = new CustomBinaryReader(sslStream, Encoding.ASCII);
clientStreamReader = new CustomBinaryReader(sslStream);
clientStreamWriter = new StreamWriter(sslStream);
//HTTPS server created - we can now decrypt the client's traffic
clientStream = sslStream;
......@@ -111,7 +112,7 @@ namespace Titanium.Web.Proxy
//Now create the request
HandleHttpSessionRequest(client, httpCmd, clientStream, clientStreamReader, clientStreamWriter,
await HandleHttpSessionRequest(client, httpCmd, clientStream, clientStreamReader, clientStreamWriter,
httpRemoteUri.Scheme == Uri.UriSchemeHttps ? true : false);
}
catch
......@@ -122,7 +123,7 @@ namespace Titanium.Web.Proxy
//This is called when requests are routed through router to this endpoint
//For ssl requests
private static void HandleClient(TransparentProxyEndPoint endPoint, TcpClient tcpClient)
private static async Task HandleClient(TransparentProxyEndPoint endPoint, TcpClient tcpClient)
{
Stream clientStream = tcpClient.GetStream();
CustomBinaryReader clientStreamReader = null;
......@@ -146,7 +147,7 @@ namespace Titanium.Web.Proxy
sslStream.AuthenticateAsServer(certificate, false,
SslProtocols.Tls, false);
clientStreamReader = new CustomBinaryReader(sslStream, Encoding.ASCII);
clientStreamReader = new CustomBinaryReader(sslStream);
clientStreamWriter = new StreamWriter(sslStream);
//HTTPS server created - we can now decrypt the client's traffic
......@@ -163,17 +164,17 @@ namespace Titanium.Web.Proxy
}
else
{
clientStreamReader = new CustomBinaryReader(clientStream, Encoding.ASCII);
clientStreamReader = new CustomBinaryReader(clientStream);
}
var httpCmd = clientStreamReader.ReadLine();
//Now create the request
HandleHttpSessionRequest(tcpClient, httpCmd, clientStream, clientStreamReader, clientStreamWriter,
await HandleHttpSessionRequest(tcpClient, httpCmd, clientStream, clientStreamReader, clientStreamWriter,
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)
{
TcpConnection connection = null;
......@@ -244,8 +245,8 @@ namespace Titanium.Web.Proxy
//construct the web request that we are going to issue on behalf of the client.
connection = connection == null ?
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)
await 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;
lastRequestHostName = args.WebSession.Request.RequestUri.Host;
......@@ -288,7 +289,7 @@ namespace Titanium.Web.Proxy
if (args.WebSession.Request.RequestBodyRead)
{
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);
}
else
......
......@@ -23,7 +23,7 @@ namespace Titanium.Web.Proxy
try
{
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)
......
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