Commit 4b86cde8 authored by justcoding121's avatar justcoding121

asyncify more

parent ff0dddf4
......@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Net;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Titanium.Web.Proxy.EventArguments;
using Titanium.Web.Proxy.Models;
......@@ -13,7 +14,7 @@ namespace Titanium.Web.Proxy.Examples.Basic
{
ProxyServer.BeforeRequest += OnRequest;
ProxyServer.BeforeResponse += OnResponse;
ProxyServer.RemoteCertificateValidationCallback += OnCertificateValidation;
ProxyServer.ServerCertificateValidationCallback += OnCertificateValidation;
//Exclude Https addresses you don't want to proxy
//Usefull for clients that use certificate pinning
......@@ -61,9 +62,8 @@ namespace Titanium.Web.Proxy.Examples.Basic
ProxyServer.Stop();
}
//Test On Request, intecept requests
//Read browser URL send back to proxy by the injection script in OnResponse event
public void OnRequest(object sender, SessionEventArgs e)
//intecept & cancel, redirect or update requests
public async Task OnRequest(object sender, SessionEventArgs e)
{
Console.WriteLine(e.WebSession.Request.Url);
......@@ -73,12 +73,12 @@ namespace Titanium.Web.Proxy.Examples.Basic
if ((e.WebSession.Request.Method.ToUpper() == "POST" || e.WebSession.Request.Method.ToUpper() == "PUT"))
{
//Get/Set request body bytes
byte[] bodyBytes = e.GetRequestBody();
e.SetRequestBody(bodyBytes);
byte[] bodyBytes = await e.GetRequestBody();
await e.SetRequestBody(bodyBytes);
//Get/Set request body as string
string bodyString = e.GetRequestBodyAsString();
e.SetRequestBodyString(bodyString);
string bodyString = await e.GetRequestBodyAsString();
await e.SetRequestBodyString(bodyString);
}
......@@ -86,26 +86,24 @@ namespace Titanium.Web.Proxy.Examples.Basic
//Filter URL
if (e.WebSession.Request.RequestUri.AbsoluteUri.Contains("google.com"))
{
e.Ok("<!DOCTYPE html>" +
"<html><body><h1>" +
"Website Blocked" +
"</h1>" +
"<p>Blocked by titanium web proxy.</p>" +
"</body>" +
"</html>");
await e.Ok("<!DOCTYPE html>" +
"<html><body><h1>" +
"Website Blocked" +
"</h1>" +
"<p>Blocked by titanium web proxy.</p>" +
"</body>" +
"</html>");
}
//Redirect example
if (e.WebSession.Request.RequestUri.AbsoluteUri.Contains("wikipedia.org"))
{
e.Redirect("https://www.paypal.com");
await e.Redirect("https://www.paypal.com");
}
}
//Test script injection
//Insert script to read the Browser URL and send it back to proxy
public void OnResponse(object sender, SessionEventArgs e)
//Modify response
public async Task OnResponse(object sender, SessionEventArgs e)
{
//read response headers
var responseHeaders = e.WebSession.Response.ResponseHeaders;
......@@ -116,11 +114,11 @@ namespace Titanium.Web.Proxy.Examples.Basic
{
if (e.WebSession.Response.ContentType.Trim().ToLower().Contains("text/html"))
{
byte[] bodyBytes = e.GetResponseBody();
e.SetResponseBody(bodyBytes);
byte[] bodyBytes = await e.GetResponseBody();
await e.SetResponseBody(bodyBytes);
string body = e.GetResponseBodyAsString();
e.SetResponseBodyString(body);
string body = await e.GetResponseBodyAsString();
await e.SetResponseBodyString(body);
}
}
}
......@@ -131,13 +129,13 @@ namespace Titanium.Web.Proxy.Examples.Basic
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public void OnCertificateValidation(object sender, CertificateValidationEventArgs e)
public async Task OnCertificateValidation(object sender, CertificateValidationEventArgs e)
{
//set IsValid to true/false based on Certificate Errors
if (e.SslPolicyErrors == System.Net.Security.SslPolicyErrors.None)
e.IsValid = true;
else
e.Session.Ok("Cannot validate server certificate! Not safe to proceed.");
await e.Session.Ok("Cannot validate server certificate! Not safe to proceed.");
}
}
}
\ No newline at end of file
......@@ -34,7 +34,7 @@ Setup HTTP proxy:
```csharp
ProxyServer.BeforeRequest += OnRequest;
ProxyServer.BeforeResponse += OnResponse;
ProxyServer.RemoteCertificateValidationCallback += OnCertificateValidation;
ProxyServer.ServerCertificateValidationCallback += OnCertificateValidation;
//Exclude Https addresses you don't want to proxy
//Usefull for clients that use certificate pinning
......@@ -61,8 +61,7 @@ Setup HTTP proxy:
GenericCertificateName = "google.com"
};
ProxyServer.AddEndPoint(transparentEndPoint);
//ProxyServer.UpStreamHttpProxy = new ExternalProxy() { HostName = "localhost", Port = 8888 };
//ProxyServer.UpStreamHttpsProxy = new ExternalProxy() { HostName = "localhost", Port = 8888 };
......@@ -87,7 +86,8 @@ Sample request and response event handlers
```csharp
public void OnRequest(object sender, SessionEventArgs e)
//intecept & cancel, redirect or update requests
public async Task OnRequest(object sender, SessionEventArgs e)
{
Console.WriteLine(e.WebSession.Request.Url);
......@@ -97,12 +97,12 @@ Sample request and response event handlers
if ((e.WebSession.Request.Method.ToUpper() == "POST" || e.WebSession.Request.Method.ToUpper() == "PUT"))
{
//Get/Set request body bytes
byte[] bodyBytes = e.GetRequestBody();
e.SetRequestBody(bodyBytes);
byte[] bodyBytes = await e.GetRequestBody();
await e.SetRequestBody(bodyBytes);
//Get/Set request body as string
string bodyString = e.GetRequestBodyAsString();
e.SetRequestBodyString(bodyString);
string bodyString = await e.GetRequestBodyAsString();
await e.SetRequestBodyString(bodyString);
}
......@@ -110,24 +110,24 @@ Sample request and response event handlers
//Filter URL
if (e.WebSession.Request.RequestUri.AbsoluteUri.Contains("google.com"))
{
e.Ok("<!DOCTYPE html>" +
"<html><body><h1>" +
"Website Blocked" +
"</h1>" +
"<p>Blocked by titanium web proxy.</p>" +
"</body>" +
"</html>");
await e.Ok("<!DOCTYPE html>" +
"<html><body><h1>" +
"Website Blocked" +
"</h1>" +
"<p>Blocked by titanium web proxy.</p>" +
"</body>" +
"</html>");
}
//Redirect example
if (e.WebSession.Request.RequestUri.AbsoluteUri.Contains("wikipedia.org"))
{
e.Redirect("https://www.paypal.com");
await e.Redirect("https://www.paypal.com");
}
}
public void OnResponse(object sender, SessionEventArgs e)
{
//Modify response
public async Task OnResponse(object sender, SessionEventArgs e)
{
//read response headers
var responseHeaders = e.WebSession.Response.ResponseHeaders;
......@@ -138,24 +138,28 @@ Sample request and response event handlers
{
if (e.WebSession.Response.ContentType.Trim().ToLower().Contains("text/html"))
{
byte[] bodyBytes = e.GetResponseBody();
e.SetResponseBody(bodyBytes);
byte[] bodyBytes = await e.GetResponseBody();
await e.SetResponseBody(bodyBytes);
string body = e.GetResponseBodyAsString();
e.SetResponseBodyString(body);
string body = await e.GetResponseBodyAsString();
await e.SetResponseBodyString(body);
}
}
}
}
// Allows overriding default certificate validation logic
public void OnCertificateValidation(object sender, CertificateValidationEventArgs e)
/// <summary>
/// Allows overriding default certificate validation logic
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public async Task OnCertificateValidation(object sender, CertificateValidationEventArgs e)
{
//set IsValid to true/false based on Certificate Errors
if (e.SslPolicyErrors == System.Net.Security.SslPolicyErrors.None)
e.IsValid = true;
else
e.Session.Ok("Cannot validate server certificate! Not safe to proceed.");
await e.Session.Ok("Cannot validate server certificate! Not safe to proceed.");
}
```
Future roadmap
......
using System.IO;
using System.IO.Compression;
using System.Threading.Tasks;
namespace Titanium.Web.Proxy.Compression
{
class DeflateCompression : ICompression
{
public byte[] Compress(byte[] responseBody)
public async Task<byte[]> Compress(byte[] responseBody)
{
using (var ms = new MemoryStream())
{
using (var zip = new DeflateStream(ms, CompressionMode.Compress, true))
{
zip.Write(responseBody, 0, responseBody.Length);
await zip.WriteAsync(responseBody, 0, responseBody.Length).ConfigureAwait(false);
}
return ms.ToArray();
......
using Ionic.Zlib;
using System.IO;
using System.Threading.Tasks;
namespace Titanium.Web.Proxy.Compression
{
class GZipCompression : ICompression
{
public byte[] Compress(byte[] responseBody)
public async Task<byte[]> Compress(byte[] responseBody)
{
using (var ms = new MemoryStream())
{
using (var zip = new GZipStream(ms, CompressionMode.Compress, true))
{
zip.Write(responseBody, 0, responseBody.Length);
await zip.WriteAsync(responseBody, 0, responseBody.Length).ConfigureAwait(false);
}
return ms.ToArray();
......
namespace Titanium.Web.Proxy.Compression
using System.Threading.Tasks;
namespace Titanium.Web.Proxy.Compression
{
interface ICompression
{
byte[] Compress(byte[] responseBody);
Task<byte[]> Compress(byte[] responseBody);
}
}
using Ionic.Zlib;
using System.IO;
using System.Threading.Tasks;
namespace Titanium.Web.Proxy.Compression
{
class ZlibCompression : ICompression
{
public byte[] Compress(byte[] responseBody)
public async Task<byte[]> Compress(byte[] responseBody)
{
using (var ms = new MemoryStream())
{
using (var zip = new ZlibStream(ms, CompressionMode.Compress, true))
{
zip.Write(responseBody, 0, responseBody.Length);
await zip.WriteAsync(responseBody, 0, responseBody.Length).ConfigureAwait(false);
}
return ms.ToArray();
......
namespace Titanium.Web.Proxy.Decompression
using System.Threading.Tasks;
namespace Titanium.Web.Proxy.Decompression
{
class DefaultDecompression : IDecompression
{
public byte[] Decompress(byte[] compressedArray)
public Task<byte[]> Decompress(byte[] compressedArray)
{
return compressedArray;
return Task.FromResult(compressedArray);
}
}
}
using Ionic.Zlib;
using System.IO;
using System.Threading.Tasks;
using Titanium.Web.Proxy.Shared;
namespace Titanium.Web.Proxy.Decompression
{
class DeflateDecompression : IDecompression
{
public byte[] Decompress(byte[] compressedArray)
public async Task<byte[]> Decompress(byte[] compressedArray)
{
var stream = new MemoryStream(compressedArray);
......@@ -17,9 +18,9 @@ namespace Titanium.Web.Proxy.Decompression
using (var output = new MemoryStream())
{
int read;
while ((read = decompressor.Read(buffer, 0, buffer.Length)) > 0)
while ((read = await decompressor.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false)) > 0)
{
output.Write(buffer, 0, read);
await output.WriteAsync(buffer, 0, read).ConfigureAwait(false);
}
return output.ToArray();
......
using System.IO;
using System.IO.Compression;
using System.Threading.Tasks;
using Titanium.Web.Proxy.Shared;
namespace Titanium.Web.Proxy.Decompression
{
class GZipDecompression : IDecompression
{
public byte[] Decompress(byte[] compressedArray)
public async Task<byte[]> Decompress(byte[] compressedArray)
{
using (var decompressor = new GZipStream(new MemoryStream(compressedArray), CompressionMode.Decompress))
{
......@@ -14,9 +15,9 @@ namespace Titanium.Web.Proxy.Decompression
using (var output = new MemoryStream())
{
int read;
while ((read = decompressor.Read(buffer, 0, buffer.Length)) > 0)
while ((read = await decompressor.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false)) > 0)
{
output.Write(buffer, 0, read);
await output.WriteAsync(buffer, 0, read).ConfigureAwait(false);
}
return output.ToArray();
}
......
using System.IO;
using System.Threading.Tasks;
namespace Titanium.Web.Proxy.Decompression
{
interface IDecompression
{
byte[] Decompress(byte[] compressedArray);
Task<byte[]> Decompress(byte[] compressedArray);
}
}
using Ionic.Zlib;
using System.IO;
using System.Threading.Tasks;
using Titanium.Web.Proxy.Shared;
namespace Titanium.Web.Proxy.Decompression
{
class ZlibDecompression : IDecompression
{
public byte[] Decompress(byte[] compressedArray)
public async Task<byte[]> Decompress(byte[] compressedArray)
{
var memoryStream = new MemoryStream(compressedArray);
using (var decompressor = new ZlibStream(memoryStream, CompressionMode.Decompress))
......@@ -16,9 +17,9 @@ namespace Titanium.Web.Proxy.Decompression
using (var output = new MemoryStream())
{
int read;
while ((read = decompressor.Read(buffer, 0, buffer.Length)) > 0)
while ((read = await decompressor.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false)) > 0)
{
output.Write(buffer, 0, read);
await output.WriteAsync(buffer, 0, read).ConfigureAwait(false);
}
return output.ToArray();
}
......
......@@ -15,12 +15,12 @@ namespace Titanium.Web.Proxy.Extensions
if (!string.IsNullOrEmpty(initialData))
{
var bytes = Encoding.ASCII.GetBytes(initialData);
output.Write(bytes, 0, bytes.Length);
await output.WriteAsync(bytes, 0, bytes.Length);
}
await input.CopyToAsync(output);
}
internal static void CopyBytesToStream(this CustomBinaryReader clientStreamReader, Stream stream, long totalBytesToRead)
internal static async Task CopyBytesToStream(this CustomBinaryReader clientStreamReader, Stream stream, long totalBytesToRead)
{
var totalbytesRead = 0;
......@@ -35,7 +35,7 @@ namespace Titanium.Web.Proxy.Extensions
while (totalbytesRead < (int)totalBytesToRead)
{
var buffer = clientStreamReader.ReadBytes(bytesToRead);
var buffer = await clientStreamReader.ReadBytesAsync(bytesToRead);
totalbytesRead += buffer.Length;
var remainingBytes = (int)totalBytesToRead - totalbytesRead;
......@@ -43,26 +43,26 @@ namespace Titanium.Web.Proxy.Extensions
{
bytesToRead = remainingBytes;
}
stream.Write(buffer, 0, buffer.Length);
await stream.WriteAsync(buffer, 0, buffer.Length);
}
}
internal static void CopyBytesToStreamChunked(this CustomBinaryReader clientStreamReader, Stream stream)
internal static async Task CopyBytesToStreamChunked(this CustomBinaryReader clientStreamReader, Stream stream)
{
while (true)
{
var chuchkHead = clientStreamReader.ReadLine();
var chuchkHead = await clientStreamReader.ReadLineAsync();
var chunkSize = int.Parse(chuchkHead, NumberStyles.HexNumber);
if (chunkSize != 0)
{
var buffer = clientStreamReader.ReadBytes(chunkSize);
stream.Write(buffer, 0, buffer.Length);
var buffer = await clientStreamReader.ReadBytesAsync(chunkSize);
await stream.WriteAsync(buffer, 0, buffer.Length);
//chunk trail
clientStreamReader.ReadLine();
await clientStreamReader.ReadLineAsync();
}
else
{
clientStreamReader.ReadLine();
await clientStreamReader.ReadLineAsync();
break;
}
}
......
......@@ -4,6 +4,7 @@ using System.IO;
using System.Net.Security;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using Titanium.Web.Proxy.Network;
using Titanium.Web.Proxy.Shared;
......@@ -31,7 +32,7 @@ namespace Titanium.Web.Proxy.Helpers
/// Read a line from the byte stream
/// </summary>
/// <returns></returns>
internal string ReadLine()
internal async Task<string> ReadLineAsync()
{
var readBuffer = new StringBuilder();
......@@ -40,7 +41,7 @@ namespace Titanium.Web.Proxy.Helpers
var lastChar = default(char);
var buffer = new byte[1];
while (this.stream.Read(buffer, 0, 1) > 0)
while (await this.stream.ReadAsync(buffer, 0, 1).ConfigureAwait(false) > 0)
{
if (lastChar == '\r' && buffer[0] == '\n')
{
......@@ -66,18 +67,18 @@ namespace Titanium.Web.Proxy.Helpers
/// Read until the last new line
/// </summary>
/// <returns></returns>
internal List<string> ReadAllLines()
internal async Task<List<string>> ReadAllLinesAsync()
{
string tmpLine;
var requestLines = new List<string>();
while (!string.IsNullOrEmpty(tmpLine = ReadLine()))
while (!string.IsNullOrEmpty(tmpLine = await ReadLineAsync().ConfigureAwait(false)))
{
requestLines.Add(tmpLine);
}
return requestLines;
}
internal byte[] ReadBytes(long totalBytesToRead)
internal async Task<byte[]> ReadBytesAsync(long totalBytesToRead)
{
int bytesToRead = Constants.BUFFER_SIZE;
......@@ -91,9 +92,9 @@ namespace Titanium.Web.Proxy.Helpers
using (var outStream = new MemoryStream())
{
while ((bytesRead += this.stream.Read(buffer, 0, bytesToRead)) > 0)
while ((bytesRead += await this.stream.ReadAsync(buffer, 0, bytesToRead).ConfigureAwait(false)) > 0)
{
outStream.Write(buffer, 0, bytesRead);
await outStream.WriteAsync(buffer, 0, bytesRead).ConfigureAwait(false);
totalBytesRead += bytesRead;
if (totalBytesRead == totalBytesToRead)
......
......@@ -14,7 +14,7 @@ namespace Titanium.Web.Proxy.Helpers
{
public class TcpHelper
{
public static void SendRaw(Stream clientStream, string httpCmd, List<HttpHeader> requestHeaders, string hostName,
public async static Task SendRaw(Stream clientStream, string httpCmd, List<HttpHeader> requestHeaders, string hostName,
int tunnelPort, bool isHttps)
{
StringBuilder sb = null;
......@@ -50,7 +50,7 @@ namespace Titanium.Web.Proxy.Helpers
try
{
sslStream = new SslStream(tunnelStream);
sslStream.AuthenticateAsClient(hostName, null, Constants.SupportedProtocols, false);
await sslStream.AuthenticateAsClientAsync(hostName, null, Constants.SupportedProtocols, false);
tunnelStream = sslStream;
}
catch
......@@ -62,17 +62,17 @@ namespace Titanium.Web.Proxy.Helpers
}
}
var sendRelay = Task.Factory.StartNew(() =>
{
if (sb != null)
clientStream.CopyToAsync(sb.ToString(), tunnelStream).Wait();
else
clientStream.CopyToAsync(string.Empty, tunnelStream).Wait();
});
Task sendRelay;
if (sb != null)
sendRelay = clientStream.CopyToAsync(sb.ToString(), tunnelStream);
else
sendRelay = clientStream.CopyToAsync(string.Empty, tunnelStream);
var receiveRelay = Task.Factory.StartNew(() =>tunnelStream.CopyToAsync(string.Empty, clientStream).Wait());
var receiveRelay = tunnelStream.CopyToAsync(string.Empty, clientStream);
Task.WaitAll(sendRelay, receiveRelay);
await Task.WhenAll(sendRelay, receiveRelay).ConfigureAwait(false);
}
catch
{
......
......@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Titanium.Web.Proxy.Models;
using Titanium.Web.Proxy.Network;
using Titanium.Web.Proxy.Shared;
......@@ -35,7 +36,7 @@ namespace Titanium.Web.Proxy.Http
this.Response = new Response();
}
internal void SendRequest()
internal async Task SendRequest()
{
Stream stream = ProxyClient.Stream;
......@@ -57,13 +58,13 @@ namespace Titanium.Web.Proxy.Http
string request = requestLines.ToString();
byte[] requestBytes = Encoding.ASCII.GetBytes(request);
stream.Write(requestBytes, 0, requestBytes.Length);
await stream.WriteAsync(requestBytes, 0, requestBytes.Length);
stream.Flush();
if (ProxyServer.Enable100ContinueBehaviour)
if (this.Request.ExpectContinue)
{
var httpResult = ProxyClient.ServerStreamReader.ReadLine().Split(Constants.SpaceSplit, 3);
var httpResult = (await ProxyClient.ServerStreamReader.ReadLineAsync()).Split(Constants.SpaceSplit, 3);
var responseStatusCode = httpResult[1].Trim();
var responseStatusDescription = httpResult[2].Trim();
......@@ -72,27 +73,27 @@ namespace Titanium.Web.Proxy.Http
&& responseStatusDescription.ToLower().Equals("continue"))
{
this.Request.Is100Continue = true;
ProxyClient.ServerStreamReader.ReadLine();
await ProxyClient.ServerStreamReader.ReadLineAsync();
}
else if (responseStatusCode.Equals("417")
&& responseStatusDescription.ToLower().Equals("expectation failed"))
{
this.Request.ExpectationFailed = true;
ProxyClient.ServerStreamReader.ReadLine();
await ProxyClient.ServerStreamReader.ReadLineAsync();
}
}
}
internal void ReceiveResponse()
internal async Task ReceiveResponse()
{
//return if this is already read
if (this.Response.ResponseStatusCode != null) return;
var httpResult = ProxyClient.ServerStreamReader.ReadLine().Split(Constants.SpaceSplit, 3);
var httpResult = (await ProxyClient.ServerStreamReader.ReadLineAsync()).Split(Constants.SpaceSplit, 3);
if (string.IsNullOrEmpty(httpResult[0]))
{
var s = ProxyClient.ServerStreamReader.ReadLine();
await ProxyClient.ServerStreamReader.ReadLineAsync();
}
this.Response.HttpVersion = httpResult[0].Trim();
......@@ -105,8 +106,8 @@ namespace Titanium.Web.Proxy.Http
{
this.Response.Is100Continue = true;
this.Response.ResponseStatusCode = null;
ProxyClient.ServerStreamReader.ReadLine();
ReceiveResponse();
await ProxyClient.ServerStreamReader.ReadLineAsync();
await ReceiveResponse();
return;
}
else if (this.Response.ResponseStatusCode.Equals("417")
......@@ -114,12 +115,12 @@ namespace Titanium.Web.Proxy.Http
{
this.Response.ExpectationFailed = true;
this.Response.ResponseStatusCode = null;
ProxyClient.ServerStreamReader.ReadLine();
ReceiveResponse();
await ProxyClient.ServerStreamReader.ReadLineAsync();
await ReceiveResponse();
return;
}
List<string> responseLines = ProxyClient.ServerStreamReader.ReadAllLines();
List<string> responseLines = await ProxyClient.ServerStreamReader.ReadAllLinesAsync();
for (int index = 0; index < responseLines.Count; ++index)
{
......
......@@ -61,13 +61,15 @@ namespace Titanium.Web.Proxy.Network
}
if (cached == null)
cached = await CreateClient(sessionArgs,hostname, port, isSecure, version);
cached = await CreateClient(sessionArgs, hostname, port, isSecure, version).ConfigureAwait(false);
//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));
//}
//just create one more preemptively
if (ConnectionCache.Where(x => x.HostName == hostname && x.port == port &&
x.IsSecure == isSecure && x.TcpClient.Connected && x.Version.Equals(version)).Count() < 2)
{
var task = CreateClient(sessionArgs, hostname, port, isSecure, version)
.ContinueWith(x => ReleaseClient(x.Result));
}
return cached;
}
......@@ -81,26 +83,26 @@ namespace Titanium.Web.Proxy.Network
{
CustomSslStream sslStream = null;
if(ProxyServer.UpStreamHttpsProxy!=null)
if (ProxyServer.UpStreamHttpsProxy != null)
{
client = new TcpClient(ProxyServer.UpStreamHttpsProxy.HostName, ProxyServer.UpStreamHttpsProxy.Port);
stream = (Stream)client.GetStream();
var writer = new StreamWriter(stream,Encoding.ASCII, Constants.BUFFER_SIZE, true);
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));
writer.WriteLine("Connection: Keep-Alive");
writer.WriteLine();
writer.Flush();
var reader = new CustomBinaryReader(stream);
var result = reader.ReadLine();
var result = await reader.ReadLineAsync().ConfigureAwait(false);
if (!result.ToLower().Contains("200 connection established"))
throw new Exception("Upstream proxy failed to create a secure tunnel");
reader.ReadAllLines();
await reader.ReadAllLinesAsync().ConfigureAwait(false);
}
else
{
......@@ -110,9 +112,9 @@ namespace Titanium.Web.Proxy.Network
try
{
sslStream = new CustomSslStream(stream, true, ProxyServer.ValidateServerCertificate);
sslStream = new CustomSslStream(stream, true, new RemoteCertificateValidationCallback(ProxyServer.ValidateServerCertificate));
sslStream.Session = sessionArgs;
await sslStream.AuthenticateAsClientAsync(hostname, null, Constants.SupportedProtocols, false);
await sslStream.AuthenticateAsClientAsync(hostname, null, Constants.SupportedProtocols, false).ConfigureAwait(false);
stream = (Stream)sslStream;
}
catch
......@@ -155,7 +157,7 @@ namespace Titanium.Web.Proxy.Network
ConnectionCache.Add(Connection);
}
internal static void ClearIdleConnections()
internal async static void ClearIdleConnections()
{
while (true)
{
......@@ -171,7 +173,7 @@ namespace Titanium.Web.Proxy.Network
ConnectionCache.RemoveAll(x => x.LastAccess < cutOff);
}
Thread.Sleep(1000 * 60 * 3);
await Task.Delay(1000 * 60 * 3).ConfigureAwait(false);
}
}
......
......@@ -34,8 +34,8 @@ namespace Titanium.Web.Proxy
public static string RootCertificateName { get; set; }
public static bool Enable100ContinueBehaviour { get; set; }
public static event EventHandler<SessionEventArgs> BeforeRequest;
public static event EventHandler<SessionEventArgs> BeforeResponse;
public static event Func<object, SessionEventArgs, Task> BeforeRequest;
public static event Func<object, SessionEventArgs, Task> BeforeResponse;
/// <summary>
/// External proxy for Http
......@@ -50,14 +50,14 @@ namespace Titanium.Web.Proxy
/// <summary>
/// Verifies the remote Secure Sockets Layer (SSL) certificate used for authentication
/// </summary>
public static event EventHandler<CertificateValidationEventArgs> RemoteCertificateValidationCallback;
public static event Func<object, CertificateValidationEventArgs, Task> ServerCertificateValidationCallback;
public static List<ProxyEndPoint> ProxyEndPoints { get; set; }
public static void Initialize()
{
Task.Factory.StartNew(() => TcpConnectionManager.ClearIdleConnections());
TcpConnectionManager.ClearIdleConnections();
}
public static void AddEndPoint(ProxyEndPoint endPoint)
......@@ -235,51 +235,6 @@ namespace Titanium.Web.Proxy
}
}
/// <summary>
/// Call back to override server certificate validation
/// </summary>
/// <param name="sender"></param>
/// <param name="certificate"></param>
/// <param name="chain"></param>
/// <param name="sslPolicyErrors"></param>
/// <returns></returns>
internal static bool ValidateServerCertificate(
object sender,
X509Certificate certificate,
X509Chain chain,
SslPolicyErrors sslPolicyErrors)
{
var param = sender as CustomSslStream;
if (RemoteCertificateValidationCallback != null)
{
var args = new CertificateValidationEventArgs();
args.Session = param.Session;
args.Certificate = certificate;
args.Chain = chain;
args.SslPolicyErrors = sslPolicyErrors;
RemoteCertificateValidationCallback.Invoke(null, args);
if(!args.IsValid)
{
param.Session.WebSession.Request.CancelRequest = true;
}
return args.IsValid;
}
if (sslPolicyErrors == SslPolicyErrors.None)
return true;
Console.WriteLine("Certificate error: {0}", sslPolicyErrors);
//By default
//do not allow this client to communicate with unauthenticated servers.
return false;
}
}
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
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