Commit 2eed8cb0 authored by Honfika's avatar Honfika

space before the commetns

parent 67c1e265
...@@ -30,7 +30,7 @@ For stable releases on [stable branch](https://github.com/justcoding121/Titanium ...@@ -30,7 +30,7 @@ For stable releases on [stable branch](https://github.com/justcoding121/Titanium
Supports Supports
* .Net Standard 2.0 or above * .Net Standard 2.0 or above
* .Net Framework 4.5 or above * .Net Framework 4.6.1 or above
### Development environment ### Development environment
...@@ -55,11 +55,11 @@ Setup HTTP proxy: ...@@ -55,11 +55,11 @@ Setup HTTP proxy:
```csharp ```csharp
var proxyServer = new ProxyServer(); var proxyServer = new ProxyServer();
//locally trust root certificate used by this proxy // locally trust root certificate used by this proxy
proxyServer.CertificateManager.TrustRootCertificate = true; proxyServer.CertificateManager.TrustRootCertificate = true;
//optionally set the Certificate Engine // optionally set the Certificate Engine
//Under Mono only BouncyCastle will be supported // Under Mono only BouncyCastle will be supported
//proxyServer.CertificateManager.CertificateEngine = Network.CertificateEngine.BouncyCastle; //proxyServer.CertificateManager.CertificateEngine = Network.CertificateEngine.BouncyCastle;
proxyServer.BeforeRequest += OnRequest; proxyServer.BeforeRequest += OnRequest;
...@@ -70,28 +70,28 @@ proxyServer.ClientCertificateSelectionCallback += OnCertificateSelection; ...@@ -70,28 +70,28 @@ proxyServer.ClientCertificateSelectionCallback += OnCertificateSelection;
var explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, 8000, true) var explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, 8000, true)
{ {
//Use self-issued generic certificate on all https requests // Use self-issued generic certificate on all https requests
//Optimizes performance by not creating a certificate for each https-enabled domain // Optimizes performance by not creating a certificate for each https-enabled domain
//Useful when certificate trust is not required by proxy clients // Useful when certificate trust is not required by proxy clients
//GenericCertificate = new X509Certificate2(Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "genericcert.pfx"), "password") //GenericCertificate = new X509Certificate2(Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "genericcert.pfx"), "password")
}; };
//Fired when a CONNECT request is received // Fired when a CONNECT request is received
explicitEndPoint.BeforeTunnelConnect += OnBeforeTunnelConnect; explicitEndPoint.BeforeTunnelConnect += OnBeforeTunnelConnect;
//An explicit endpoint is where the client knows about the existence of a proxy // An explicit endpoint is where the client knows about the existence of a proxy
//So client sends request in a proxy friendly manner // So client sends request in a proxy friendly manner
proxyServer.AddEndPoint(explicitEndPoint); proxyServer.AddEndPoint(explicitEndPoint);
proxyServer.Start(); proxyServer.Start();
//Transparent endpoint is useful for reverse proxy (client is not aware of the existence of proxy) // Transparent endpoint is useful for reverse proxy (client is not aware of the existence of proxy)
//A transparent endpoint usually requires a network router port forwarding HTTP(S) packets or DNS // A transparent endpoint usually requires a network router port forwarding HTTP(S) packets or DNS
//to send data to this endPoint // to send data to this endPoint
var transparentEndPoint = new TransparentProxyEndPoint(IPAddress.Any, 8001, true) var transparentEndPoint = new TransparentProxyEndPoint(IPAddress.Any, 8001, true)
{ {
//Generic Certificate hostname to use // Generic Certificate hostname to use
//when SNI is disabled by client // when SNI is disabled by client
GenericCertificateName = "google.com" GenericCertificateName = "google.com"
}; };
proxyServer.AddEndPoint(transparentEndPoint); proxyServer.AddEndPoint(transparentEndPoint);
...@@ -103,14 +103,14 @@ foreach (var endPoint in proxyServer.ProxyEndPoints) ...@@ -103,14 +103,14 @@ foreach (var endPoint in proxyServer.ProxyEndPoints)
Console.WriteLine("Listening on '{0}' endpoint at Ip {1} and port: {2} ", Console.WriteLine("Listening on '{0}' endpoint at Ip {1} and port: {2} ",
endPoint.GetType().Name, endPoint.IpAddress, endPoint.Port); endPoint.GetType().Name, endPoint.IpAddress, endPoint.Port);
//Only explicit proxies can be set as system proxy! // Only explicit proxies can be set as system proxy!
proxyServer.SetAsSystemHttpProxy(explicitEndPoint); proxyServer.SetAsSystemHttpProxy(explicitEndPoint);
proxyServer.SetAsSystemHttpsProxy(explicitEndPoint); proxyServer.SetAsSystemHttpsProxy(explicitEndPoint);
//wait here (You can use something else as a wait function, I am using this as a demo) // wait here (You can use something else as a wait function, I am using this as a demo)
Console.Read(); Console.Read();
//Unsubscribe & Quit // Unsubscribe & Quit
explicitEndPoint.BeforeTunnelConnect -= OnBeforeTunnelConnect; explicitEndPoint.BeforeTunnelConnect -= OnBeforeTunnelConnect;
proxyServer.BeforeRequest -= OnRequest; proxyServer.BeforeRequest -= OnRequest;
proxyServer.BeforeResponse -= OnResponse; proxyServer.BeforeResponse -= OnResponse;
...@@ -118,11 +118,11 @@ proxyServer.ServerCertificateValidationCallback -= OnCertificateValidation; ...@@ -118,11 +118,11 @@ proxyServer.ServerCertificateValidationCallback -= OnCertificateValidation;
proxyServer.ClientCertificateSelectionCallback -= OnCertificateSelection; proxyServer.ClientCertificateSelectionCallback -= OnCertificateSelection;
proxyServer.Stop(); proxyServer.Stop();
``` ```
Sample request and response event handlers Sample request and response event handlers
```csharp ```csharp
private async Task OnBeforeTunnelConnectRequest(object sender, TunnelConnectSessionEventArgs e) private async Task OnBeforeTunnelConnectRequest(object sender, TunnelConnectSessionEventArgs e)
{ {
...@@ -130,9 +130,9 @@ private async Task OnBeforeTunnelConnectRequest(object sender, TunnelConnectSess ...@@ -130,9 +130,9 @@ private async Task OnBeforeTunnelConnectRequest(object sender, TunnelConnectSess
if (hostname.Contains("dropbox.com")) if (hostname.Contains("dropbox.com"))
{ {
//Exclude Https addresses you don't want to proxy // Exclude Https addresses you don't want to proxy
//Useful for clients that use certificate pinning // Useful for clients that use certificate pinning
//for example dropbox.com // for example dropbox.com
e.DecryptSsl = false; e.DecryptSsl = false;
} }
} }
...@@ -141,88 +141,88 @@ public async Task OnRequest(object sender, SessionEventArgs e) ...@@ -141,88 +141,88 @@ public async Task OnRequest(object sender, SessionEventArgs e)
{ {
Console.WriteLine(e.HttpClient.Request.Url); Console.WriteLine(e.HttpClient.Request.Url);
////read request headers // read request headers
var requestHeaders = e.HttpClient.Request.RequestHeaders; var requestHeaders = e.HttpClient.Request.RequestHeaders;
var method = e.HttpClient.Request.Method.ToUpper(); var method = e.HttpClient.Request.Method.ToUpper();
if ((method == "POST" || method == "PUT" || method == "PATCH")) if ((method == "POST" || method == "PUT" || method == "PATCH"))
{ {
//Get/Set request body bytes // Get/Set request body bytes
byte[] bodyBytes = await e.GetRequestBody(); byte[] bodyBytes = await e.GetRequestBody();
await e.SetRequestBody(bodyBytes); await e.SetRequestBody(bodyBytes);
//Get/Set request body as string // Get/Set request body as string
string bodyString = await e.GetRequestBodyAsString(); string bodyString = await e.GetRequestBodyAsString();
await e.SetRequestBodyString(bodyString); await e.SetRequestBodyString(bodyString);
//store request // store request
//so that you can find it from response handler // so that you can find it from response handler
e.UserData = e.HttpClient.Request; e.UserData = e.HttpClient.Request;
} }
//To cancel a request with a custom HTML content // To cancel a request with a custom HTML content
//Filter URL // Filter URL
if (e.HttpClient.Request.RequestUri.AbsoluteUri.Contains("google.com")) if (e.HttpClient.Request.RequestUri.AbsoluteUri.Contains("google.com"))
{ {
e.Ok("<!DOCTYPE html>" + e.Ok("<!DOCTYPE html>" +
"<html><body><h1>" + "<html><body><h1>" +
"Website Blocked" + "Website Blocked" +
"</h1>" + "</h1>" +
"<p>Blocked by titanium web proxy.</p>" + "<p>Blocked by titanium web proxy.</p>" +
"</body>" + "</body>" +
"</html>"); "</html>");
} }
//Redirect example
// Redirect example
if (e.HttpClient.Request.RequestUri.AbsoluteUri.Contains("wikipedia.org")) if (e.HttpClient.Request.RequestUri.AbsoluteUri.Contains("wikipedia.org"))
{ {
e.Redirect("https://www.paypal.com"); e.Redirect("https://www.paypal.com");
} }
} }
//Modify response // Modify response
public async Task OnResponse(object sender, SessionEventArgs e) public async Task OnResponse(object sender, SessionEventArgs e)
{ {
//read response headers // read response headers
var responseHeaders = e.HttpClient.Response.ResponseHeaders; var responseHeaders = e.HttpClient.Response.ResponseHeaders;
//if (!e.ProxySession.Request.Host.Equals("medeczane.sgk.gov.tr")) return; //if (!e.ProxySession.Request.Host.Equals("medeczane.sgk.gov.tr")) return;
if (e.HttpClient.Request.Method == "GET" || e.HttpClient.Request.Method == "POST") if (e.HttpClient.Request.Method == "GET" || e.HttpClient.Request.Method == "POST")
{ {
if (e.HttpClient.Response.ResponseStatusCode == "200") if (e.HttpClient.Response.ResponseStatusCode == "200")
{ {
if (e.HttpClient.Response.ContentType!=null && e.HttpClient.Response.ContentType.Trim().ToLower().Contains("text/html")) if (e.HttpClient.Response.ContentType!=null && e.HttpClient.Response.ContentType.Trim().ToLower().Contains("text/html"))
{ {
byte[] bodyBytes = await e.GetResponseBody(); byte[] bodyBytes = await e.GetResponseBody();
await e.SetResponseBody(bodyBytes); await e.SetResponseBody(bodyBytes);
string body = await e.GetResponseBodyAsString(); string body = await e.GetResponseBodyAsString();
await e.SetResponseBodyString(body); await e.SetResponseBodyString(body);
} }
} }
} }
if(e.UserData!=null) if (e.UserData!=null)
{ {
//access request from UserData property where we stored it in RequestHandler // access request from UserData property where we stored it in RequestHandler
var request = (Request)e.UserData; var request = (Request)e.UserData;
} }
} }
/// Allows overriding default certificate validation logic // Allows overriding default certificate validation logic
public Task OnCertificateValidation(object sender, CertificateValidationEventArgs e) public Task OnCertificateValidation(object sender, CertificateValidationEventArgs e)
{ {
//set IsValid to true/false based on Certificate Errors // set IsValid to true/false based on Certificate Errors
if (e.SslPolicyErrors == System.Net.Security.SslPolicyErrors.None) if (e.SslPolicyErrors == System.Net.Security.SslPolicyErrors.None)
e.IsValid = true; e.IsValid = true;
return Task.FromResult(0); return Task.FromResult(0);
} }
/// Allows overriding default client certificate selection logic during mutual authentication // Allows overriding default client certificate selection logic during mutual authentication
public Task OnCertificateSelection(object sender, CertificateSelectionEventArgs e) public Task OnCertificateSelection(object sender, CertificateSelectionEventArgs e)
{ {
//set e.clientCertificate to override // set e.clientCertificate to override
return Task.FromResult(0); return Task.FromResult(0);
} }
``` ```
......
...@@ -193,7 +193,7 @@ namespace Titanium.Web.Proxy.Examples.Basic ...@@ -193,7 +193,7 @@ namespace Titanium.Web.Proxy.Examples.Basic
string ext = System.IO.Path.GetExtension(e.HttpClient.Request.RequestUri.AbsolutePath); 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; //var userData = e.HttpClient.UserData as CustomUserData;
//if (ext == ".gif" || ext == ".png" || ext == ".jpg") //if (ext == ".gif" || ext == ".png" || ext == ".jpg")
......
...@@ -615,36 +615,36 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -615,36 +615,36 @@ namespace Titanium.Web.Proxy.EventArguments
/// <param name="closeServerConnection">Close the server connection used by request if any?</param> /// <param name="closeServerConnection">Close the server connection used by request if any?</param>
public void Respond(Response response, bool closeServerConnection = false) 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) 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) if (HttpClient.Response.Locked)
{ {
throw new Exception("You cannot call this function after response is sent to the client."); throw new Exception("You cannot call this function after response is sent to the client.");
} }
//cleanup original response. // cleanup original response.
if (closeServerConnection) if (closeServerConnection)
{ {
//no need to cleanup original connection. // no need to cleanup original connection.
//it will be closed any way. // it will be closed any way.
TerminateServerConnection(); TerminateServerConnection();
} }
response.SetOriginalHeaders(HttpClient.Response); 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 = response;
HttpClient.Response.Locked = true; 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 else
{ {
HttpClient.Request.Locked = true; HttpClient.Request.Locked = true;
HttpClient.Request.CancelRequest = true; HttpClient.Request.CancelRequest = true;
//set new response. // set new response.
HttpClient.Response = response; HttpClient.Response = response;
HttpClient.Response.Locked = true; HttpClient.Response.Locked = true;
} }
......
...@@ -152,7 +152,8 @@ namespace Titanium.Web.Proxy ...@@ -152,7 +152,8 @@ namespace Titanium.Web.Proxy
http2Supported = connection.NegotiatedApplicationProtocol == http2Supported = connection.NegotiatedApplicationProtocol ==
SslApplicationProtocol.Http2; 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); await tcpConnectionFactory.Release(connection, true);
} }
catch (Exception) catch (Exception)
......
...@@ -50,11 +50,11 @@ namespace Titanium.Web.Proxy.Extensions ...@@ -50,11 +50,11 @@ namespace Titanium.Web.Proxy.Extensions
socket.Blocking = false; socket.Blocking = false;
socket.Send(tmp, 0, 0); socket.Send(tmp, 0, 0);
//Connected. // Connected.
} }
catch catch
{ {
//Should we let 10035 == WSAEWOULDBLOCK as valid connection? // Should we let 10035 == WSAEWOULDBLOCK as valid connection?
return false; return false;
} }
finally finally
......
...@@ -41,7 +41,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -41,7 +41,7 @@ namespace Titanium.Web.Proxy.Helpers
return true; return true;
} }
//if hostname matches local host name // if hostname matches local host name
if (hostName.Equals(localhostName, StringComparison.OrdinalIgnoreCase)) if (hostName.Equals(localhostName, StringComparison.OrdinalIgnoreCase))
{ {
return true; return true;
......
...@@ -42,7 +42,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -42,7 +42,7 @@ namespace Titanium.Web.Proxy.Helpers
public static bool IsMac => isRunningOnMac; 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 private class UwpHelper
{ {
const long APPMODEL_ERROR_NO_PACKAGE = 15700L; const long APPMODEL_ERROR_NO_PACKAGE = 15700L;
......
...@@ -37,10 +37,10 @@ namespace Titanium.Web.Proxy.Network ...@@ -37,10 +37,10 @@ namespace Titanium.Web.Proxy.Network
{ {
try try
{ {
//setup connection // setup connection
currentConnection = currentConnection as TcpServerConnection ?? currentConnection = currentConnection as TcpServerConnection ??
await generator(); await generator();
//try // try
@continue = await action(currentConnection); @continue = await action(currentConnection);
} }
...@@ -65,12 +65,12 @@ namespace Titanium.Web.Proxy.Network ...@@ -65,12 +65,12 @@ namespace Titanium.Web.Proxy.Network
return new RetryResult(currentConnection, exception, @continue); return new RetryResult(currentConnection, exception, @continue);
} }
//before retry clear connection // before retry clear connection
private async Task disposeConnection() private async Task disposeConnection()
{ {
if (currentConnection != null) if (currentConnection != null)
{ {
//close connection on error // close connection on error
await tcpConnectionFactory.Release(currentConnection, true); await tcpConnectionFactory.Release(currentConnection, true);
currentConnection = null; currentConnection = null;
} }
......
...@@ -82,9 +82,9 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -82,9 +82,9 @@ namespace Titanium.Web.Proxy.Network.Tcp
{ {
Task.Run(async () => Task.Run(async () =>
{ {
//delay calling tcp connection close() // delay calling tcp connection close()
//so that client have enough time to call close first. // so that client have enough time to call close first.
//This way we can push tcp Time_Wait to client side when possible. // This way we can push tcp Time_Wait to client side when possible.
await Task.Delay(1000); await Task.Delay(1000);
proxyServer.UpdateClientConnectionCount(false); proxyServer.UpdateClientConnectionCount(false);
tcpClient.CloseSocket(); tcpClient.CloseSocket();
......
...@@ -25,15 +25,15 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -25,15 +25,15 @@ namespace Titanium.Web.Proxy.Network.Tcp
internal class TcpConnectionFactory : IDisposable internal class TcpConnectionFactory : IDisposable
{ {
//Tcp server connection pool cache // Tcp server connection pool cache
private readonly ConcurrentDictionary<string, ConcurrentQueue<TcpServerConnection>> cache private readonly ConcurrentDictionary<string, ConcurrentQueue<TcpServerConnection>> cache
= new ConcurrentDictionary<string, ConcurrentQueue<TcpServerConnection>>(); = new ConcurrentDictionary<string, ConcurrentQueue<TcpServerConnection>>();
//Tcp connections waiting to be disposed by cleanup task // Tcp connections waiting to be disposed by cleanup task
private readonly ConcurrentBag<TcpServerConnection> disposalBag = private readonly ConcurrentBag<TcpServerConnection> disposalBag =
new ConcurrentBag<TcpServerConnection>(); new ConcurrentBag<TcpServerConnection>();
//cache object race operations lock // cache object race operations lock
private readonly SemaphoreSlim @lock = new SemaphoreSlim(1); private readonly SemaphoreSlim @lock = new SemaphoreSlim(1);
private volatile bool runCleanUpTask = true; private volatile bool runCleanUpTask = true;
...@@ -55,7 +55,7 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -55,7 +55,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
// That can create cache miss for same server connection unnecessarily especially when prefetching with Connect. // 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 2 is separated using applicationProtocols below.
var cacheKeyBuilder = new StringBuilder($"{remoteHostName}-{remotePort}-" + var cacheKeyBuilder = new StringBuilder($"{remoteHostName}-{remotePort}-" +
//when creating Tcp client isConnect won't matter // when creating Tcp client isConnect won't matter
$"{isHttps}-"); $"{isHttps}-");
if (applicationProtocols != null) if (applicationProtocols != null)
{ {
...@@ -238,7 +238,7 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -238,7 +238,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
ProxyServer proxyServer, SessionEventArgsBase session, IPEndPoint upStreamEndPoint, ExternalProxy externalProxy, ProxyServer proxyServer, SessionEventArgsBase session, IPEndPoint upStreamEndPoint, ExternalProxy externalProxy,
CancellationToken cancellationToken) 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) if (Server.ProxyEndPoints.Any(x => x.Port == remotePort)
&& NetworkHelper.IsLocalIpAddress(remoteHostName)) && NetworkHelper.IsLocalIpAddress(remoteHostName))
{ {
...@@ -288,7 +288,7 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -288,7 +288,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
LingerState = new LingerOption(true, proxyServer.TcpTimeWaitSeconds) LingerState = new LingerOption(true, proxyServer.TcpTimeWaitSeconds)
}; };
//linux has a bug with socket reuse in .net core. // linux has a bug with socket reuse in .net core.
if (proxyServer.ReuseSocket && RunTime.IsWindows) if (proxyServer.ReuseSocket && RunTime.IsWindows)
{ {
tcpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); tcpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
...@@ -550,7 +550,7 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -550,7 +550,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
} }
finally finally
{ {
//cleanup every 3 seconds by default // cleanup every 3 seconds by default
await Task.Delay(1000 * 3); await Task.Delay(1000 * 3);
} }
......
...@@ -90,9 +90,9 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -90,9 +90,9 @@ namespace Titanium.Web.Proxy.Network.Tcp
{ {
Task.Run(async () => Task.Run(async () =>
{ {
//delay calling tcp connection close() // delay calling tcp connection close()
//so that server have enough time to call close first. // so that server have enough time to call close first.
//This way we can push tcp Time_Wait to server side when possible. // This way we can push tcp Time_Wait to server side when possible.
await Task.Delay(1000); await Task.Delay(1000);
proxyServer.UpdateServerConnectionCount(false); proxyServer.UpdateServerConnectionCount(false);
Stream?.Dispose(); Stream?.Dispose();
......
...@@ -210,7 +210,7 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security ...@@ -210,7 +210,7 @@ namespace Titanium.Web.Proxy.Network.WinAuth.Security
// int cbBuffer; // int cbBuffer;
// int BufferType; // int BufferType;
// pvBuffer; // 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... // SecBuffer and release it...
int currentOffset = index * Marshal.SizeOf(typeof(Buffer)); int currentOffset = index * Marshal.SizeOf(typeof(Buffer));
var secBufferpvBuffer = Marshal.ReadIntPtr(pBuffers, var secBufferpvBuffer = Marshal.ReadIntPtr(pBuffers,
......
...@@ -122,7 +122,9 @@ namespace Titanium.Web.Proxy ...@@ -122,7 +122,9 @@ namespace Titanium.Web.Proxy
/// </summary> /// </summary>
private SystemProxyManager systemProxySettingsManager { get; } private SystemProxyManager systemProxySettingsManager { get; }
//Number of exception retries when connection pool is enabled. /// <summary>
/// Number of exception retries when connection pool is enabled.
/// </summary>
private int retries => EnableConnectionPool ? MaxCachedConnections : 0; private int retries => EnableConnectionPool ? MaxCachedConnections : 0;
/// <summary> /// <summary>
...@@ -660,7 +662,7 @@ namespace Titanium.Web.Proxy ...@@ -660,7 +662,7 @@ namespace Titanium.Web.Proxy
{ {
endPoint.Listener = new TcpListener(endPoint.IpAddress, endPoint.Port); 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) if (ReuseSocket && RunTime.IsWindows)
{ {
endPoint.Listener.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); endPoint.Listener.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
...@@ -871,13 +873,13 @@ namespace Titanium.Web.Proxy ...@@ -871,13 +873,13 @@ namespace Titanium.Web.Proxy
/// <returns></returns> /// <returns></returns>
internal async Task InvokeConnectionCreateEvent(TcpClient client, bool isClientConnection) internal async Task InvokeConnectionCreateEvent(TcpClient client, bool isClientConnection)
{ {
//client connection created // client connection created
if (isClientConnection && OnClientConnectionCreate != null) if (isClientConnection && OnClientConnectionCreate != null)
{ {
await OnClientConnectionCreate.InvokeAsync(this, client, ExceptionFunc); await OnClientConnectionCreate.InvokeAsync(this, client, ExceptionFunc);
} }
//server connection created // server connection created
if (!isClientConnection && OnServerConnectionCreate != null) if (!isClientConnection && OnServerConnectionCreate != null)
{ {
await OnServerConnectionCreate.InvokeAsync(this, client, ExceptionFunc); await OnServerConnectionCreate.InvokeAsync(this, client, ExceptionFunc);
......
...@@ -163,7 +163,7 @@ namespace Titanium.Web.Proxy ...@@ -163,7 +163,7 @@ namespace Titanium.Web.Proxy
await args.GetRequestBody(cancellationToken); 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(); request.SetOriginalHeaders();
args.TimeLine["Request Received"] = DateTime.Now; args.TimeLine["Request Received"] = DateTime.Now;
...@@ -191,7 +191,7 @@ namespace Titanium.Web.Proxy ...@@ -191,7 +191,7 @@ namespace Titanium.Web.Proxy
continue; continue;
} }
//If prefetch task is available. // If prefetch task is available.
if (connection == null && prefetchTask != null) if (connection == null && prefetchTask != null)
{ {
try try
...@@ -226,11 +226,11 @@ namespace Titanium.Web.Proxy ...@@ -226,11 +226,11 @@ namespace Titanium.Web.Proxy
clientConnection.NegotiatedApplicationProtocol, clientConnection.NegotiatedApplicationProtocol,
cancellationToken, cancellationTokenSource); cancellationToken, cancellationTokenSource);
//update connection to latest used // update connection to latest used
connection = result.LatestConnection; connection = result.LatestConnection;
closeServerConnection = !result.Continue; closeServerConnection = !result.Continue;
//throw if exception happened // throw if exception happened
if (!result.IsSuccess) if (!result.IsSuccess)
{ {
throw result.Exception; throw result.Exception;
...@@ -241,7 +241,7 @@ namespace Titanium.Web.Proxy ...@@ -241,7 +241,7 @@ namespace Titanium.Web.Proxy
return; return;
} }
//user requested // user requested
if (args.HttpClient.CloseServerConnection) if (args.HttpClient.CloseServerConnection)
{ {
closeServerConnection = true; closeServerConnection = true;
...@@ -304,13 +304,13 @@ namespace Titanium.Web.Proxy ...@@ -304,13 +304,13 @@ namespace Titanium.Web.Proxy
TcpServerConnection serverConnection, SslApplicationProtocol sslApplicationProtocol, TcpServerConnection serverConnection, SslApplicationProtocol sslApplicationProtocol,
CancellationToken cancellationToken, CancellationTokenSource cancellationTokenSource) CancellationToken cancellationToken, CancellationTokenSource cancellationTokenSource)
{ {
//a connection generator task with captured parameters via closure. // a connection generator task with captured parameters via closure.
Func<Task<TcpServerConnection>> generator = () => Func<Task<TcpServerConnection>> generator = () =>
tcpConnectionFactory.GetServerConnection(this, args, isConnect: false, tcpConnectionFactory.GetServerConnection(this, args, isConnect: false,
applicationProtocol: sslApplicationProtocol, applicationProtocol: sslApplicationProtocol,
noCache: false, cancellationToken: cancellationToken); 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<ServerConnectionException>().ExecuteAsync(async (connection) => return await retryPolicy<ServerConnectionException>().ExecuteAsync(async (connection) =>
{ {
args.TimeLine["Connection Ready"] = DateTime.Now; args.TimeLine["Connection Ready"] = DateTime.Now;
...@@ -390,12 +390,12 @@ namespace Titanium.Web.Proxy ...@@ -390,12 +390,12 @@ namespace Titanium.Web.Proxy
{ {
var supportedAcceptEncoding = new List<string>(); var supportedAcceptEncoding = new List<string>();
//only allow proxy supported compressions // only allow proxy supported compressions
supportedAcceptEncoding.AddRange(acceptEncoding.Split(',') supportedAcceptEncoding.AddRange(acceptEncoding.Split(',')
.Select(x => x.Trim()) .Select(x => x.Trim())
.Where(x => ProxyConstants.ProxySupportedCompressions.Contains(x))); .Where(x => ProxyConstants.ProxySupportedCompressions.Contains(x)));
//uncompressed is always supported by proxy // uncompressed is always supported by proxy
supportedAcceptEncoding.Add("identity"); supportedAcceptEncoding.Add("identity");
requestHeaders.SetOrAddHeaderValue(KnownHeaders.AcceptEncoding, requestHeaders.SetOrAddHeaderValue(KnownHeaders.AcceptEncoding,
......
...@@ -51,8 +51,8 @@ namespace Titanium.Web.Proxy ...@@ -51,8 +51,8 @@ namespace Titanium.Web.Proxy
} }
} }
//save original values so that if user changes them // save original values so that if user changes them
//we can still use original values when syphoning out data from attached tcp connection. // we can still use original values when syphoning out data from attached tcp connection.
response.SetOriginalHeaders(); response.SetOriginalHeaders();
// if user requested call back then do it // if user requested call back then do it
...@@ -66,10 +66,10 @@ namespace Titanium.Web.Proxy ...@@ -66,10 +66,10 @@ namespace Titanium.Web.Proxy
var clientStreamWriter = args.ProxyClient.ClientStreamWriter; 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) 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); await clientStreamWriter.WriteResponseAsync(response, cancellationToken: cancellationToken);
if (args.HttpClient.Connection != null if (args.HttpClient.Connection != null
......
...@@ -63,7 +63,7 @@ namespace Titanium.Web.Proxy.StreamExtended.Network ...@@ -63,7 +63,7 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
public void Flush() public void Flush()
{ {
//send out the current data from from the buffer // send out the current data from from the buffer
if (bufferLength > 0) if (bufferLength > 0)
{ {
writer.Write(buffer, 0, bufferLength); writer.Write(buffer, 0, bufferLength);
...@@ -73,7 +73,7 @@ namespace Titanium.Web.Proxy.StreamExtended.Network ...@@ -73,7 +73,7 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
public async Task FlushAsync(CancellationToken cancellationToken = default) 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) if (bufferLength > 0)
{ {
await writer.WriteAsync(buffer, 0, bufferLength, cancellationToken); await writer.WriteAsync(buffer, 0, bufferLength, cancellationToken);
......
...@@ -257,13 +257,13 @@ namespace Titanium.Web.Proxy.StreamExtended.Network ...@@ -257,13 +257,13 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
await FillBufferAsync(cancellationToken); await FillBufferAsync(cancellationToken);
} }
//When index is greater than the buffer size // When index is greater than the buffer size
if (streamBuffer.Length <= index) if (streamBuffer.Length <= index)
{ {
throw new Exception("Requested Peek index exceeds the buffer size. Consider increasing the buffer size."); 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) if (Available <= index)
{ {
return -1; return -1;
...@@ -287,7 +287,7 @@ namespace Titanium.Web.Proxy.StreamExtended.Network ...@@ -287,7 +287,7 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
await FillBufferAsync(cancellationToken); await FillBufferAsync(cancellationToken);
} }
//When index is greater than the buffer size // When index is greater than the buffer size
if (streamBuffer.Length <= (index + size)) if (streamBuffer.Length <= (index + size))
{ {
throw new Exception("Requested Peek index and size exceeds the buffer size. Consider increasing the buffer size."); throw new Exception("Requested Peek index and size exceeds the buffer size. Consider increasing the buffer size.");
...@@ -477,8 +477,8 @@ namespace Titanium.Web.Proxy.StreamExtended.Network ...@@ -477,8 +477,8 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
if (bufferLength > 0) if (bufferLength > 0)
{ {
//normally we fill the buffer only when it is empty, but sometimes we need more data // 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 // move the remaining data to the beginning of the buffer
Buffer.BlockCopy(streamBuffer, bufferPos, streamBuffer, 0, bufferLength); Buffer.BlockCopy(streamBuffer, bufferPos, streamBuffer, 0, bufferLength);
} }
...@@ -521,8 +521,8 @@ namespace Titanium.Web.Proxy.StreamExtended.Network ...@@ -521,8 +521,8 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
if (bufferLength > 0) if (bufferLength > 0)
{ {
//normally we fill the buffer only when it is empty, but sometimes we need more data // 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 // move the remaining data to the beginning of the buffer
Buffer.BlockCopy(streamBuffer, bufferPos, streamBuffer, 0, bufferLength); Buffer.BlockCopy(streamBuffer, bufferPos, streamBuffer, 0, bufferLength);
} }
...@@ -586,7 +586,7 @@ namespace Titanium.Web.Proxy.StreamExtended.Network ...@@ -586,7 +586,7 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
byte newChar = reader.ReadByteFromBuffer(); byte newChar = reader.ReadByteFromBuffer();
buffer[bufferDataLength] = newChar; buffer[bufferDataLength] = newChar;
//if new line // if new line
if (newChar == '\n') if (newChar == '\n')
{ {
if (lastChar == '\r') if (lastChar == '\r')
...@@ -599,7 +599,7 @@ namespace Titanium.Web.Proxy.StreamExtended.Network ...@@ -599,7 +599,7 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
bufferDataLength++; bufferDataLength++;
//store last char for new line comparison // store last char for new line comparison
lastChar = newChar; lastChar = newChar;
if (bufferDataLength == buffer.Length) if (bufferDataLength == buffer.Length)
...@@ -663,8 +663,8 @@ namespace Titanium.Web.Proxy.StreamExtended.Network ...@@ -663,8 +663,8 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
vAsyncResult.ContinueWith(pAsyncResult => vAsyncResult.ContinueWith(pAsyncResult =>
{ {
//use TaskExtended to pass State as AsyncObject // use TaskExtended to pass State as AsyncObject
//callback will call EndRead (otherwise, it will block) // callback will call EndRead (otherwise, it will block)
callback?.Invoke(new TaskResult<int>(pAsyncResult, state)); callback?.Invoke(new TaskResult<int>(pAsyncResult, state));
}); });
......
...@@ -16,7 +16,7 @@ namespace Titanium.Web.Proxy.StreamExtended ...@@ -16,7 +16,7 @@ namespace Titanium.Web.Proxy.StreamExtended
private static string GetExtensionData(int value, byte[] data) 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) switch (value)
{ {
case 0: case 0:
...@@ -59,8 +59,8 @@ namespace Titanium.Web.Proxy.StreamExtended ...@@ -59,8 +59,8 @@ namespace Titanium.Web.Proxy.StreamExtended
private static string GetSupportedGroup(byte[] data) private static string GetSupportedGroup(byte[] data)
{ {
//https://datatracker.ietf.org/doc/draft-ietf-tls-rfc4492bis/?include_text=1 // https://datatracker.ietf.org/doc/draft-ietf-tls-rfc4492bis/?include_text=1
List<string> list = new List<string>(); var list = new List<string>();
if (data.Length < 2) if (data.Length < 2)
{ {
return string.Empty; return string.Empty;
...@@ -73,70 +73,70 @@ namespace Titanium.Web.Proxy.StreamExtended ...@@ -73,70 +73,70 @@ namespace Titanium.Web.Proxy.StreamExtended
switch (namedCurve) switch (namedCurve)
{ {
case 1: case 1:
list.Add("sect163k1 [0x1]"); //deprecated list.Add("sect163k1 [0x1]"); // deprecated
break; break;
case 2: case 2:
list.Add("sect163r1 [0x2]"); //deprecated list.Add("sect163r1 [0x2]"); // deprecated
break; break;
case 3: case 3:
list.Add("sect163r2 [0x3]"); //deprecated list.Add("sect163r2 [0x3]"); // deprecated
break; break;
case 4: case 4:
list.Add("sect193r1 [0x4]"); //deprecated list.Add("sect193r1 [0x4]"); // deprecated
break; break;
case 5: case 5:
list.Add("sect193r2 [0x5]"); //deprecated list.Add("sect193r2 [0x5]"); // deprecated
break; break;
case 6: case 6:
list.Add("sect233k1 [0x6]"); //deprecated list.Add("sect233k1 [0x6]"); // deprecated
break; break;
case 7: case 7:
list.Add("sect233r1 [0x7]"); //deprecated list.Add("sect233r1 [0x7]"); // deprecated
break; break;
case 8: case 8:
list.Add("sect239k1 [0x8]"); //deprecated list.Add("sect239k1 [0x8]"); // deprecated
break; break;
case 9: case 9:
list.Add("sect283k1 [0x9]"); //deprecated list.Add("sect283k1 [0x9]"); // deprecated
break; break;
case 10: case 10:
list.Add("sect283r1 [0xA]"); //deprecated list.Add("sect283r1 [0xA]"); // deprecated
break; break;
case 11: case 11:
list.Add("sect409k1 [0xB]"); //deprecated list.Add("sect409k1 [0xB]"); // deprecated
break; break;
case 12: case 12:
list.Add("sect409r1 [0xC]"); //deprecated list.Add("sect409r1 [0xC]"); // deprecated
break; break;
case 13: case 13:
list.Add("sect571k1 [0xD]"); //deprecated list.Add("sect571k1 [0xD]"); // deprecated
break; break;
case 14: case 14:
list.Add("sect571r1 [0xE]"); //deprecated list.Add("sect571r1 [0xE]"); // deprecated
break; break;
case 15: case 15:
list.Add("secp160k1 [0xF]"); //deprecated list.Add("secp160k1 [0xF]"); // deprecated
break; break;
case 16: case 16:
list.Add("secp160r1 [0x10]"); //deprecated list.Add("secp160r1 [0x10]"); // deprecated
break; break;
case 17: case 17:
list.Add("secp160r2 [0x11]"); //deprecated list.Add("secp160r2 [0x11]"); // deprecated
break; break;
case 18: case 18:
list.Add("secp192k1 [0x12]"); //deprecated list.Add("secp192k1 [0x12]"); // deprecated
break; break;
case 19: case 19:
list.Add("secp192r1 [0x13]"); //deprecated list.Add("secp192r1 [0x13]"); // deprecated
break; break;
case 20: case 20:
list.Add("secp224k1 [0x14]"); //deprecated list.Add("secp224k1 [0x14]"); // deprecated
break; break;
case 21: case 21:
list.Add("secp224r1 [0x15]"); //deprecated list.Add("secp224r1 [0x15]"); // deprecated
break; break;
case 22: case 22:
list.Add("secp256k1 [0x16]"); //deprecated list.Add("secp256k1 [0x16]"); // deprecated
break; break;
case 23: case 23:
list.Add("secp256r1 [0x17]"); list.Add("secp256r1 [0x17]");
...@@ -178,10 +178,10 @@ namespace Titanium.Web.Proxy.StreamExtended ...@@ -178,10 +178,10 @@ namespace Titanium.Web.Proxy.StreamExtended
list.Add("ffdhe8192 [0x0104]"); list.Add("ffdhe8192 [0x0104]");
break; break;
case 65281: case 65281:
list.Add("arbitrary_explicit_prime_curves [0xFF01]"); //deprecated list.Add("arbitrary_explicit_prime_curves [0xFF01]"); // deprecated
break; break;
case 65282: case 65282:
list.Add("arbitrary_explicit_char2_curves [0xFF02]"); //deprecated list.Add("arbitrary_explicit_char2_curves [0xFF02]"); // deprecated
break; break;
default: default:
list.Add($"unknown [0x{namedCurve:X4}]"); list.Add($"unknown [0x{namedCurve:X4}]");
...@@ -318,7 +318,7 @@ namespace Titanium.Web.Proxy.StreamExtended ...@@ -318,7 +318,7 @@ namespace Titanium.Web.Proxy.StreamExtended
private static string GetExtensionName(int value) 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) switch (value)
{ {
case 0: case 0:
......
...@@ -34,8 +34,8 @@ namespace Titanium.Web.Proxy.StreamExtended ...@@ -34,8 +34,8 @@ namespace Titanium.Web.Proxy.StreamExtended
/// <returns></returns> /// <returns></returns>
public static async Task<ClientHelloInfo> PeekClientHello(CustomBufferedStream clientStream, IBufferPool bufferPool, CancellationToken cancellationToken = default) public static async Task<ClientHelloInfo> PeekClientHello(CustomBufferedStream clientStream, IBufferPool bufferPool, CancellationToken cancellationToken = default)
{ {
//detects the HTTPS ClientHello message as it is described in the following url: // 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 // https://stackoverflow.com/questions/3897883/how-to-detect-an-incoming-ssl-https-handshake-ssl-wire-format
int recordType = await clientStream.PeekByteAsync(0, cancellationToken); int recordType = await clientStream.PeekByteAsync(0, cancellationToken);
if (recordType == -1) if (recordType == -1)
...@@ -45,7 +45,7 @@ namespace Titanium.Web.Proxy.StreamExtended ...@@ -45,7 +45,7 @@ namespace Titanium.Web.Proxy.StreamExtended
if ((recordType & 0x80) == 0x80) if ((recordType & 0x80) == 0x80)
{ {
//SSL 2 // SSL 2
var peekStream = new CustomBufferedPeekStream(clientStream, bufferPool, 1); var peekStream = new CustomBufferedPeekStream(clientStream, bufferPool, 1);
// length value + minimum length // length value + minimum length
...@@ -105,14 +105,14 @@ namespace Titanium.Web.Proxy.StreamExtended ...@@ -105,14 +105,14 @@ namespace Titanium.Web.Proxy.StreamExtended
{ {
var peekStream = new CustomBufferedPeekStream(clientStream, bufferPool, 1); 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 // 2 version + 2 length + 1 type + 3 length(?) + 2 version + 32 random + 1 sessionid length
if (!await peekStream.EnsureBufferLength(43, cancellationToken)) if (!await peekStream.EnsureBufferLength(43, cancellationToken))
{ {
return null; 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 majorVersion = peekStream.ReadByte();
int minorVersion = peekStream.ReadByte(); int minorVersion = peekStream.ReadByte();
...@@ -220,8 +220,8 @@ namespace Titanium.Web.Proxy.StreamExtended ...@@ -220,8 +220,8 @@ namespace Titanium.Web.Proxy.StreamExtended
/// <returns></returns> /// <returns></returns>
public static async Task<ServerHelloInfo> PeekServerHello(CustomBufferedStream serverStream, IBufferPool bufferPool, CancellationToken cancellationToken = default) public static async Task<ServerHelloInfo> PeekServerHello(CustomBufferedStream serverStream, IBufferPool bufferPool, CancellationToken cancellationToken = default)
{ {
//detects the HTTPS ClientHello message as it is described in the following url: // 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 // https://stackoverflow.com/questions/3897883/how-to-detect-an-incoming-ssl-https-handshake-ssl-wire-format
int recordType = await serverStream.PeekByteAsync(0, cancellationToken); int recordType = await serverStream.PeekByteAsync(0, cancellationToken);
if (recordType == -1) if (recordType == -1)
...@@ -231,7 +231,7 @@ namespace Titanium.Web.Proxy.StreamExtended ...@@ -231,7 +231,7 @@ namespace Titanium.Web.Proxy.StreamExtended
if ((recordType & 0x80) == 0x80) if ((recordType & 0x80) == 0x80)
{ {
//SSL 2 // SSL 2
// not tested. SSL2 is deprecated // not tested. SSL2 is deprecated
var peekStream = new CustomBufferedPeekStream(serverStream, bufferPool, 1); var peekStream = new CustomBufferedPeekStream(serverStream, bufferPool, 1);
...@@ -284,14 +284,14 @@ namespace Titanium.Web.Proxy.StreamExtended ...@@ -284,14 +284,14 @@ namespace Titanium.Web.Proxy.StreamExtended
{ {
var peekStream = new CustomBufferedPeekStream(serverStream, bufferPool, 1); 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 // 2 version + 2 length + 1 type + 3 length(?) + 2 version + 32 random + 1 sessionid length
if (!await peekStream.EnsureBufferLength(43, cancellationToken)) if (!await peekStream.EnsureBufferLength(43, cancellationToken))
{ {
return null; 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 majorVersion = peekStream.ReadByte();
int minorVersion = peekStream.ReadByte(); int minorVersion = peekStream.ReadByte();
......
...@@ -13,7 +13,7 @@ using System.Threading.Tasks; ...@@ -13,7 +13,7 @@ using System.Threading.Tasks;
namespace Titanium.Web.Proxy.IntegrationTests.Setup namespace Titanium.Web.Proxy.IntegrationTests.Setup
{ {
//set up a kestrel test server // set up a kestrel test server
public class TestServer : IDisposable public class TestServer : IDisposable
{ {
public string ListeningHttpUrl => $"http://localhost:{HttpListeningPort}"; public string ListeningHttpUrl => $"http://localhost:{HttpListeningPort}";
......
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