Event to override the default verification logic of remote SSL certificate received during authentication.
Event occurs when server connection count changed.
diff --git a/examples/Titanium.Web.Proxy.Examples.Basic/ProxyTestController.cs b/examples/Titanium.Web.Proxy.Examples.Basic/ProxyTestController.cs
index 04681b95c..dbd2dbd2d 100644
--- a/examples/Titanium.Web.Proxy.Examples.Basic/ProxyTestController.cs
+++ b/examples/Titanium.Web.Proxy.Examples.Basic/ProxyTestController.cs
@@ -193,7 +193,7 @@ private async Task onResponse(object sender, SessionEventArgs e)
string ext = System.IO.Path.GetExtension(e.HttpClient.Request.RequestUri.AbsolutePath);
- //access user data set in request to do something with it
+ // access user data set in request to do something with it
//var userData = e.HttpClient.UserData as CustomUserData;
//if (ext == ".gif" || ext == ".png" || ext == ".jpg")
diff --git a/src/Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs b/src/Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs
index 325f90c63..2e14f37f9 100644
--- a/src/Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs
+++ b/src/Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs
@@ -615,36 +615,36 @@ public void Redirect(string url, bool closeServerConnection = false)
///
Close the server connection used by request if any?
public void Respond(Response response, bool closeServerConnection = false)
{
- //request already send/ready to be sent.
+ // request already send/ready to be sent.
if (HttpClient.Request.Locked)
{
- //response already received from server and ready to be sent to client.
+ // response already received from server and ready to be sent to client.
if (HttpClient.Response.Locked)
{
throw new Exception("You cannot call this function after response is sent to the client.");
}
- //cleanup original response.
+ // cleanup original response.
if (closeServerConnection)
{
- //no need to cleanup original connection.
- //it will be closed any way.
+ // no need to cleanup original connection.
+ // it will be closed any way.
TerminateServerConnection();
}
response.SetOriginalHeaders(HttpClient.Response);
- //response already received from server but not yet ready to sent to client.
+ // response already received from server but not yet ready to sent to client.
HttpClient.Response = response;
HttpClient.Response.Locked = true;
}
- //request not yet sent/not yet ready to be sent.
+ // request not yet sent/not yet ready to be sent.
else
{
HttpClient.Request.Locked = true;
HttpClient.Request.CancelRequest = true;
- //set new response.
+ // set new response.
HttpClient.Response = response;
HttpClient.Response.Locked = true;
}
diff --git a/src/Titanium.Web.Proxy/ExplicitClientHandler.cs b/src/Titanium.Web.Proxy/ExplicitClientHandler.cs
index 9bd7d4fc2..496b01f0f 100644
--- a/src/Titanium.Web.Proxy/ExplicitClientHandler.cs
+++ b/src/Titanium.Web.Proxy/ExplicitClientHandler.cs
@@ -134,6 +134,7 @@ await clientStreamWriter.WriteResponseAsync(connectArgs.HttpClient.Response,
if (decryptSsl && isClientHello)
{
+ clientConnection.SslProtocol = clientHelloInfo.SslProtocol;
connectRequest.RequestUri = new Uri("https://" + httpUrl);
bool http2Supported = false;
@@ -151,7 +152,8 @@ await clientStreamWriter.WriteResponseAsync(connectArgs.HttpClient.Response,
http2Supported = connection.NegotiatedApplicationProtocol ==
SslApplicationProtocol.Http2;
- //release connection back to pool instead of closing when connection pool is enabled.
+
+ // release connection back to pool instead of closing when connection pool is enabled.
await tcpConnectionFactory.Release(connection, true);
}
catch (Exception)
@@ -165,15 +167,15 @@ await clientStreamWriter.WriteResponseAsync(connectArgs.HttpClient.Response,
IPAddress[] ipAddresses = null;
try
{
- //make sure the host can be resolved before creating the prefetch task
+ // make sure the host can be resolved before creating the prefetch task
ipAddresses = await Dns.GetHostAddressesAsync(connectArgs.HttpClient.Request.RequestUri.Host);
}
catch (SocketException) { }
if (ipAddresses != null && ipAddresses.Length > 0)
{
- //don't pass cancellation token here
- //it could cause floating server connections when client exits
+ // don't pass cancellation token here
+ // it could cause floating server connections when client exits
prefetchConnectionTask = tcpConnectionFactory.GetServerConnection(this, connectArgs,
isConnect: true, applicationProtocols: null, noCache: false,
cancellationToken: CancellationToken.None);
diff --git a/src/Titanium.Web.Proxy/Extensions/TcpExtensions.cs b/src/Titanium.Web.Proxy/Extensions/TcpExtensions.cs
index e39a05f8a..21fc392db 100644
--- a/src/Titanium.Web.Proxy/Extensions/TcpExtensions.cs
+++ b/src/Titanium.Web.Proxy/Extensions/TcpExtensions.cs
@@ -50,11 +50,11 @@ internal static bool IsGoodConnection(this TcpClient client)
socket.Blocking = false;
socket.Send(tmp, 0, 0);
- //Connected.
+ // Connected.
}
catch
{
- //Should we let 10035 == WSAEWOULDBLOCK as valid connection?
+ // Should we let 10035 == WSAEWOULDBLOCK as valid connection?
return false;
}
finally
diff --git a/src/Titanium.Web.Proxy/Helpers/Network.cs b/src/Titanium.Web.Proxy/Helpers/Network.cs
index 80c6b15d4..5d4afc291 100644
--- a/src/Titanium.Web.Proxy/Helpers/Network.cs
+++ b/src/Titanium.Web.Proxy/Helpers/Network.cs
@@ -41,7 +41,7 @@ internal static bool IsLocalIpAddress(string hostName)
return true;
}
- //if hostname matches local host name
+ // if hostname matches local host name
if (hostName.Equals(localhostName, StringComparison.OrdinalIgnoreCase))
{
return true;
diff --git a/src/Titanium.Web.Proxy/Helpers/RunTime.cs b/src/Titanium.Web.Proxy/Helpers/RunTime.cs
index c116f00e5..b2d1e9847 100644
--- a/src/Titanium.Web.Proxy/Helpers/RunTime.cs
+++ b/src/Titanium.Web.Proxy/Helpers/RunTime.cs
@@ -42,7 +42,7 @@ public static class RunTime
public static bool IsMac => isRunningOnMac;
- //https://github.com/qmatteoq/DesktopBridgeHelpers/blob/master/DesktopBridge.Helpers/Helpers.cs
+ // https://github.com/qmatteoq/DesktopBridgeHelpers/blob/master/DesktopBridge.Helpers/Helpers.cs
private class UwpHelper
{
const long APPMODEL_ERROR_NO_PACKAGE = 15700L;
diff --git a/src/Titanium.Web.Proxy/Network/RetryPolicy.cs b/src/Titanium.Web.Proxy/Network/RetryPolicy.cs
index 9300d7b7f..fa77e3b9d 100644
--- a/src/Titanium.Web.Proxy/Network/RetryPolicy.cs
+++ b/src/Titanium.Web.Proxy/Network/RetryPolicy.cs
@@ -37,10 +37,10 @@ internal async Task
ExecuteAsync(Func ExecuteAsync(Func tcpClient.Client.RemoteEndPoint;
+ internal SslProtocols SslProtocol { get; set; }
+
internal SslApplicationProtocol NegotiatedApplicationProtocol { get; set; }
private readonly TcpClient tcpClient;
@@ -79,9 +82,9 @@ public void Dispose()
{
Task.Run(async () =>
{
- //delay calling tcp connection close()
- //so that client have enough time to call close first.
- //This way we can push tcp Time_Wait to client side when possible.
+ // delay calling tcp connection close()
+ // so that client have enough time to call close first.
+ // This way we can push tcp Time_Wait to client side when possible.
await Task.Delay(1000);
proxyServer.UpdateClientConnectionCount(false);
tcpClient.CloseSocket();
diff --git a/src/Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs b/src/Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs
index 50b5cc4c2..258513b0c 100644
--- a/src/Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs
+++ b/src/Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs
@@ -1,10 +1,12 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
+using System.IO;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
+using System.Security.Authentication;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@@ -23,15 +25,15 @@ namespace Titanium.Web.Proxy.Network.Tcp
internal class TcpConnectionFactory : IDisposable
{
- //Tcp server connection pool cache
+ // Tcp server connection pool cache
private readonly ConcurrentDictionary> cache
= new ConcurrentDictionary>();
- //Tcp connections waiting to be disposed by cleanup task
+ // Tcp connections waiting to be disposed by cleanup task
private readonly ConcurrentBag disposalBag =
new ConcurrentBag();
- //cache object race operations lock
+ // cache object race operations lock
private readonly SemaphoreSlim @lock = new SemaphoreSlim(1);
private volatile bool runCleanUpTask = true;
@@ -46,14 +48,14 @@ internal TcpConnectionFactory(ProxyServer server)
internal string GetConnectionCacheKey(string remoteHostName, int remotePort,
bool isHttps, List applicationProtocols,
- ProxyServer proxyServer, IPEndPoint upStreamEndPoint, ExternalProxy externalProxy)
+ IPEndPoint upStreamEndPoint, ExternalProxy externalProxy)
{
- //http version is ignored since its an application level decision b/w HTTP 1.0/1.1
- //also when doing connect request MS Edge browser sends http 1.0 but uses 1.1 after server sends 1.1 its response.
- //That can create cache miss for same server connection unnecessarily especially when prefetching with Connect.
- //http version 2 is separated using applicationProtocols below.
+ // http version is ignored since its an application level decision b/w HTTP 1.0/1.1
+ // also when doing connect request MS Edge browser sends http 1.0 but uses 1.1 after server sends 1.1 its response.
+ // That can create cache miss for same server connection unnecessarily especially when prefetching with Connect.
+ // http version 2 is separated using applicationProtocols below.
var cacheKeyBuilder = new StringBuilder($"{remoteHostName}-{remotePort}-" +
- //when creating Tcp client isConnect won't matter
+ // when creating Tcp client isConnect won't matter
$"{isHttps}-");
if (applicationProtocols != null)
{
@@ -69,7 +71,6 @@ internal string GetConnectionCacheKey(string remoteHostName, int remotePort,
cacheKeyBuilder.Append(externalProxy != null ? $"{externalProxy.GetCacheKey()}-" : string.Empty);
return cacheKeyBuilder.ToString();
-
}
///
@@ -101,7 +102,7 @@ internal async Task GetConnectionCacheKey(ProxyServer server, SessionEve
session.HttpClient.Request.RequestUri.Host,
session.HttpClient.Request.RequestUri.Port,
isHttps, applicationProtocols,
- server, session.HttpClient.UpStreamEndPoint ?? server.UpStreamEndPoint,
+ session.HttpClient.UpStreamEndPoint ?? server.UpStreamEndPoint,
customUpStreamProxy ?? (isHttps ? server.UpStreamHttpsProxy : server.UpStreamHttpProxy));
}
@@ -109,9 +110,11 @@ internal async Task GetConnectionCacheKey(ProxyServer server, SessionEve
///
/// Create a server connection.
///
+ /// The proxy server.
/// The session event arguments.
/// Is this a CONNECT request.
///
+ /// if set to true [no cache].
/// The cancellation token for this async task.
///
internal Task GetServerConnection(ProxyServer server, SessionEventArgsBase session, bool isConnect,
@@ -129,9 +132,11 @@ internal Task GetServerConnection(ProxyServer server, Sessi
///
/// Create a server connection.
///
+ /// The proxy server.
/// The session event arguments.
/// Is this a CONNECT request.
///
+ /// if set to true [no cache].
/// The cancellation token for this async task.
///
internal async Task GetServerConnection(ProxyServer server, SessionEventArgsBase session, bool isConnect,
@@ -166,6 +171,7 @@ internal async Task GetServerConnection(ProxyServer server,
/// The list of HTTPS application level protocol to negotiate if needed.
/// Is this a CONNECT request.
/// The current ProxyServer instance.
+ /// The session.
/// The local upstream endpoint to make request via.
/// The external proxy to make request via.
/// Not from cache/create new connection.
@@ -176,9 +182,9 @@ internal async Task GetServerConnection(string remoteHostNa
ProxyServer proxyServer, SessionEventArgsBase session, IPEndPoint upStreamEndPoint, ExternalProxy externalProxy,
bool noCache, CancellationToken cancellationToken)
{
+ var sslProtocol = session.ProxyClient.Connection.SslProtocol;
var cacheKey = GetConnectionCacheKey(remoteHostName, remotePort,
- isHttps, applicationProtocols,
- proxyServer, upStreamEndPoint, externalProxy);
+ isHttps, applicationProtocols, upStreamEndPoint, externalProxy);
if (proxyServer.EnableConnectionPool && !noCache)
{
@@ -202,7 +208,7 @@ internal async Task GetServerConnection(string remoteHostNa
}
}
- var connection = await createServerConnection(remoteHostName, remotePort, httpVersion, isHttps,
+ var connection = await createServerConnection(remoteHostName, remotePort, httpVersion, isHttps, sslProtocol,
applicationProtocols, isConnect, proxyServer, session, upStreamEndPoint, externalProxy, cancellationToken);
connection.CacheKey = cacheKey;
@@ -217,6 +223,7 @@ internal async Task GetServerConnection(string remoteHostNa
/// The remote port.
/// The http version to use.
/// Is this a HTTPS request.
+ /// The SSL protocol.
/// The list of HTTPS application level protocol to negotiate if needed.
/// Is this a CONNECT request.
/// The current ProxyServer instance.
@@ -226,11 +233,11 @@ internal async Task GetServerConnection(string remoteHostNa
/// The cancellation token for this async task.
///
private async Task createServerConnection(string remoteHostName, int remotePort,
- Version httpVersion, bool isHttps, List applicationProtocols, bool isConnect,
+ Version httpVersion, bool isHttps, SslProtocols sslProtocol, List applicationProtocols, bool isConnect,
ProxyServer proxyServer, SessionEventArgsBase session, IPEndPoint upStreamEndPoint, ExternalProxy externalProxy,
CancellationToken cancellationToken)
{
- //deny connection to proxy end points to avoid infinite connection loop.
+ // deny connection to proxy end points to avoid infinite connection loop.
if (Server.ProxyEndPoints.Any(x => x.Port == remotePort)
&& NetworkHelper.IsLocalIpAddress(remoteHostName))
{
@@ -266,22 +273,12 @@ private async Task createServerConnection(string remoteHost
SslApplicationProtocol negotiatedApplicationProtocol = default;
+ bool retry = true;
+ var enabledSslProtocols = sslProtocol;
+
+ retry:
try
{
- tcpClient = new TcpClient(upStreamEndPoint)
- {
- NoDelay = proxyServer.NoDelay,
- ReceiveTimeout = proxyServer.ConnectionTimeOutSeconds * 1000,
- SendTimeout = proxyServer.ConnectionTimeOutSeconds * 1000,
- LingerState = new LingerOption(true, proxyServer.TcpTimeWaitSeconds)
- };
-
- //linux has a bug with socket reuse in .net core.
- if (proxyServer.ReuseSocket && RunTime.IsWindows)
- {
- tcpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
- }
-
var hostname = useUpstreamProxy ? externalProxy.HostName : remoteHostName;
var port = useUpstreamProxy ? externalProxy.Port : remotePort;
@@ -300,6 +297,27 @@ private async Task createServerConnection(string remoteHost
{
try
{
+ var ipAddress = ipAddresses[i];
+ if (upStreamEndPoint == null)
+ {
+ tcpClient = new TcpClient(ipAddress.AddressFamily);
+ }
+ else
+ {
+ tcpClient = new TcpClient(upStreamEndPoint);
+ }
+
+ tcpClient.NoDelay = proxyServer.NoDelay;
+ tcpClient.ReceiveTimeout = proxyServer.ConnectionTimeOutSeconds * 1000;
+ tcpClient.SendTimeout = proxyServer.ConnectionTimeOutSeconds * 1000;
+ tcpClient.LingerState = new LingerOption(true, proxyServer.TcpTimeWaitSeconds);
+
+ // linux has a bug with socket reuse in .net core.
+ if (proxyServer.ReuseSocket && RunTime.IsWindows)
+ {
+ tcpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
+ }
+
await tcpClient.ConnectAsync(ipAddresses[i], port);
break;
}
@@ -365,7 +383,7 @@ private async Task createServerConnection(string remoteHost
ApplicationProtocols = applicationProtocols,
TargetHost = remoteHostName,
ClientCertificates = null,
- EnabledSslProtocols = proxyServer.SupportedSslProtocols,
+ EnabledSslProtocols = enabledSslProtocols,
CertificateRevocationCheckMode = proxyServer.CheckCertificateRevocation
};
await sslStream.AuthenticateAsClientAsync(options, cancellationToken);
@@ -380,6 +398,12 @@ private async Task createServerConnection(string remoteHost
}
}
+ catch (IOException ex) when (ex.HResult == unchecked((int)0x80131620) && retry && enabledSslProtocols >= SslProtocols.Tls11)
+ {
+ enabledSslProtocols = SslProtocols.Tls;
+ retry = false;
+ goto retry;
+ }
catch (Exception)
{
stream?.Dispose();
@@ -532,7 +556,7 @@ private async Task clearOutdatedConnections()
}
finally
{
- //cleanup every 3 seconds by default
+ // cleanup every 3 seconds by default
await Task.Delay(1000 * 3);
}
diff --git a/src/Titanium.Web.Proxy/Network/Tcp/TcpServerConnection.cs b/src/Titanium.Web.Proxy/Network/Tcp/TcpServerConnection.cs
index d14de3482..93633b92e 100644
--- a/src/Titanium.Web.Proxy/Network/Tcp/TcpServerConnection.cs
+++ b/src/Titanium.Web.Proxy/Network/Tcp/TcpServerConnection.cs
@@ -90,9 +90,9 @@ public void Dispose()
{
Task.Run(async () =>
{
- //delay calling tcp connection close()
- //so that server have enough time to call close first.
- //This way we can push tcp Time_Wait to server side when possible.
+ // delay calling tcp connection close()
+ // so that server have enough time to call close first.
+ // This way we can push tcp Time_Wait to server side when possible.
await Task.Delay(1000);
proxyServer.UpdateServerConnectionCount(false);
Stream?.Dispose();
diff --git a/src/Titanium.Web.Proxy/Network/WinAuth/Security/Common.cs b/src/Titanium.Web.Proxy/Network/WinAuth/Security/Common.cs
index 3ffbc0108..ab7c1c247 100644
--- a/src/Titanium.Web.Proxy/Network/WinAuth/Security/Common.cs
+++ b/src/Titanium.Web.Proxy/Network/WinAuth/Security/Common.cs
@@ -210,7 +210,7 @@ public void Dispose()
// int cbBuffer;
// int BufferType;
// pvBuffer;
- //What we need to do here is to grab a hold of the pvBuffer allocate by the individual
+ // What we need to do here is to grab a hold of the pvBuffer allocate by the individual
// SecBuffer and release it...
int currentOffset = index * Marshal.SizeOf(typeof(Buffer));
var secBufferpvBuffer = Marshal.ReadIntPtr(pBuffers,
diff --git a/src/Titanium.Web.Proxy/ProxyServer.cs b/src/Titanium.Web.Proxy/ProxyServer.cs
index c7c0bf5fd..26148e835 100644
--- a/src/Titanium.Web.Proxy/ProxyServer.cs
+++ b/src/Titanium.Web.Proxy/ProxyServer.cs
@@ -122,7 +122,9 @@ public ProxyServer(string rootCertificateName, string rootCertificateIssuerName,
///
private SystemProxyManager systemProxySettingsManager { get; }
- //Number of exception retries when connection pool is enabled.
+ ///
+ /// Number of exception retries when connection pool is enabled.
+ ///
private int retries => EnableConnectionPool ? MaxCachedConnections : 0;
///
@@ -266,7 +268,7 @@ public ProxyServer(string rootCertificateName, string rootCertificateIssuerName,
/// Local adapter/NIC endpoint where proxy makes request via.
/// Defaults via any IP addresses of this machine.
///
- public IPEndPoint UpStreamEndPoint { get; set; } = new IPEndPoint(IPAddress.Any, 0);
+ public IPEndPoint UpStreamEndPoint { get; set; }
///
/// A list of IpAddress and port this proxy is listening to.
@@ -660,7 +662,7 @@ private void listen(ProxyEndPoint endPoint)
{
endPoint.Listener = new TcpListener(endPoint.IpAddress, endPoint.Port);
- //linux/macOS has a bug with socket reuse in .net core.
+ // linux/macOS has a bug with socket reuse in .net core.
if (ReuseSocket && RunTime.IsWindows)
{
endPoint.Listener.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
@@ -871,13 +873,13 @@ internal void UpdateServerConnectionCount(bool increment)
///
internal async Task InvokeConnectionCreateEvent(TcpClient client, bool isClientConnection)
{
- //client connection created
+ // client connection created
if (isClientConnection && OnClientConnectionCreate != null)
{
await OnClientConnectionCreate.InvokeAsync(this, client, ExceptionFunc);
}
- //server connection created
+ // server connection created
if (!isClientConnection && OnServerConnectionCreate != null)
{
await OnServerConnectionCreate.InvokeAsync(this, client, ExceptionFunc);
diff --git a/src/Titanium.Web.Proxy/RequestHandler.cs b/src/Titanium.Web.Proxy/RequestHandler.cs
index e2d3628dd..ab3701577 100644
--- a/src/Titanium.Web.Proxy/RequestHandler.cs
+++ b/src/Titanium.Web.Proxy/RequestHandler.cs
@@ -163,7 +163,7 @@ await clientStreamWriter.WriteResponseAsync(args.HttpClient.Response,
await args.GetRequestBody(cancellationToken);
}
- //we need this to syphon out data from connection if API user changes them.
+ // we need this to syphon out data from connection if API user changes them.
request.SetOriginalHeaders();
args.TimeLine["Request Received"] = DateTime.Now;
@@ -191,7 +191,7 @@ await clientStreamWriter.WriteResponseAsync(args.HttpClient.Response,
continue;
}
- //If prefetch task is available.
+ // If prefetch task is available.
if (connection == null && prefetchTask != null)
{
try
@@ -226,11 +226,11 @@ await clientStreamWriter.WriteResponseAsync(args.HttpClient.Response,
clientConnection.NegotiatedApplicationProtocol,
cancellationToken, cancellationTokenSource);
- //update connection to latest used
+ // update connection to latest used
connection = result.LatestConnection;
closeServerConnection = !result.Continue;
- //throw if exception happened
+ // throw if exception happened
if (!result.IsSuccess)
{
throw result.Exception;
@@ -241,7 +241,7 @@ await clientStreamWriter.WriteResponseAsync(args.HttpClient.Response,
return;
}
- //user requested
+ // user requested
if (args.HttpClient.CloseServerConnection)
{
closeServerConnection = true;
@@ -304,13 +304,13 @@ private async Task handleHttpSessionRequest(string httpCmd, Session
TcpServerConnection serverConnection, SslApplicationProtocol sslApplicationProtocol,
CancellationToken cancellationToken, CancellationTokenSource cancellationTokenSource)
{
- //a connection generator task with captured parameters via closure.
+ // a connection generator task with captured parameters via closure.
Func> generator = () =>
tcpConnectionFactory.GetServerConnection(this, args, isConnect: false,
applicationProtocol: sslApplicationProtocol,
noCache: false, cancellationToken: cancellationToken);
- //for connection pool, retry fails until cache is exhausted.
+ // for connection pool, retry fails until cache is exhausted.
return await retryPolicy().ExecuteAsync(async (connection) =>
{
args.TimeLine["Connection Ready"] = DateTime.Now;
@@ -390,12 +390,12 @@ private void prepareRequestHeaders(HeaderCollection requestHeaders)
{
var supportedAcceptEncoding = new List();
- //only allow proxy supported compressions
+ // only allow proxy supported compressions
supportedAcceptEncoding.AddRange(acceptEncoding.Split(',')
.Select(x => x.Trim())
.Where(x => ProxyConstants.ProxySupportedCompressions.Contains(x)));
- //uncompressed is always supported by proxy
+ // uncompressed is always supported by proxy
supportedAcceptEncoding.Add("identity");
requestHeaders.SetOrAddHeaderValue(KnownHeaders.AcceptEncoding,
diff --git a/src/Titanium.Web.Proxy/ResponseHandler.cs b/src/Titanium.Web.Proxy/ResponseHandler.cs
index 39156f637..8e8794730 100644
--- a/src/Titanium.Web.Proxy/ResponseHandler.cs
+++ b/src/Titanium.Web.Proxy/ResponseHandler.cs
@@ -51,8 +51,8 @@ private async Task handleHttpSessionResponse(SessionEventArgs args)
}
}
- //save original values so that if user changes them
- //we can still use original values when syphoning out data from attached tcp connection.
+ // save original values so that if user changes them
+ // we can still use original values when syphoning out data from attached tcp connection.
response.SetOriginalHeaders();
// if user requested call back then do it
@@ -66,10 +66,10 @@ private async Task handleHttpSessionResponse(SessionEventArgs args)
var clientStreamWriter = args.ProxyClient.ClientStreamWriter;
- //user set custom response by ignoring original response from server.
+ // user set custom response by ignoring original response from server.
if (response.Locked)
{
- //write custom user response with body and return.
+ // write custom user response with body and return.
await clientStreamWriter.WriteResponseAsync(response, cancellationToken: cancellationToken);
if (args.HttpClient.Connection != null
diff --git a/src/Titanium.Web.Proxy/StreamExtended/ClientHelloInfo.cs b/src/Titanium.Web.Proxy/StreamExtended/ClientHelloInfo.cs
index 2ad96ae94..cbbf68058 100644
--- a/src/Titanium.Web.Proxy/StreamExtended/ClientHelloInfo.cs
+++ b/src/Titanium.Web.Proxy/StreamExtended/ClientHelloInfo.cs
@@ -1,6 +1,7 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
+using System.Security.Authentication;
using System.Text;
using Titanium.Web.Proxy.StreamExtended.Models;
@@ -51,6 +52,33 @@ public DateTime Time
public Dictionary Extensions { get; set; }
+ public SslProtocols SslProtocol
+ {
+ get
+ {
+ int major = MajorVersion;
+ int minor = MinorVersion;
+ if (major == 3 && minor == 3)
+ return SslProtocols.Tls12;
+
+ if (major == 3 && minor == 2)
+ return SslProtocols.Tls11;
+
+ if (major == 3 && minor == 1)
+ return SslProtocols.Tls;
+
+#pragma warning disable 618
+ if (major == 3 && minor == 0)
+ return SslProtocols.Ssl3;
+
+ if (major == 2 && minor == 0)
+ return SslProtocols.Ssl2;
+#pragma warning restore 618
+
+ return SslProtocols.None;
+ }
+ }
+
private static string SslVersionToString(int major, int minor)
{
string str = "Unknown";
@@ -119,4 +147,4 @@ public override string ToString()
return sb.ToString();
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Titanium.Web.Proxy/StreamExtended/Network/ClientHelloAlpnAdderStream.cs b/src/Titanium.Web.Proxy/StreamExtended/Network/ClientHelloAlpnAdderStream.cs
deleted file mode 100644
index fcb3db54e..000000000
--- a/src/Titanium.Web.Proxy/StreamExtended/Network/ClientHelloAlpnAdderStream.cs
+++ /dev/null
@@ -1,138 +0,0 @@
-using System.Diagnostics;
-using System.IO;
-using System.Threading;
-using Titanium.Web.Proxy.StreamExtended.BufferPool;
-
-namespace Titanium.Web.Proxy.StreamExtended.Network
-{
- public class ClientHelloAlpnAdderStream : Stream
- {
- private readonly CustomBufferedStream stream;
- private readonly IBufferPool bufferPool;
-
- private bool called;
-
- public ClientHelloAlpnAdderStream(CustomBufferedStream stream, IBufferPool bufferPool)
- {
- this.stream = stream;
- }
-
- public override void Flush()
- {
- stream.Flush();
- }
-
- public override long Seek(long offset, SeekOrigin origin)
- {
- return stream.Seek(offset, origin);
- }
-
- public override void SetLength(long value)
- {
- stream.SetLength(value);
- }
-
- [DebuggerStepThrough]
- public override int Read(byte[] buffer, int offset, int count)
- {
- return stream.Read(buffer, offset, count);
- }
-
- public override void Write(byte[] buffer, int offset, int count)
- {
- if (called)
- {
- stream.Write(buffer, offset, count);
- return;
- }
-
- called = true;
- var ms = new MemoryStream(buffer, offset, count);
-
- //this can be non async, because reads from a memory stream
- var cts = new CancellationTokenSource();
- var clientHello = SslTools.PeekClientHello(new CustomBufferedStream(ms, bufferPool, (int)ms.Length), bufferPool, cts.Token).Result;
- if (clientHello != null)
- {
- // 0x00 0x10: ALPN identifier
- // 0x00 0x0e: length of ALPN data
- // 0x00 0x0c: length of ALPN data again:)
- var dataToAdd = new byte[]
- {
- 0x0, 0x10, 0x0, 0xE, 0x0, 0xC,
- 2, (byte)'h', (byte)'2',
- 8, (byte)'h', (byte)'t', (byte)'t', (byte)'p', (byte)'/', (byte)'1', (byte)'.', (byte)'1'
- };
-
- int newByteCount = clientHello.Extensions == null ? dataToAdd.Length + 2 : dataToAdd.Length;
- var buffer2 = new byte[buffer.Length + newByteCount];
-
- for (int i = 0; i < buffer.Length; i++)
- {
- buffer2[i] = buffer[i];
- }
-
- //this is a hacky solution, but works
- int length = (buffer[offset + 3] << 8) + buffer[offset + 4];
- length += newByteCount;
- buffer2[offset + 3] = (byte)(length >> 8);
- buffer2[offset + 4] = (byte)length;
-
- length = (buffer[offset + 6] << 16) + (buffer[offset + 7] << 8) + buffer[offset + 8];
- length += newByteCount;
- buffer2[offset + 6] = (byte)(length >> 16);
- buffer2[offset + 7] = (byte)(length >> 8);
- buffer2[offset + 8] = (byte)length;
-
- int pos = offset + clientHello.EntensionsStartPosition;
- int endPos = offset + clientHello.ClientHelloLength;
- if (clientHello.Extensions != null)
- {
- // update ALPN length
- length = (buffer[pos] << 8) + buffer[pos + 1];
- length += newByteCount;
- buffer2[pos] = (byte)(length >> 8);
- buffer2[pos + 1] = (byte)length;
- }
- else
- {
- // add ALPN length
- length = dataToAdd.Length;
- buffer2[pos] = (byte)(length >> 8);
- buffer2[pos + 1] = (byte)length;
- endPos += 2;
- }
-
- for (int i = 0; i < dataToAdd.Length; i++)
- {
- buffer2[endPos + i] = dataToAdd[i];
- }
-
- // copy the reamining data if any
- for (int i = clientHello.ClientHelloLength; i < count; i++)
- {
- buffer2[offset + newByteCount + i] = buffer[offset + i];
- }
-
- buffer = buffer2;
- count += newByteCount;
- }
-
- stream.Write(buffer, offset, count);
- }
-
- public override bool CanRead => stream.CanRead;
-
- public override bool CanSeek => stream.CanSeek;
-
- public override bool CanWrite => stream.CanWrite;
-
- public override long Length => stream.Length;
-
- public override long Position
- {
- get => stream.Position;
- set => stream.Position = value;
- }
- }
-}
\ No newline at end of file
diff --git a/src/Titanium.Web.Proxy/StreamExtended/Network/CopyStream.cs b/src/Titanium.Web.Proxy/StreamExtended/Network/CopyStream.cs
index 08f6bf40c..025509014 100644
--- a/src/Titanium.Web.Proxy/StreamExtended/Network/CopyStream.cs
+++ b/src/Titanium.Web.Proxy/StreamExtended/Network/CopyStream.cs
@@ -63,7 +63,7 @@ public Task PeekBytesAsync(byte[] buffer, int offset, int index, int size,
public void Flush()
{
- //send out the current data from from the buffer
+ // send out the current data from from the buffer
if (bufferLength > 0)
{
writer.Write(buffer, 0, bufferLength);
@@ -73,7 +73,7 @@ public void Flush()
public async Task FlushAsync(CancellationToken cancellationToken = default)
{
- //send out the current data from from the buffer
+ // send out the current data from from the buffer
if (bufferLength > 0)
{
await writer.WriteAsync(buffer, 0, bufferLength, cancellationToken);
diff --git a/src/Titanium.Web.Proxy/StreamExtended/Network/CustomBufferedStream.cs b/src/Titanium.Web.Proxy/StreamExtended/Network/CustomBufferedStream.cs
index 2b6818f26..32e6e8879 100644
--- a/src/Titanium.Web.Proxy/StreamExtended/Network/CustomBufferedStream.cs
+++ b/src/Titanium.Web.Proxy/StreamExtended/Network/CustomBufferedStream.cs
@@ -257,13 +257,13 @@ public async Task PeekByteAsync(int index, CancellationToken cancellationTo
await FillBufferAsync(cancellationToken);
}
- //When index is greater than the buffer size
+ // When index is greater than the buffer size
if (streamBuffer.Length <= index)
{
throw new Exception("Requested Peek index exceeds the buffer size. Consider increasing the buffer size.");
}
- //When index is greater than the buffer size
+ // When index is greater than the buffer size
if (Available <= index)
{
return -1;
@@ -287,7 +287,7 @@ public async Task PeekBytesAsync(byte[] buffer, int offset, int index, int
await FillBufferAsync(cancellationToken);
}
- //When index is greater than the buffer size
+ // When index is greater than the buffer size
if (streamBuffer.Length <= (index + size))
{
throw new Exception("Requested Peek index and size exceeds the buffer size. Consider increasing the buffer size.");
@@ -477,8 +477,8 @@ public bool FillBuffer()
if (bufferLength > 0)
{
- //normally we fill the buffer only when it is empty, but sometimes we need more data
- //move the remaining data to the beginning of the buffer
+ // normally we fill the buffer only when it is empty, but sometimes we need more data
+ // move the remaining data to the beginning of the buffer
Buffer.BlockCopy(streamBuffer, bufferPos, streamBuffer, 0, bufferLength);
}
@@ -521,8 +521,8 @@ public async Task FillBufferAsync(CancellationToken cancellationToken = de
if (bufferLength > 0)
{
- //normally we fill the buffer only when it is empty, but sometimes we need more data
- //move the remaining data to the beginning of the buffer
+ // normally we fill the buffer only when it is empty, but sometimes we need more data
+ // move the remaining data to the beginning of the buffer
Buffer.BlockCopy(streamBuffer, bufferPos, streamBuffer, 0, bufferLength);
}
@@ -586,7 +586,7 @@ internal static async Task ReadLineInternalAsync(ICustomStreamReader rea
byte newChar = reader.ReadByteFromBuffer();
buffer[bufferDataLength] = newChar;
- //if new line
+ // if new line
if (newChar == '\n')
{
if (lastChar == '\r')
@@ -599,7 +599,7 @@ internal static async Task ReadLineInternalAsync(ICustomStreamReader rea
bufferDataLength++;
- //store last char for new line comparison
+ // store last char for new line comparison
lastChar = newChar;
if (bufferDataLength == buffer.Length)
@@ -663,8 +663,8 @@ public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, Asy
vAsyncResult.ContinueWith(pAsyncResult =>
{
- //use TaskExtended to pass State as AsyncObject
- //callback will call EndRead (otherwise, it will block)
+ // use TaskExtended to pass State as AsyncObject
+ // callback will call EndRead (otherwise, it will block)
callback?.Invoke(new TaskResult(pAsyncResult, state));
});
diff --git a/src/Titanium.Web.Proxy/StreamExtended/Network/ServerHelloAlpnAdderStream.cs b/src/Titanium.Web.Proxy/StreamExtended/Network/ServerHelloAlpnAdderStream.cs
deleted file mode 100644
index 26dda6c7f..000000000
--- a/src/Titanium.Web.Proxy/StreamExtended/Network/ServerHelloAlpnAdderStream.cs
+++ /dev/null
@@ -1,138 +0,0 @@
-using System.Diagnostics;
-using System.IO;
-using System.Threading;
-using Titanium.Web.Proxy.StreamExtended.BufferPool;
-
-namespace Titanium.Web.Proxy.StreamExtended.Network
-{
- public class ServerHelloAlpnAdderStream : Stream
- {
- private readonly IBufferPool bufferPool;
- private readonly CustomBufferedStream stream;
-
- private bool called;
-
- public ServerHelloAlpnAdderStream(CustomBufferedStream stream, IBufferPool bufferPool)
- {
- this.bufferPool = bufferPool;
- this.stream = stream;
- }
-
- public override void Flush()
- {
- stream.Flush();
- }
-
- public override long Seek(long offset, SeekOrigin origin)
- {
- return stream.Seek(offset, origin);
- }
-
- public override void SetLength(long value)
- {
- stream.SetLength(value);
- }
-
- [DebuggerStepThrough]
- public override int Read(byte[] buffer, int offset, int count)
- {
- return stream.Read(buffer, offset, count);
- }
-
- public override void Write(byte[] buffer, int offset, int count)
- {
- if (called)
- {
- stream.Write(buffer, offset, count);
- return;
- }
-
- called = true;
- var ms = new MemoryStream(buffer, offset, count);
-
- //this can be non async, because reads from a memory stream
- var cts = new CancellationTokenSource();
- var serverHello = SslTools.PeekServerHello(new CustomBufferedStream(ms, bufferPool, (int)ms.Length), bufferPool, cts.Token).Result;
- if (serverHello != null)
- {
- // 0x00 0x10: ALPN identifier
- // 0x00 0x0e: length of ALPN data
- // 0x00 0x0c: length of ALPN data again:)
- var dataToAdd = new byte[]
- {
- 0x0, 0x10, 0x0, 0x5, 0x0, 0x3,
- 2, (byte)'h', (byte)'2'
- };
-
- int newByteCount = serverHello.Extensions == null ? dataToAdd.Length + 2 : dataToAdd.Length;
- var buffer2 = new byte[buffer.Length + newByteCount];
-
- for (int i = 0; i < buffer.Length; i++)
- {
- buffer2[i] = buffer[i];
- }
-
- //this is a hacky solution, but works
- int length = (buffer[offset + 3] << 8) + buffer[offset + 4];
- length += newByteCount;
- buffer2[offset + 3] = (byte)(length >> 8);
- buffer2[offset + 4] = (byte)length;
-
- length = (buffer[offset + 6] << 16) + (buffer[offset + 7] << 8) + buffer[offset + 8];
- length += newByteCount;
- buffer2[offset + 6] = (byte)(length >> 16);
- buffer2[offset + 7] = (byte)(length >> 8);
- buffer2[offset + 8] = (byte)length;
-
- int pos = offset + serverHello.EntensionsStartPosition;
- int endPos = offset + serverHello.ServerHelloLength;
- if (serverHello.Extensions != null)
- {
- // update ALPN length
- length = (buffer[pos] << 8) + buffer[pos + 1];
- length += newByteCount;
- buffer2[pos] = (byte)(length >> 8);
- buffer2[pos + 1] = (byte)length;
- }
- else
- {
- // add ALPN length
- length = dataToAdd.Length;
- buffer2[pos] = (byte)(length >> 8);
- buffer2[pos + 1] = (byte)length;
- endPos += 2;
- }
-
- for (int i = 0; i < dataToAdd.Length; i++)
- {
- buffer2[endPos + i] = dataToAdd[i];
- }
-
- // copy the reamining data if any
- for (int i = serverHello.ServerHelloLength; i < count; i++)
- {
- buffer2[offset + newByteCount + i] = buffer[offset + i];
- }
-
- buffer = buffer2;
- count += newByteCount;
- }
-
- stream.Write(buffer, offset, count);
- }
-
- public override bool CanRead => stream.CanRead;
-
- public override bool CanSeek => stream.CanSeek;
-
- public override bool CanWrite => stream.CanWrite;
-
- public override long Length => stream.Length;
-
- public override long Position
- {
- get => stream.Position;
- set => stream.Position = value;
- }
- }
-}
\ No newline at end of file
diff --git a/src/Titanium.Web.Proxy/StreamExtended/SslExtensions.cs b/src/Titanium.Web.Proxy/StreamExtended/SslExtensions.cs
index c6569fdad..f8d129033 100644
--- a/src/Titanium.Web.Proxy/StreamExtended/SslExtensions.cs
+++ b/src/Titanium.Web.Proxy/StreamExtended/SslExtensions.cs
@@ -16,7 +16,7 @@ internal static SslExtension GetExtension(int value, byte[] data, int position)
private static string GetExtensionData(int value, byte[] data)
{
- //https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml
+ // https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml
switch (value)
{
case 0:
@@ -59,8 +59,8 @@ private static string GetExtensionData(int value, byte[] data)
private static string GetSupportedGroup(byte[] data)
{
- //https://datatracker.ietf.org/doc/draft-ietf-tls-rfc4492bis/?include_text=1
- List list = new List();
+ // https://datatracker.ietf.org/doc/draft-ietf-tls-rfc4492bis/?include_text=1
+ var list = new List();
if (data.Length < 2)
{
return string.Empty;
@@ -73,70 +73,70 @@ private static string GetSupportedGroup(byte[] data)
switch (namedCurve)
{
case 1:
- list.Add("sect163k1 [0x1]"); //deprecated
+ list.Add("sect163k1 [0x1]"); // deprecated
break;
case 2:
- list.Add("sect163r1 [0x2]"); //deprecated
+ list.Add("sect163r1 [0x2]"); // deprecated
break;
case 3:
- list.Add("sect163r2 [0x3]"); //deprecated
+ list.Add("sect163r2 [0x3]"); // deprecated
break;
case 4:
- list.Add("sect193r1 [0x4]"); //deprecated
+ list.Add("sect193r1 [0x4]"); // deprecated
break;
case 5:
- list.Add("sect193r2 [0x5]"); //deprecated
+ list.Add("sect193r2 [0x5]"); // deprecated
break;
case 6:
- list.Add("sect233k1 [0x6]"); //deprecated
+ list.Add("sect233k1 [0x6]"); // deprecated
break;
case 7:
- list.Add("sect233r1 [0x7]"); //deprecated
+ list.Add("sect233r1 [0x7]"); // deprecated
break;
case 8:
- list.Add("sect239k1 [0x8]"); //deprecated
+ list.Add("sect239k1 [0x8]"); // deprecated
break;
case 9:
- list.Add("sect283k1 [0x9]"); //deprecated
+ list.Add("sect283k1 [0x9]"); // deprecated
break;
case 10:
- list.Add("sect283r1 [0xA]"); //deprecated
+ list.Add("sect283r1 [0xA]"); // deprecated
break;
case 11:
- list.Add("sect409k1 [0xB]"); //deprecated
+ list.Add("sect409k1 [0xB]"); // deprecated
break;
case 12:
- list.Add("sect409r1 [0xC]"); //deprecated
+ list.Add("sect409r1 [0xC]"); // deprecated
break;
case 13:
- list.Add("sect571k1 [0xD]"); //deprecated
+ list.Add("sect571k1 [0xD]"); // deprecated
break;
case 14:
- list.Add("sect571r1 [0xE]"); //deprecated
+ list.Add("sect571r1 [0xE]"); // deprecated
break;
case 15:
- list.Add("secp160k1 [0xF]"); //deprecated
+ list.Add("secp160k1 [0xF]"); // deprecated
break;
case 16:
- list.Add("secp160r1 [0x10]"); //deprecated
+ list.Add("secp160r1 [0x10]"); // deprecated
break;
case 17:
- list.Add("secp160r2 [0x11]"); //deprecated
+ list.Add("secp160r2 [0x11]"); // deprecated
break;
case 18:
- list.Add("secp192k1 [0x12]"); //deprecated
+ list.Add("secp192k1 [0x12]"); // deprecated
break;
case 19:
- list.Add("secp192r1 [0x13]"); //deprecated
+ list.Add("secp192r1 [0x13]"); // deprecated
break;
case 20:
- list.Add("secp224k1 [0x14]"); //deprecated
+ list.Add("secp224k1 [0x14]"); // deprecated
break;
case 21:
- list.Add("secp224r1 [0x15]"); //deprecated
+ list.Add("secp224r1 [0x15]"); // deprecated
break;
case 22:
- list.Add("secp256k1 [0x16]"); //deprecated
+ list.Add("secp256k1 [0x16]"); // deprecated
break;
case 23:
list.Add("secp256r1 [0x17]");
@@ -178,10 +178,10 @@ private static string GetSupportedGroup(byte[] data)
list.Add("ffdhe8192 [0x0104]");
break;
case 65281:
- list.Add("arbitrary_explicit_prime_curves [0xFF01]"); //deprecated
+ list.Add("arbitrary_explicit_prime_curves [0xFF01]"); // deprecated
break;
case 65282:
- list.Add("arbitrary_explicit_char2_curves [0xFF02]"); //deprecated
+ list.Add("arbitrary_explicit_char2_curves [0xFF02]"); // deprecated
break;
default:
list.Add($"unknown [0x{namedCurve:X4}]");
@@ -318,7 +318,7 @@ private static string GetApplicationLayerProtocolNegotiation(byte[] data)
private static string GetExtensionName(int value)
{
- //https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml
+ // https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml
switch (value)
{
case 0:
diff --git a/src/Titanium.Web.Proxy/StreamExtended/SslTools.cs b/src/Titanium.Web.Proxy/StreamExtended/SslTools.cs
index fbe6471b5..5b6b87167 100644
--- a/src/Titanium.Web.Proxy/StreamExtended/SslTools.cs
+++ b/src/Titanium.Web.Proxy/StreamExtended/SslTools.cs
@@ -34,8 +34,8 @@ public static async Task IsClientHello(CustomBufferedStream stream, IBuffe
///
public static async Task PeekClientHello(CustomBufferedStream clientStream, IBufferPool bufferPool, CancellationToken cancellationToken = default)
{
- //detects the HTTPS ClientHello message as it is described in the following url:
- //https://stackoverflow.com/questions/3897883/how-to-detect-an-incoming-ssl-https-handshake-ssl-wire-format
+ // detects the HTTPS ClientHello message as it is described in the following url:
+ // https://stackoverflow.com/questions/3897883/how-to-detect-an-incoming-ssl-https-handshake-ssl-wire-format
int recordType = await clientStream.PeekByteAsync(0, cancellationToken);
if (recordType == -1)
@@ -45,7 +45,7 @@ public static async Task PeekClientHello(CustomBufferedStream c
if ((recordType & 0x80) == 0x80)
{
- //SSL 2
+ // SSL 2
var peekStream = new CustomBufferedPeekStream(clientStream, bufferPool, 1);
// length value + minimum length
@@ -105,14 +105,14 @@ public static async Task PeekClientHello(CustomBufferedStream c
{
var peekStream = new CustomBufferedPeekStream(clientStream, bufferPool, 1);
- //should contain at least 43 bytes
+ // should contain at least 43 bytes
// 2 version + 2 length + 1 type + 3 length(?) + 2 version + 32 random + 1 sessionid length
if (!await peekStream.EnsureBufferLength(43, cancellationToken))
{
return null;
}
- //SSL 3.0 or TLS 1.0, 1.1 and 1.2
+ // SSL 3.0 or TLS 1.0, 1.1 and 1.2
int majorVersion = peekStream.ReadByte();
int minorVersion = peekStream.ReadByte();
@@ -220,8 +220,8 @@ public static async Task IsServerHello(CustomBufferedStream stream, IBuffe
///
public static async Task PeekServerHello(CustomBufferedStream serverStream, IBufferPool bufferPool, CancellationToken cancellationToken = default)
{
- //detects the HTTPS ClientHello message as it is described in the following url:
- //https://stackoverflow.com/questions/3897883/how-to-detect-an-incoming-ssl-https-handshake-ssl-wire-format
+ // detects the HTTPS ClientHello message as it is described in the following url:
+ // https://stackoverflow.com/questions/3897883/how-to-detect-an-incoming-ssl-https-handshake-ssl-wire-format
int recordType = await serverStream.PeekByteAsync(0, cancellationToken);
if (recordType == -1)
@@ -231,7 +231,7 @@ public static async Task PeekServerHello(CustomBufferedStream s
if ((recordType & 0x80) == 0x80)
{
- //SSL 2
+ // SSL 2
// not tested. SSL2 is deprecated
var peekStream = new CustomBufferedPeekStream(serverStream, bufferPool, 1);
@@ -284,14 +284,14 @@ public static async Task PeekServerHello(CustomBufferedStream s
{
var peekStream = new CustomBufferedPeekStream(serverStream, bufferPool, 1);
- //should contain at least 43 bytes
+ // should contain at least 43 bytes
// 2 version + 2 length + 1 type + 3 length(?) + 2 version + 32 random + 1 sessionid length
if (!await peekStream.EnsureBufferLength(43, cancellationToken))
{
return null;
}
- //SSL 3.0 or TLS 1.0, 1.1 and 1.2
+ // SSL 3.0 or TLS 1.0, 1.1 and 1.2
int majorVersion = peekStream.ReadByte();
int minorVersion = peekStream.ReadByte();
diff --git a/src/Titanium.Web.Proxy/TransparentClientHandler.cs b/src/Titanium.Web.Proxy/TransparentClientHandler.cs
index 4a63772d9..9af6814fe 100644
--- a/src/Titanium.Web.Proxy/TransparentClientHandler.cs
+++ b/src/Titanium.Web.Proxy/TransparentClientHandler.cs
@@ -62,8 +62,9 @@ private async Task handleClient(TransparentProxyEndPoint endPoint, TcpClientConn
if (endPoint.DecryptSsl && args.DecryptSsl)
{
+ clientConnection.SslProtocol = clientHelloInfo.SslProtocol;
- //do client authentication using certificate
+ // do client authentication using certificate
X509Certificate2 certificate = null;
try
{
diff --git a/tests/Titanium.Web.Proxy.IntegrationTests/Setup/TestServer.cs b/tests/Titanium.Web.Proxy.IntegrationTests/Setup/TestServer.cs
index de4e6b9c9..c0eacbe23 100644
--- a/tests/Titanium.Web.Proxy.IntegrationTests/Setup/TestServer.cs
+++ b/tests/Titanium.Web.Proxy.IntegrationTests/Setup/TestServer.cs
@@ -13,7 +13,7 @@
namespace Titanium.Web.Proxy.IntegrationTests.Setup
{
- //set up a kestrel test server
+ // set up a kestrel test server
public class TestServer : IDisposable
{
public string ListeningHttpUrl => $"http://localhost:{HttpListeningPort}";