Commit e928c25a authored by Jehonathan Thomas's avatar Jehonathan Thomas Committed by GitHub

Merge pull request #215 from justcoding121/develop

Beta merge
parents b62f9f14 e7b254f1
......@@ -5,7 +5,7 @@ namespace Titanium.Web.Proxy.Examples.Basic
{
public class Program
{
private static readonly ProxyTestController Controller = new ProxyTestController();
private static readonly ProxyTestController controller = new ProxyTestController();
public static void Main(string[] args)
{
......@@ -15,13 +15,13 @@ namespace Titanium.Web.Proxy.Examples.Basic
//Start proxy controller
Controller.StartProxy();
controller.StartProxy();
Console.WriteLine("Hit any key to exit..");
Console.WriteLine();
Console.Read();
Controller.Stop();
controller.Stop();
}
......@@ -30,7 +30,7 @@ namespace Titanium.Web.Proxy.Examples.Basic
if (eventType != 2) return false;
try
{
Controller.Stop();
controller.Stop();
}
catch
{
......
using System;
using System.Collections.Generic;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
using Titanium.Web.Proxy.EventArguments;
using Titanium.Web.Proxy.Models;
......@@ -9,10 +10,10 @@ namespace Titanium.Web.Proxy.Examples.Basic
{
public class ProxyTestController
{
private ProxyServer proxyServer;
private readonly ProxyServer proxyServer;
//share requestBody outside handlers
private Dictionary<Guid, string> requestBodyHistory;
private readonly Dictionary<Guid, string> requestBodyHistory = new Dictionary<Guid, string>();
public ProxyTestController()
{
......@@ -21,9 +22,10 @@ namespace Titanium.Web.Proxy.Examples.Basic
//optionally set the Certificate Engine
//Under Mono only BouncyCastle will be supported
//proxyServer.CertificateEngine = Network.CertificateEngine.BouncyCastle;
//proxyServer.CertificateEngine = Network.CertificateEngine.BouncyCastle;
requestBodyHistory = new Dictionary<Guid, string>();
//optionally set the Root Certificate
//proxyServer.RootCertificate = new X509Certificate2("myCert.pfx", string.Empty, X509KeyStorageFlags.Exportable);
}
public void StartProxy()
......
......@@ -112,7 +112,7 @@ Sample request and response event handlers
```csharp
//To access requestBody from OnResponse handler
private Dictionary<Guid, string> requestBodyHistory;
private Dictionary<Guid, string> requestBodyHistory = new Dictionary<Guid, string>();
public async Task OnRequest(object sender, SessionEventArgs e)
{
......
......@@ -9,7 +9,7 @@ namespace Titanium.Web.Proxy.UnitTests
[TestClass]
public class CertificateManagerTests
{
private readonly static string[] hostNames
private static readonly string[] hostNames
= new string[] { "facebook.com", "youtube.com", "google.com",
"bing.com", "yahoo.com"};
......
......@@ -16,7 +16,7 @@ namespace Titanium.Web.Proxy
/// <param name="chain"></param>
/// <param name="sslPolicyErrors"></param>
/// <returns></returns>
internal bool ValidateServerCertificate(
private bool ValidateServerCertificate(
object sender,
X509Certificate certificate,
X509Chain chain,
......@@ -66,7 +66,7 @@ namespace Titanium.Web.Proxy
/// <param name="remoteCertificate"></param>
/// <param name="acceptableIssuers"></param>
/// <returns></returns>
internal X509Certificate SelectClientCertificate(
private X509Certificate SelectClientCertificate(
object sender,
string targetHost,
X509CertificateCollection localCertificates,
......
......@@ -5,7 +5,7 @@ namespace Titanium.Web.Proxy.Extensions
/// <summary>
/// Extension methods for Byte Arrays.
/// </summary>
public static class ByteArrayExtensions
internal static class ByteArrayExtensions
{
/// <summary>
/// Get the sub array from byte of data
......@@ -15,7 +15,7 @@ namespace Titanium.Web.Proxy.Extensions
/// <param name="index"></param>
/// <param name="length"></param>
/// <returns></returns>
public static T[] SubArray<T>(this T[] data, int index, int length)
internal static T[] SubArray<T>(this T[] data, int index, int length)
{
var result = new T[length];
Array.Copy(data, index, result, 0, length);
......
......@@ -6,12 +6,12 @@ namespace Titanium.Web.Proxy.Helpers
/// <summary>
/// A helper class to set proxy settings for firefox
/// </summary>
public class FireFoxProxySettingsManager
internal class FireFoxProxySettingsManager
{
/// <summary>
/// Add Firefox settings.
/// </summary>
public void AddFirefox()
internal void AddFirefox()
{
try
{
......@@ -40,7 +40,7 @@ namespace Titanium.Web.Proxy.Helpers
/// <summary>
/// Remove firefox settings.
/// </summary>
public void RemoveFirefox()
internal void RemoveFirefox()
{
try
{
......
using System.Linq;
using System.Net;
namespace Titanium.Web.Proxy.Helpers
{
internal class NetworkHelper
{
private static int FindProcessIdFromLocalPort(int port, IpVersion ipVersion)
{
var tcpRow = TcpHelper.GetExtendedTcpTable(ipVersion).FirstOrDefault(
row => row.LocalEndPoint.Port == port);
return tcpRow?.ProcessId ?? 0;
}
internal static int GetProcessIdFromPort(int port, bool ipV6Enabled)
{
var processId = FindProcessIdFromLocalPort(port, IpVersion.Ipv4);
if (processId > 0 && !ipV6Enabled)
{
return processId;
}
return FindProcessIdFromLocalPort(port, IpVersion.Ipv6);
}
/// <summary>
/// Adapated from below link
/// http://stackoverflow.com/questions/11834091/how-to-check-if-localhost
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
internal static bool IsLocalIpAddress(IPAddress address)
{
// get local IP addresses
var localIPs = Dns.GetHostAddresses(Dns.GetHostName());
// test if any host IP equals to any local IP or to localhost
return IPAddress.IsLoopback(address) || localIPs.Contains(address);
}
}
}
using System.Linq;
using System.Net;
using System.Net.Sockets;
namespace Titanium.Web.Proxy.Helpers
{
internal class NetworkHelper
{
private static int FindProcessIdFromLocalPort(int port, IpVersion ipVersion)
{
var tcpRow = TcpHelper.GetExtendedTcpTable(ipVersion).FirstOrDefault(
row => row.LocalEndPoint.Port == port);
return tcpRow?.ProcessId ?? 0;
}
internal static int GetProcessIdFromPort(int port, bool ipV6Enabled)
{
var processId = FindProcessIdFromLocalPort(port, IpVersion.Ipv4);
if (processId > 0 && !ipV6Enabled)
{
return processId;
}
return FindProcessIdFromLocalPort(port, IpVersion.Ipv6);
}
/// <summary>
/// Adapated from below link
/// http://stackoverflow.com/questions/11834091/how-to-check-if-localhost
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
internal static bool IsLocalIpAddress(IPAddress address)
{
// get local IP addresses
var localIPs = Dns.GetHostAddresses(Dns.GetHostName());
// test if any host IP equals to any local IP or to localhost
return IPAddress.IsLoopback(address) || localIPs.Contains(address);
}
internal static bool IsLocalIpAddress(string hostName)
{
bool isLocalhost = false;
IPHostEntry localhost = Dns.GetHostEntry("127.0.0.1");
if (hostName == localhost.HostName)
{
IPHostEntry hostEntry = Dns.GetHostEntry(hostName);
isLocalhost = hostEntry.AddressList.Any(IPAddress.IsLoopback);
}
if (!isLocalhost)
{
localhost = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddress = null;
if (IPAddress.TryParse(hostName, out ipAddress))
isLocalhost = localhost.AddressList.Any(x => x.Equals(ipAddress));
if (!isLocalhost)
{
try
{
var hostEntry = Dns.GetHostEntry(hostName);
isLocalhost = localhost.AddressList.Any(x => hostEntry.AddressList.Any(x.Equals));
}
catch (SocketException)
{
}
}
}
return isLocalhost;
}
}
}
......@@ -53,8 +53,8 @@ namespace Titanium.Web.Proxy.Models
/// </summary>
public class ExplicitProxyEndPoint : ProxyEndPoint
{
private List<string> _excludedHttpsHostNameRegex;
private List<string> _includedHttpsHostNameRegex;
private List<string> excludedHttpsHostNameRegex;
private List<string> includedHttpsHostNameRegex;
internal bool IsSystemHttpProxy { get; set; }
......@@ -65,7 +65,7 @@ namespace Titanium.Web.Proxy.Models
/// </summary>
public List<string> ExcludedHttpsHostNameRegex
{
get { return _excludedHttpsHostNameRegex; }
get { return excludedHttpsHostNameRegex; }
set
{
if (IncludedHttpsHostNameRegex != null)
......@@ -73,7 +73,7 @@ namespace Titanium.Web.Proxy.Models
throw new ArgumentException("Cannot set excluded when included is set");
}
_excludedHttpsHostNameRegex = value;
excludedHttpsHostNameRegex = value;
}
}
......@@ -82,7 +82,7 @@ namespace Titanium.Web.Proxy.Models
/// </summary>
public List<string> IncludedHttpsHostNameRegex
{
get { return _includedHttpsHostNameRegex; }
get { return includedHttpsHostNameRegex; }
set
{
if (ExcludedHttpsHostNameRegex != null)
......@@ -90,7 +90,7 @@ namespace Titanium.Web.Proxy.Models
throw new ArgumentException("Cannot set included when excluded is set");
}
_includedHttpsHostNameRegex = value;
includedHttpsHostNameRegex = value;
}
}
......
......@@ -8,7 +8,7 @@ namespace Titanium.Web.Proxy.Models
/// </summary>
public class ExternalProxy
{
private static readonly Lazy<NetworkCredential> DefaultCredentials = new Lazy<NetworkCredential>(() => CredentialCache.DefaultNetworkCredentials);
private static readonly Lazy<NetworkCredential> defaultCredentials = new Lazy<NetworkCredential>(() => CredentialCache.DefaultNetworkCredentials);
private string userName;
private string password;
......@@ -18,16 +18,21 @@ namespace Titanium.Web.Proxy.Models
/// </summary>
public bool UseDefaultCredentials { get; set; }
/// <summary>
/// Bypass this proxy for connections to localhost?
/// </summary>
public bool BypassForLocalhost { get; set; }
/// <summary>
/// Username.
/// </summary>
public string UserName {
get { return UseDefaultCredentials ? DefaultCredentials.Value.UserName : userName; }
get { return UseDefaultCredentials ? defaultCredentials.Value.UserName : userName; }
set
{
userName = value;
if (DefaultCredentials.Value.UserName != userName)
if (defaultCredentials.Value.UserName != userName)
{
UseDefaultCredentials = false;
}
......@@ -39,12 +44,12 @@ namespace Titanium.Web.Proxy.Models
/// </summary>
public string Password
{
get { return UseDefaultCredentials ? DefaultCredentials.Value.Password : password; }
get { return UseDefaultCredentials ? defaultCredentials.Value.Password : password; }
set
{
password = value;
if (DefaultCredentials.Value.Password != password)
if (defaultCredentials.Value.Password != password)
{
UseDefaultCredentials = false;
}
......
......@@ -21,10 +21,10 @@ namespace Titanium.Web.Proxy.Network.Certificate
/// <summary>
/// Implements certificate generation operations.
/// </summary>
public class BCCertificateMaker : ICertificateMaker
internal class BCCertificateMaker : ICertificateMaker
{
private const int CertificateValidDays = 1825;
private const int CertificateGraceDays = 366;
private const int certificateValidDays = 1825;
private const int certificateGraceDays = 366;
/// <summary>
/// Makes the certificate.
......@@ -187,7 +187,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
return certificate;
}
return MakeCertificateInternal(isRoot, subject, $"CN={subject}", DateTime.UtcNow.AddDays(-CertificateGraceDays), DateTime.UtcNow.AddDays(CertificateValidDays), isRoot ? null : signingCert);
return MakeCertificateInternal(isRoot, subject, $"CN={subject}", DateTime.UtcNow.AddDays(-certificateGraceDays), DateTime.UtcNow.AddDays(certificateValidDays), isRoot ? null : signingCert);
}
}
......
......@@ -10,7 +10,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
/// Certificate Maker - uses MakeCert
/// Calls COM objects using reflection
/// </summary>
public class WinCertificateMaker : ICertificateMaker
internal class WinCertificateMaker : ICertificateMaker
{
private readonly Type typeX500DN;
......@@ -42,12 +42,12 @@ namespace Titanium.Web.Proxy.Network.Certificate
private readonly string sProviderName = "Microsoft Enhanced Cryptographic Provider v1.0";
private object _SharedPrivateKey;
private object sharedPrivateKey;
/// <summary>
/// Constructor.
/// </summary>
public WinCertificateMaker()
internal WinCertificateMaker()
{
typeX500DN = Type.GetTypeFromProgID("X509Enrollment.CX500DistinguishedName", true);
typeX509PrivateKey = Type.GetTypeFromProgID("X509Enrollment.CX509PrivateKey", true);
......@@ -105,7 +105,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
if (!isRoot)
{
sharedPrivateKey = _SharedPrivateKey;
sharedPrivateKey = this.sharedPrivateKey;
}
if (sharedPrivateKey == null)
......@@ -130,52 +130,52 @@ namespace Titanium.Web.Proxy.Network.Certificate
if (!isRoot)
{
_SharedPrivateKey = sharedPrivateKey;
this.sharedPrivateKey = sharedPrivateKey;
}
}
typeValue = new object[1];
var OID = Activator.CreateInstance(typeOID);
var oid = Activator.CreateInstance(typeOID);
typeValue[0] = "1.3.6.1.5.5.7.3.1";
typeOID.InvokeMember("InitializeFromValue", BindingFlags.InvokeMethod, null, OID, typeValue);
typeOID.InvokeMember("InitializeFromValue", BindingFlags.InvokeMethod, null, oid, typeValue);
var OIDS = Activator.CreateInstance(typeOIDS);
typeValue[0] = OID;
typeOIDS.InvokeMember("Add", BindingFlags.InvokeMethod, null, OIDS, typeValue);
var oids = Activator.CreateInstance(typeOIDS);
typeValue[0] = oid;
typeOIDS.InvokeMember("Add", BindingFlags.InvokeMethod, null, oids, typeValue);
var EKUExt = Activator.CreateInstance(typeEKUExt);
typeValue[0] = OIDS;
typeEKUExt.InvokeMember("InitializeEncode", BindingFlags.InvokeMethod, null, EKUExt, typeValue);
var ekuExt = Activator.CreateInstance(typeEKUExt);
typeValue[0] = oids;
typeEKUExt.InvokeMember("InitializeEncode", BindingFlags.InvokeMethod, null, ekuExt, typeValue);
var RequestCert = Activator.CreateInstance(typeRequestCert);
var requestCert = Activator.CreateInstance(typeRequestCert);
typeValue = new[] { 1, sharedPrivateKey, string.Empty };
typeRequestCert.InvokeMember("InitializeFromPrivateKey", BindingFlags.InvokeMethod, null, RequestCert, typeValue);
typeRequestCert.InvokeMember("InitializeFromPrivateKey", BindingFlags.InvokeMethod, null, requestCert, typeValue);
typeValue = new[] { x500CertDN };
typeRequestCert.InvokeMember("Subject", BindingFlags.PutDispProperty, null, RequestCert, typeValue);
typeRequestCert.InvokeMember("Subject", BindingFlags.PutDispProperty, null, requestCert, typeValue);
typeValue[0] = x500RootCertDN;
typeRequestCert.InvokeMember("Issuer", BindingFlags.PutDispProperty, null, RequestCert, typeValue);
typeRequestCert.InvokeMember("Issuer", BindingFlags.PutDispProperty, null, requestCert, typeValue);
typeValue[0] = validFrom;
typeRequestCert.InvokeMember("NotBefore", BindingFlags.PutDispProperty, null, RequestCert, typeValue);
typeRequestCert.InvokeMember("NotBefore", BindingFlags.PutDispProperty, null, requestCert, typeValue);
typeValue[0] = validTo;
typeRequestCert.InvokeMember("NotAfter", BindingFlags.PutDispProperty, null, RequestCert, typeValue);
typeRequestCert.InvokeMember("NotAfter", BindingFlags.PutDispProperty, null, requestCert, typeValue);
var KUExt = Activator.CreateInstance(typeKUExt);
var kuExt = Activator.CreateInstance(typeKUExt);
typeValue[0] = 176;
typeKUExt.InvokeMember("InitializeEncode", BindingFlags.InvokeMethod, null, KUExt, typeValue);
typeKUExt.InvokeMember("InitializeEncode", BindingFlags.InvokeMethod, null, kuExt, typeValue);
var certificate = typeRequestCert.InvokeMember("X509Extensions", BindingFlags.GetProperty, null, RequestCert, null);
var certificate = typeRequestCert.InvokeMember("X509Extensions", BindingFlags.GetProperty, null, requestCert, null);
typeValue = new object[1];
if (!isRoot)
{
typeValue[0] = KUExt;
typeValue[0] = kuExt;
typeX509Extensions.InvokeMember("Add", BindingFlags.InvokeMethod, null, certificate, typeValue);
}
typeValue[0] = EKUExt;
typeValue[0] = ekuExt;
typeX509Extensions.InvokeMember("Add", BindingFlags.InvokeMethod, null, certificate, typeValue);
if (!isRoot)
......@@ -203,12 +203,12 @@ namespace Titanium.Web.Proxy.Network.Certificate
if (!isRoot)
{
var SignerCertificate = Activator.CreateInstance(typeSignerCertificate);
var signerCertificate = Activator.CreateInstance(typeSignerCertificate);
typeValue = new object[] { 0, 0, 12, signingCertificate.Thumbprint };
typeSignerCertificate.InvokeMember("Initialize", BindingFlags.InvokeMethod, null, SignerCertificate, typeValue);
typeValue = new[] { SignerCertificate };
typeRequestCert.InvokeMember("SignerCertificate", BindingFlags.PutDispProperty, null, RequestCert, typeValue);
typeSignerCertificate.InvokeMember("Initialize", BindingFlags.InvokeMethod, null, signerCertificate, typeValue);
typeValue = new[] { signerCertificate };
typeRequestCert.InvokeMember("SignerCertificate", BindingFlags.PutDispProperty, null, requestCert, typeValue);
}
else
{
......@@ -220,24 +220,24 @@ namespace Titanium.Web.Proxy.Network.Certificate
typeX509Extensions.InvokeMember("Add", BindingFlags.InvokeMethod, null, certificate, typeValue);
}
OID = Activator.CreateInstance(typeOID);
oid = Activator.CreateInstance(typeOID);
typeValue = new object[] { 1, 0, 0, hashAlg };
typeOID.InvokeMember("InitializeFromAlgorithmName", BindingFlags.InvokeMethod, null, OID, typeValue);
typeOID.InvokeMember("InitializeFromAlgorithmName", BindingFlags.InvokeMethod, null, oid, typeValue);
typeValue = new[] { OID };
typeRequestCert.InvokeMember("HashAlgorithm", BindingFlags.PutDispProperty, null, RequestCert, typeValue);
typeRequestCert.InvokeMember("Encode", BindingFlags.InvokeMethod, null, RequestCert, null);
typeValue = new[] { oid };
typeRequestCert.InvokeMember("HashAlgorithm", BindingFlags.PutDispProperty, null, requestCert, typeValue);
typeRequestCert.InvokeMember("Encode", BindingFlags.InvokeMethod, null, requestCert, null);
var X509Enrollment = Activator.CreateInstance(typeX509Enrollment);
var x509Enrollment = Activator.CreateInstance(typeX509Enrollment);
typeValue[0] = RequestCert;
typeX509Enrollment.InvokeMember("InitializeFromRequest", BindingFlags.InvokeMethod, null, X509Enrollment, typeValue);
typeValue[0] = requestCert;
typeX509Enrollment.InvokeMember("InitializeFromRequest", BindingFlags.InvokeMethod, null, x509Enrollment, typeValue);
if (isRoot)
{
typeValue[0] = fullSubject;
typeX509Enrollment.InvokeMember("CertificateFriendlyName", BindingFlags.PutDispProperty, null, X509Enrollment, typeValue);
typeX509Enrollment.InvokeMember("CertificateFriendlyName", BindingFlags.PutDispProperty, null, x509Enrollment, typeValue);
}
......@@ -245,15 +245,15 @@ namespace Titanium.Web.Proxy.Network.Certificate
typeValue[0] = 0;
var createCertRequest = typeX509Enrollment.InvokeMember("CreateRequest", BindingFlags.InvokeMethod, null, X509Enrollment, typeValue);
var createCertRequest = typeX509Enrollment.InvokeMember("CreateRequest", BindingFlags.InvokeMethod, null, x509Enrollment, typeValue);
typeValue = new[] { 2, createCertRequest, 0, string.Empty };
typeX509Enrollment.InvokeMember("InstallResponse", BindingFlags.InvokeMethod, null, X509Enrollment, typeValue);
typeX509Enrollment.InvokeMember("InstallResponse", BindingFlags.InvokeMethod, null, x509Enrollment, typeValue);
typeValue = new object[] { null, 0, 1 };
try
{
var empty = (string)typeX509Enrollment.InvokeMember("CreatePFX", BindingFlags.InvokeMethod, null, X509Enrollment, typeValue);
var empty = (string)typeX509Enrollment.InvokeMember("CreatePFX", BindingFlags.InvokeMethod, null, x509Enrollment, typeValue);
return new X509Certificate2(Convert.FromBase64String(empty), string.Empty, X509KeyStorageFlags.Exportable);
}
catch (Exception)
......
......@@ -31,6 +31,10 @@ namespace Titanium.Web.Proxy.Network
/// </summary>
internal class CertificateManager : IDisposable
{
private const string defaultRootCertificateIssuer = "Titanium";
private const string defaultRootRootCertificateName = "Titanium Root Certificate Authority";
private readonly ICertificateMaker certEngine;
private bool clearCertificates { get; set; }
......@@ -66,8 +70,8 @@ namespace Titanium.Web.Proxy.Network
certEngine = new WinCertificateMaker();
}
Issuer = issuer;
RootCertificateName = rootCertificateName;
Issuer = issuer ?? defaultRootCertificateIssuer;
RootCertificateName = rootCertificateName ?? defaultRootRootCertificateName;
certificateCache = new ConcurrentDictionary<string, CachedCertificate>();
}
......@@ -88,7 +92,7 @@ namespace Titanium.Web.Proxy.Network
return fileName;
}
internal X509Certificate2 GetRootCertificate()
internal X509Certificate2 LoadRootCertificate()
{
var fileName = GetRootCertificatePath();
if (!File.Exists(fileName)) return null;
......@@ -108,11 +112,16 @@ namespace Titanium.Web.Proxy.Network
/// <returns>true if succeeded, else false</returns>
internal bool CreateTrustedRootCertificate()
{
RootCertificate = GetRootCertificate();
if (RootCertificate == null)
{
RootCertificate = LoadRootCertificate();
}
if (RootCertificate != null)
{
return true;
}
try
{
RootCertificate = CreateCertificate(RootCertificateName, true);
......@@ -121,6 +130,7 @@ namespace Titanium.Web.Proxy.Network
{
exceptionFunc(e);
}
if (RootCertificate != null)
{
try
......@@ -133,9 +143,23 @@ namespace Titanium.Web.Proxy.Network
exceptionFunc(e);
}
}
return RootCertificate != null;
}
/// <summary>
/// Trusts the root certificate.
/// </summary>
/// <param name="exceptionFunc"></param>
internal void TrustRootCertificate(Action<Exception> exceptionFunc)
{
//current user
TrustRootCertificate(StoreLocation.CurrentUser, exceptionFunc);
//current system
TrustRootCertificate(StoreLocation.LocalMachine, exceptionFunc);
}
/// <summary>
/// Create an SSL certificate
/// </summary>
......@@ -144,15 +168,13 @@ namespace Titanium.Web.Proxy.Network
/// <returns></returns>
internal virtual X509Certificate2 CreateCertificate(string certificateName, bool isRootCertificate)
{
if (certificateCache.ContainsKey(certificateName))
{
var cached = certificateCache[certificateName];
cached.LastAccess = DateTime.Now;
return cached.Certificate;
}
X509Certificate2 certificate = null;
lock (string.Intern(certificateName))
{
......@@ -160,6 +182,11 @@ namespace Titanium.Web.Proxy.Network
{
try
{
if (!isRootCertificate && RootCertificate == null)
{
CreateTrustedRootCertificate();
}
certificate = certEngine.MakeCertificate(certificateName, isRootCertificate, RootCertificate);
}
catch (Exception e)
......@@ -168,7 +195,7 @@ namespace Titanium.Web.Proxy.Network
}
if (certificate != null && !certificateCache.ContainsKey(certificateName))
{
certificateCache.Add(certificateName, new CachedCertificate() { Certificate = certificate });
certificateCache.Add(certificateName, new CachedCertificate { Certificate = certificate });
}
}
else
......@@ -182,10 +209,7 @@ namespace Titanium.Web.Proxy.Network
}
}
return certificate;
}
/// <summary>
......
......@@ -7,7 +7,7 @@ namespace Titanium.Web.Proxy.Network
/// <summary>
/// This class wraps Tcp connection to client
/// </summary>
public class ProxyClient
internal class ProxyClient
{
/// <summary>
/// TcpClient used to communicate with client
......
......@@ -9,7 +9,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
/// <summary>
/// An object that holds TcpConnection to a particular server and port
/// </summary>
public class TcpConnection : IDisposable
internal class TcpConnection : IDisposable
{
internal ExternalProxy UpStreamHttpProxy { get; set; }
......
using System;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Net.Security;
using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Models;
using System.Security.Authentication;
using System.Linq;
using Titanium.Web.Proxy.Shared;
namespace Titanium.Web.Proxy.Network.Tcp
{
using System.Net;
/// <summary>
/// A class that manages Tcp Connection to server used by this proxy server
/// </summary>
internal class TcpConnectionFactory
{
/// <summary>
/// Creates a TCP connection to server
/// </summary>
/// <param name="bufferSize"></param>
/// <param name="connectionTimeOutSeconds"></param>
/// <param name="remoteHostName"></param>
/// <param name="httpVersion"></param>
/// <param name="isHttps"></param>
/// <param name="remotePort"></param>
/// <param name="supportedSslProtocols"></param>
/// <param name="remoteCertificateValidationCallback"></param>
/// <param name="localCertificateSelectionCallback"></param>
/// <param name="externalHttpProxy"></param>
/// <param name="externalHttpsProxy"></param>
/// <param name="clientStream"></param>
/// <param name="upStreamEndPoint"></param>
/// <returns></returns>
internal async Task<TcpConnection> CreateClient(int bufferSize, int connectionTimeOutSeconds,
string remoteHostName, int remotePort, Version httpVersion,
bool isHttps, SslProtocols supportedSslProtocols,
RemoteCertificateValidationCallback remoteCertificateValidationCallback, LocalCertificateSelectionCallback localCertificateSelectionCallback,
ExternalProxy externalHttpProxy, ExternalProxy externalHttpsProxy,
Stream clientStream, EndPoint upStreamEndPoint)
{
TcpClient client;
Stream stream;
if (isHttps)
{
SslStream sslStream = null;
//If this proxy uses another external proxy then create a tunnel request for HTTPS connections
if (externalHttpsProxy != null && externalHttpsProxy.HostName != remoteHostName)
{
client = new TcpClient();
client.Client.Bind(upStreamEndPoint);
await client.ConnectAsync(externalHttpsProxy.HostName, externalHttpsProxy.Port);
stream = client.GetStream();
using (var writer = new StreamWriter(stream, Encoding.ASCII, bufferSize, true) { NewLine = ProxyConstants.NewLine })
{
await writer.WriteLineAsync($"CONNECT {remoteHostName}:{remotePort} HTTP/{httpVersion}");
await writer.WriteLineAsync($"Host: {remoteHostName}:{remotePort}");
await writer.WriteLineAsync("Connection: Keep-Alive");
if (!string.IsNullOrEmpty(externalHttpsProxy.UserName) && externalHttpsProxy.Password != null)
{
await writer.WriteLineAsync("Proxy-Connection: keep-alive");
await writer.WriteLineAsync("Proxy-Authorization" + ": Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes(externalHttpsProxy.UserName + ":" + externalHttpsProxy.Password)));
}
await writer.WriteLineAsync();
await writer.FlushAsync();
writer.Close();
}
using (var reader = new CustomBinaryReader(stream))
{
var result = await reader.ReadLineAsync();
if (!new[] { "200 OK", "connection established" }.Any(s => result.ToLower().Contains(s.ToLower())))
{
throw new Exception("Upstream proxy failed to create a secure tunnel");
}
await reader.ReadAllLinesAsync();
}
}
else
{
client = new TcpClient();
client.Client.Bind(upStreamEndPoint);
await client.ConnectAsync(remoteHostName, remotePort);
stream = client.GetStream();
}
try
{
sslStream = new SslStream(stream, true, remoteCertificateValidationCallback,
localCertificateSelectionCallback);
await sslStream.AuthenticateAsClientAsync(remoteHostName, null, supportedSslProtocols, false);
stream = sslStream;
}
catch
{
sslStream?.Dispose();
throw;
}
}
else
{
if (externalHttpProxy != null && externalHttpProxy.HostName != remoteHostName)
{
client = new TcpClient();
client.Client.Bind(upStreamEndPoint);
await client.ConnectAsync(externalHttpProxy.HostName, externalHttpProxy.Port);
stream = client.GetStream();
}
else
{
client = new TcpClient();
client.Client.Bind(upStreamEndPoint);
await client.ConnectAsync(remoteHostName, remotePort);
stream = client.GetStream();
}
}
client.ReceiveTimeout = connectionTimeOutSeconds * 1000;
client.SendTimeout = connectionTimeOutSeconds * 1000;
stream.ReadTimeout = connectionTimeOutSeconds * 1000;
stream.WriteTimeout = connectionTimeOutSeconds * 1000;
return new TcpConnection()
{
UpStreamHttpProxy = externalHttpProxy,
UpStreamHttpsProxy = externalHttpsProxy,
HostName = remoteHostName,
Port = remotePort,
IsHttps = isHttps,
TcpClient = client,
StreamReader = new CustomBinaryReader(stream),
Stream = stream,
Version = httpVersion
};
}
}
using System;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Net.Security;
using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Models;
using System.Security.Authentication;
using System.Linq;
using Titanium.Web.Proxy.Shared;
namespace Titanium.Web.Proxy.Network.Tcp
{
using System.Net;
/// <summary>
/// A class that manages Tcp Connection to server used by this proxy server
/// </summary>
internal class TcpConnectionFactory
{
/// <summary>
/// Creates a TCP connection to server
/// </summary>
/// <param name="bufferSize"></param>
/// <param name="connectionTimeOutSeconds"></param>
/// <param name="remoteHostName"></param>
/// <param name="httpVersion"></param>
/// <param name="isHttps"></param>
/// <param name="remotePort"></param>
/// <param name="supportedSslProtocols"></param>
/// <param name="remoteCertificateValidationCallback"></param>
/// <param name="localCertificateSelectionCallback"></param>
/// <param name="externalHttpProxy"></param>
/// <param name="externalHttpsProxy"></param>
/// <param name="clientStream"></param>
/// <param name="upStreamEndPoint"></param>
/// <returns></returns>
internal async Task<TcpConnection> CreateClient(int bufferSize, int connectionTimeOutSeconds,
string remoteHostName, int remotePort, Version httpVersion,
bool isHttps, SslProtocols supportedSslProtocols,
RemoteCertificateValidationCallback remoteCertificateValidationCallback, LocalCertificateSelectionCallback localCertificateSelectionCallback,
ExternalProxy externalHttpProxy, ExternalProxy externalHttpsProxy,
Stream clientStream, IPEndPoint upStreamEndPoint)
{
TcpClient client;
Stream stream;
bool isLocalhost = (externalHttpsProxy == null && externalHttpProxy == null) ? false : NetworkHelper.IsLocalIpAddress(remoteHostName);
bool useHttpsProxy = externalHttpsProxy != null && externalHttpsProxy.HostName != remoteHostName && (externalHttpsProxy.BypassForLocalhost && !isLocalhost);
bool useHttpProxy = externalHttpProxy != null && externalHttpProxy.HostName != remoteHostName && (externalHttpProxy.BypassForLocalhost && !isLocalhost);
if (isHttps)
{
SslStream sslStream = null;
//If this proxy uses another external proxy then create a tunnel request for HTTPS connections
if (useHttpsProxy)
{
client = new TcpClient(upStreamEndPoint);
await client.ConnectAsync(externalHttpsProxy.HostName, externalHttpsProxy.Port);
stream = client.GetStream();
using (var writer = new StreamWriter(stream, Encoding.ASCII, bufferSize, true) { NewLine = ProxyConstants.NewLine })
{
await writer.WriteLineAsync($"CONNECT {remoteHostName}:{remotePort} HTTP/{httpVersion}");
await writer.WriteLineAsync($"Host: {remoteHostName}:{remotePort}");
await writer.WriteLineAsync("Connection: Keep-Alive");
if (!string.IsNullOrEmpty(externalHttpsProxy.UserName) && externalHttpsProxy.Password != null)
{
await writer.WriteLineAsync("Proxy-Connection: keep-alive");
await writer.WriteLineAsync("Proxy-Authorization" + ": Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes(externalHttpsProxy.UserName + ":" + externalHttpsProxy.Password)));
}
await writer.WriteLineAsync();
await writer.FlushAsync();
writer.Close();
}
using (var reader = new CustomBinaryReader(stream))
{
var result = await reader.ReadLineAsync();
if (!new[] { "200 OK", "connection established" }.Any(s => result.ToLower().Contains(s.ToLower())))
{
throw new Exception("Upstream proxy failed to create a secure tunnel");
}
await reader.ReadAllLinesAsync();
}
}
else
{
client = new TcpClient(upStreamEndPoint);
await client.ConnectAsync(remoteHostName, remotePort);
stream = client.GetStream();
}
try
{
sslStream = new SslStream(stream, true, remoteCertificateValidationCallback,
localCertificateSelectionCallback);
await sslStream.AuthenticateAsClientAsync(remoteHostName, null, supportedSslProtocols, false);
stream = sslStream;
}
catch
{
sslStream?.Dispose();
throw;
}
}
else
{
if (useHttpProxy)
{
client = new TcpClient(upStreamEndPoint);
await client.ConnectAsync(externalHttpProxy.HostName, externalHttpProxy.Port);
stream = client.GetStream();
}
else
{
client = new TcpClient(upStreamEndPoint);
await client.ConnectAsync(remoteHostName, remotePort);
stream = client.GetStream();
}
}
client.ReceiveTimeout = connectionTimeOutSeconds * 1000;
client.SendTimeout = connectionTimeOutSeconds * 1000;
stream.ReadTimeout = connectionTimeOutSeconds * 1000;
stream.WriteTimeout = connectionTimeOutSeconds * 1000;
return new TcpConnection()
{
UpStreamHttpProxy = externalHttpProxy,
UpStreamHttpsProxy = externalHttpsProxy,
HostName = remoteHostName,
Port = remotePort,
IsHttps = isHttps,
TcpClient = client,
StreamReader = new CustomBinaryReader(stream),
Stream = stream,
Version = httpVersion
};
}
}
}
\ No newline at end of file
......@@ -13,7 +13,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
/// Initializes a new instance of the <see cref="TcpRow"/> class.
/// </summary>
/// <param name="tcpRow">TcpRow struct.</param>
public TcpRow(NativeMethods.TcpRow tcpRow)
internal TcpRow(NativeMethods.TcpRow tcpRow)
{
ProcessId = tcpRow.owningPid;
......@@ -29,16 +29,16 @@ namespace Titanium.Web.Proxy.Network.Tcp
/// <summary>
/// Gets the local end point.
/// </summary>
public IPEndPoint LocalEndPoint { get; }
internal IPEndPoint LocalEndPoint { get; }
/// <summary>
/// Gets the remote end point.
/// </summary>
public IPEndPoint RemoteEndPoint { get; }
/// <summary>
/// Gets the remote end point.
/// </summary>
internal IPEndPoint RemoteEndPoint { get; }
/// <summary>
/// Gets the process identifier.
/// </summary>
public int ProcessId { get; }
internal int ProcessId { get; }
}
}
\ No newline at end of file
......@@ -17,7 +17,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
/// Initializes a new instance of the <see cref="TcpTable"/> class.
/// </summary>
/// <param name="tcpRows">TcpRow collection to initialize with.</param>
public TcpTable(IEnumerable<TcpRow> tcpRows)
internal TcpTable(IEnumerable<TcpRow> tcpRows)
{
this.tcpRows = tcpRows;
}
......@@ -25,7 +25,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
/// <summary>
/// Gets the TCP rows.
/// </summary>
public IEnumerable<TcpRow> TcpRows => tcpRows;
internal IEnumerable<TcpRow> TcpRows => tcpRows;
/// <summary>
/// Returns an enumerator that iterates through the collection.
......
......@@ -19,11 +19,10 @@ namespace Titanium.Web.Proxy
/// </summary>
public partial class ProxyServer : IDisposable
{
/// <summary>
/// Is the root certificate used by this proxy is valid?
/// </summary>
private bool certValidated { get; set; }
private bool? certValidated { get; set; }
/// <summary>
/// Is the proxy currently running
......@@ -33,7 +32,7 @@ namespace Titanium.Web.Proxy
/// <summary>
/// Manages certificates used by this proxy
/// </summary>
private CertificateManager certificateCacheManager { get; set; }
private CertificateManager certificateManager { get; set; }
/// <summary>
/// An default exception log func
......@@ -45,6 +44,8 @@ namespace Titanium.Web.Proxy
/// </summary>
private Action<Exception> exceptionFunc;
private bool trustRootCertificate;
/// <summary>
/// A object that creates tcp connection to server
/// </summary>
......@@ -66,27 +67,65 @@ namespace Titanium.Web.Proxy
/// <summary>
/// Buffer size used throughout this proxy
/// </summary>
public int BUFFER_SIZE { get; set; } = 8192;
public int BufferSize { get; set; } = 8192;
/// <summary>
/// The root certificate
/// </summary>
public X509Certificate2 RootCertificate
{
get { return certificateManager.RootCertificate; }
set { certificateManager.RootCertificate = value; }
}
/// <summary>
/// Name of the root certificate issuer
/// Name of the root certificate issuer
/// (This is valid only when RootCertificate property is not set)
/// </summary>
public string RootCertificateIssuerName { get; set; }
public string RootCertificateIssuerName
{
get { return certificateManager.Issuer; }
set
{
CreateCertificateManager(certificateManager.RootCertificateName, value);
certValidated = null;
}
}
/// <summary>
/// Name of the root certificate
/// (This is valid only when RootCertificate property is not set)
/// If no certificate is provided then a default Root Certificate will be created and used
/// The provided root certificate has to be in the proxy exe directory with the private key
/// The root certificate file should be named as "rootCert.pfx"
/// The provided root certificate will be stored in proxy exe directory with the private key
/// Root certificate file will be named as "rootCert.pfx"
/// </summary>
public string RootCertificateName { get; set; }
public string RootCertificateName
{
get { return certificateManager.RootCertificateName; }
set
{
CreateCertificateManager(value, certificateManager.Issuer);
certValidated = null;
}
}
/// <summary>
/// Trust the RootCertificate used by this proxy server
/// Note that this do not make the client trust the certificate!
/// This would import the root certificate to the certificate store of machine that runs this proxy server
/// </summary>
public bool TrustRootCertificate { get; set; }
public bool TrustRootCertificate
{
get { return trustRootCertificate; }
set
{
trustRootCertificate = value;
if (value)
{
EnsureRootCertificate();
}
}
}
/// <summary>
/// Select Certificate Engine
......@@ -211,7 +250,9 @@ namespace Titanium.Web.Proxy
/// <summary>
/// Constructor
/// </summary>
public ProxyServer() : this(null, null) { }
public ProxyServer() : this(null, null)
{
}
/// <summary>
/// Constructor.
......@@ -220,9 +261,6 @@ namespace Titanium.Web.Proxy
/// <param name="rootCertificateIssuerName">Name of root certificate issuer.</param>
public ProxyServer(string rootCertificateName, string rootCertificateIssuerName)
{
RootCertificateName = rootCertificateName;
RootCertificateIssuerName = rootCertificateIssuerName;
//default values
ConnectionTimeOutSeconds = 120;
CertificateCacheTimeOutMinutes = 60;
......@@ -233,8 +271,8 @@ namespace Titanium.Web.Proxy
#if !DEBUG
new FireFoxProxySettingsManager();
#endif
RootCertificateName = RootCertificateName ?? "Titanium Root Certificate Authority";
RootCertificateIssuerName = RootCertificateIssuerName ?? "Titanium";
CreateCertificateManager(rootCertificateName, rootCertificateIssuerName);
}
/// <summary>
......@@ -328,8 +366,10 @@ namespace Titanium.Web.Proxy
.ToList()
.ForEach(x => x.IsSystemHttpsProxy = false);
EnsureRootCertificate();
//If certificate was trusted by the machine
if (certValidated)
if (certValidated == true)
{
systemProxySettingsManager.SetHttpsProxy(
Equals(endPoint.IpAddress, IPAddress.Any) |
......@@ -397,23 +437,6 @@ namespace Titanium.Web.Proxy
throw new Exception("Proxy is already running.");
}
certificateCacheManager = new CertificateManager(CertificateEngine,
RootCertificateIssuerName,
RootCertificateName, ExceptionFunc);
certValidated = certificateCacheManager.CreateTrustedRootCertificate();
if (TrustRootCertificate)
{
//current user
certificateCacheManager
.TrustRootCertificate(StoreLocation.CurrentUser, ExceptionFunc);
//current system
certificateCacheManager
.TrustRootCertificate(StoreLocation.LocalMachine, ExceptionFunc);
}
if (ForwardToUpstreamGateway && GetCustomUpStreamHttpProxyFunc == null
&& GetCustomUpStreamHttpsProxyFunc == null)
{
......@@ -426,32 +449,11 @@ namespace Titanium.Web.Proxy
Listen(endPoint);
}
certificateCacheManager.ClearIdleCertificates(CertificateCacheTimeOutMinutes);
certificateManager.ClearIdleCertificates(CertificateCacheTimeOutMinutes);
proxyRunning = true;
}
/// <summary>
/// Gets the system up stream proxy.
/// </summary>
/// <param name="sessionEventArgs">The <see cref="SessionEventArgs"/> instance containing the event data.</param>
/// <returns><see cref="ExternalProxy"/> instance containing valid proxy configuration from PAC/WAPD scripts if any exists.</returns>
private Task<ExternalProxy> GetSystemUpStreamProxy(SessionEventArgs sessionEventArgs)
{
// Use built-in WebProxy class to handle PAC/WAPD scripts.
var systemProxyResolver = new WebProxy();
var systemProxyUri = systemProxyResolver.GetProxy(sessionEventArgs.WebSession.Request.RequestUri);
// TODO: Apply authorization
var systemProxy = new ExternalProxy
{
HostName = systemProxyUri.Host,
Port = systemProxyUri.Port
};
return Task.FromResult(systemProxy);
}
/// <summary>
/// Stop this proxy server
......@@ -480,11 +482,24 @@ namespace Titanium.Web.Proxy
ProxyEndPoints.Clear();
certificateCacheManager?.StopClearIdleCertificates();
certificateManager?.StopClearIdleCertificates();
proxyRunning = false;
}
/// <summary>
/// Dispose Proxy.
/// </summary>
public void Dispose()
{
if (proxyRunning)
{
Stop();
}
certificateManager?.Dispose();
}
/// <summary>
/// Listen on the given end point on local machine
/// </summary>
......@@ -499,16 +514,7 @@ namespace Titanium.Web.Proxy
endPoint.Listener.BeginAcceptTcpClient(OnAcceptConnection, endPoint);
}
/// <summary>
/// Quit listening on the given end point
/// </summary>
/// <param name="endPoint"></param>
private void QuitListen(ProxyEndPoint endPoint)
{
endPoint.Listener.Stop();
endPoint.Listener.Server.Close();
endPoint.Listener.Server.Dispose();
}
/// <summary>
/// Verifiy if its safe to set this end point as System proxy
......@@ -528,6 +534,48 @@ namespace Titanium.Web.Proxy
}
}
/// <summary>
/// Gets the system up stream proxy.
/// </summary>
/// <param name="sessionEventArgs">The <see cref="SessionEventArgs"/> instance containing the event data.</param>
/// <returns><see cref="ExternalProxy"/> instance containing valid proxy configuration from PAC/WAPD scripts if any exists.</returns>
private Task<ExternalProxy> GetSystemUpStreamProxy(SessionEventArgs sessionEventArgs)
{
// Use built-in WebProxy class to handle PAC/WAPD scripts.
var systemProxyResolver = new WebProxy();
var systemProxyUri = systemProxyResolver.GetProxy(sessionEventArgs.WebSession.Request.RequestUri);
// TODO: Apply authorization
var systemProxy = new ExternalProxy
{
HostName = systemProxyUri.Host,
Port = systemProxyUri.Port
};
return Task.FromResult(systemProxy);
}
private void CreateCertificateManager(string rootCertificateName, string rootCertificateIssuerName)
{
certificateManager = new CertificateManager(CertificateEngine,
rootCertificateIssuerName, rootCertificateName, ExceptionFunc);
}
private void EnsureRootCertificate()
{
if (!certValidated.HasValue)
{
certValidated = certificateManager.CreateTrustedRootCertificate();
if (TrustRootCertificate)
{
certificateManager.TrustRootCertificate(ExceptionFunc);
}
}
}
/// <summary>
/// When a connection is received from client act
/// </summary>
......@@ -599,18 +647,16 @@ namespace Titanium.Web.Proxy
}
/// <summary>
/// Dispose Proxy.
/// Quit listening on the given end point
/// </summary>
public void Dispose()
/// <param name="endPoint"></param>
private void QuitListen(ProxyEndPoint endPoint)
{
if (proxyRunning)
{
Stop();
}
certificateCacheManager?.Dispose();
endPoint.Listener.Stop();
endPoint.Listener.Server.Close();
endPoint.Listener.Server.Dispose();
}
/// <summary>
/// Invocator for BeforeRequest event.
/// </summary>
......
......@@ -115,7 +115,7 @@ namespace Titanium.Web.Proxy
sslStream = new SslStream(clientStream, true);
var certificate = endPoint.GenericCertificate ?? certificateCacheManager.CreateCertificate(httpRemoteUri.Host, false);
var certificate = endPoint.GenericCertificate ?? certificateManager.CreateCertificate(httpRemoteUri.Host, false);
//Successfully managed to authenticate the client using the fake certificate
await sslStream.AuthenticateAsServerAsync(certificate, false,
......@@ -147,7 +147,7 @@ namespace Titanium.Web.Proxy
//write back successfull CONNECT response
await WriteConnectResponse(clientStreamWriter, version);
await TcpHelper.SendRaw(BUFFER_SIZE, ConnectionTimeOutSeconds, httpRemoteUri.Host, httpRemoteUri.Port,
await TcpHelper.SendRaw(BufferSize, ConnectionTimeOutSeconds, httpRemoteUri.Host, httpRemoteUri.Port,
null, version, null,
false, SupportedSslProtocols,
ValidateServerCertificate,
......@@ -185,7 +185,7 @@ namespace Titanium.Web.Proxy
var sslStream = new SslStream(clientStream, true);
//implement in future once SNI supported by SSL stream, for now use the same certificate
var certificate = certificateCacheManager.CreateCertificate(endPoint.GenericCertificateName, false);
var certificate = certificateManager.CreateCertificate(endPoint.GenericCertificateName, false);
try
{
......@@ -245,7 +245,7 @@ namespace Titanium.Web.Proxy
args.CustomUpStreamHttpProxyUsed = customUpStreamHttpProxy;
args.CustomUpStreamHttpsProxyUsed = customUpStreamHttpsProxy;
connection = await tcpConnectionFactory.CreateClient(BUFFER_SIZE, ConnectionTimeOutSeconds,
connection = await tcpConnectionFactory.CreateClient(BufferSize, ConnectionTimeOutSeconds,
args.WebSession.Request.RequestUri.Host, args.WebSession.Request.RequestUri.Port, args.WebSession.Request.HttpVersion,
args.IsHttps, SupportedSslProtocols,
ValidateServerCertificate,
......@@ -378,7 +378,7 @@ namespace Titanium.Web.Proxy
}
var args =
new SessionEventArgs(BUFFER_SIZE, HandleHttpSessionResponse)
new SessionEventArgs(BufferSize, HandleHttpSessionResponse)
{
ProxyClient = {TcpClient = client},
WebSession = {ConnectHeaders = connectHeaders}
......@@ -487,7 +487,7 @@ namespace Titanium.Web.Proxy
//if upgrading to websocket then relay the requet without reading the contents
if (args.WebSession.Request.UpgradeToWebSocket)
{
await TcpHelper.SendRaw(BUFFER_SIZE, ConnectionTimeOutSeconds, httpRemoteUri.Host, httpRemoteUri.Port,
await TcpHelper.SendRaw(BufferSize, ConnectionTimeOutSeconds, httpRemoteUri.Host, httpRemoteUri.Port,
httpCmd, httpVersion, args.WebSession.Request.RequestHeaders, args.IsHttps,
SupportedSslProtocols, ValidateServerCertificate,
SelectClientCertificate,
......@@ -581,14 +581,14 @@ namespace Titanium.Web.Proxy
//send the request body bytes to server
if (args.WebSession.Request.ContentLength > 0)
{
await args.ProxyClient.ClientStreamReader.CopyBytesToStream(BUFFER_SIZE, postStream, args.WebSession.Request.ContentLength);
await args.ProxyClient.ClientStreamReader.CopyBytesToStream(BufferSize, postStream, args.WebSession.Request.ContentLength);
}
//Need to revist, find any potential bugs
//send the request body bytes to server in chunks
else if (args.WebSession.Request.IsChunked)
{
await args.ProxyClient.ClientStreamReader.CopyBytesToStreamChunked(BUFFER_SIZE, postStream);
await args.ProxyClient.ClientStreamReader.CopyBytesToStreamChunked(BufferSize, postStream);
}
}
}
......
......@@ -22,7 +22,7 @@ namespace Titanium.Web.Proxy
/// </summary>
/// <param name="args"></param>
/// <returns></returns>
public async Task HandleHttpSessionResponse(SessionEventArgs args)
private async Task HandleHttpSessionResponse(SessionEventArgs args)
{
//read response & headers from server
await args.WebSession.ReceiveResponse();
......@@ -108,7 +108,7 @@ namespace Titanium.Web.Proxy
|| !args.WebSession.Response.ResponseKeepAlive)
{
await args.WebSession.ServerConnection.StreamReader
.WriteResponseBody(BUFFER_SIZE, args.ProxyClient.ClientStream, args.WebSession.Response.IsChunked,
.WriteResponseBody(BufferSize, args.ProxyClient.ClientStream, args.WebSession.Response.IsChunked,
args.WebSession.Response.ContentLength);
}
//write response if connection:keep-alive header exist and when version is http/1.0
......@@ -116,7 +116,7 @@ namespace Titanium.Web.Proxy
else if (args.WebSession.Response.ResponseKeepAlive && args.WebSession.Response.HttpVersion.Minor == 0)
{
await args.WebSession.ServerConnection.StreamReader
.WriteResponseBody(BUFFER_SIZE, args.ProxyClient.ClientStream, args.WebSession.Response.IsChunked,
.WriteResponseBody(BufferSize, args.ProxyClient.ClientStream, args.WebSession.Response.IsChunked,
args.WebSession.Response.ContentLength);
}
}
......
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