Unverified Commit 2560b800 authored by justcoding121's avatar justcoding121 Committed by GitHub

Merge pull request #449 from justcoding121/master

Beta
parents 8ce2dc27 421e2598
......@@ -149,8 +149,9 @@ namespace Titanium.Web.Proxy.Examples.Basic
}
}
private async Task OnBeforeTunnelConnectResponse(object sender, TunnelConnectSessionEventArgs e)
private Task OnBeforeTunnelConnectResponse(object sender, TunnelConnectSessionEventArgs e)
{
return Task.FromResult(false);
}
// intecept & cancel redirect or update requests
......
......@@ -140,8 +140,9 @@ namespace Titanium.Web.Proxy
{
// test server HTTP/2 support
// todo: this is a hack, because Titanium does not support HTTP protocol changing currently
var connection = await getServerConnection(connectArgs, true,
SslExtensions.Http2ProtocolAsList, true, cancellationToken);
var connection = await tcpConnectionFactory.GetServerConnection(this, connectArgs,
isConnect: true, applicationProtocols: SslExtensions.Http2ProtocolAsList,
noCache: true, cancellationToken: cancellationToken);
http2Supported = connection.NegotiatedApplicationProtocol == SslApplicationProtocol.Http2;
......@@ -153,8 +154,9 @@ namespace Titanium.Web.Proxy
//don't pass cancellation token here
//it could cause floating server connections when client exits
prefetchConnectionTask = getServerConnection(connectArgs, true,
null, false, CancellationToken.None);
prefetchConnectionTask = tcpConnectionFactory.GetServerConnection(this, connectArgs,
isConnect: true, applicationProtocols: null, noCache: false,
cancellationToken: CancellationToken.None);
try
{
......@@ -201,6 +203,12 @@ namespace Titanium.Web.Proxy
{
decryptSsl = false;
}
if(!decryptSsl)
{
await tcpConnectionFactory.Release(prefetchConnectionTask, true);
prefetchConnectionTask = null;
}
}
if (cancellationTokenSource.IsCancellationRequested)
......@@ -214,8 +222,9 @@ namespace Titanium.Web.Proxy
// create new connection to server.
// If we detected that client tunnel CONNECTs without SSL by checking for empty client hello then
// this connection should not be HTTPS.
var connection = await getServerConnection(connectArgs,
true, SslExtensions.Http2ProtocolAsList, true, cancellationToken);
var connection = await tcpConnectionFactory.GetServerConnection(this, connectArgs,
isConnect: true, applicationProtocols: SslExtensions.Http2ProtocolAsList,
noCache: true, cancellationToken: cancellationToken);
try
{
......@@ -247,8 +256,6 @@ namespace Titanium.Web.Proxy
(buffer, offset, count) => { connectArgs.OnDataSent(buffer, offset, count); },
(buffer, offset, count) => { connectArgs.OnDataReceived(buffer, offset, count); },
connectArgs.CancellationTokenSource, ExceptionFunc);
}
finally
{
......@@ -284,9 +291,9 @@ namespace Titanium.Web.Proxy
throw new Exception($"HTTP/2 Protocol violation. Empty string expected, '{line}' received");
}
var connection = await getServerConnection(connectArgs, true,
SslExtensions.Http2ProtocolAsList, true,
cancellationToken);
var connection = await tcpConnectionFactory.GetServerConnection(this, connectArgs,
isConnect: true, applicationProtocols: SslExtensions.Http2ProtocolAsList,
noCache: true, cancellationToken: cancellationToken);
try
{
await connection.StreamWriter.WriteLineAsync("PRI * HTTP/2.0", cancellationToken);
......@@ -335,19 +342,9 @@ namespace Titanium.Web.Proxy
}
finally
{
if (!calledRequestHandler
&& prefetchConnectionTask != null)
if (!calledRequestHandler)
{
TcpServerConnection prefetchedConnection = null;
try
{
prefetchedConnection = await prefetchConnectionTask;
}
finally
{
await tcpConnectionFactory.Release(prefetchedConnection, closeServerConnection);
}
await tcpConnectionFactory.Release(prefetchConnectionTask, closeServerConnection);
}
clientStream.Dispose();
......
namespace Titanium.Web.Proxy.Models
{
public enum ProxyAuthenticationResult
{
/// <summary>
/// Indicates the authentication request was successful
/// </summary>
Success,
/// <summary>
/// Indicates the authentication request failed
/// </summary>
Failure,
/// <summary>
/// Indicates that this stage of the authentication request succeeded
/// And a second pass of the handshake needs to occur
/// </summary>
ContinuationNeeded
}
/// <summary>
/// A context container for authentication flows
/// </summary>
public class ProxyAuthenticationContext
{
/// <summary>
/// The result of the current authentication request
/// </summary>
public ProxyAuthenticationResult Result { get; set; }
/// <summary>
/// An optional continuation token to return to the caller if set
/// </summary>
public string Continuation { get; set; }
public static ProxyAuthenticationContext Failed()
{
return new ProxyAuthenticationContext
{
Result = ProxyAuthenticationResult.Failure,
Continuation = null
};
}
public static ProxyAuthenticationContext Succeeded()
{
return new ProxyAuthenticationContext
{
Result = ProxyAuthenticationResult.Success,
Continuation = null
};
}
}
}
using Polly;
using System;
using System.Threading.Tasks;
using Titanium.Web.Proxy.Network.Tcp;
namespace Titanium.Web.Proxy.Network
{
internal class RetryPolicy<T> where T : Exception
{
private readonly int retries;
private readonly TcpConnectionFactory tcpConnectionFactory;
private TcpServerConnection currentConnection;
private Policy policy;
internal RetryPolicy(int retries, TcpConnectionFactory tcpConnectionFactory)
{
this.retries = retries;
this.tcpConnectionFactory = tcpConnectionFactory;
policy = getRetryPolicy();
}
/// <summary>
/// Execute and retry the given action until retry number of times.
/// </summary>
/// <param name="action">The action to retry with return value specifying whether caller should continue execution.</param>
/// <param name="generator">The Tcp connection generator to be invoked to get new connection for retry.</param>
/// <param name="initialConnection">Initial Tcp connection to use.</param>
/// <returns>Returns the latest connection used and the latest exception if any.</returns>
internal async Task<RetryResult> ExecuteAsync(Func<TcpServerConnection, Task<bool>> action,
Func<Task<TcpServerConnection>> generator, TcpServerConnection initialConnection)
{
currentConnection = initialConnection;
Exception exception = null;
bool @continue = true;
try
{
//retry on error with polly policy
//do not use polly context to store connection; it does not save states b/w attempts
await policy.ExecuteAsync(async () =>
{
//setup connection
currentConnection = currentConnection as TcpServerConnection ??
await generator();
//try
@continue = await action(currentConnection);
});
}
catch (Exception e) { exception = e; }
return new RetryResult(currentConnection, exception, @continue);
}
//get the policy
private Policy getRetryPolicy()
{
return Policy.Handle<T>()
.RetryAsync(retries,
onRetryAsync: onRetry);
}
//before retry clear connection
private async Task onRetry(Exception ex, int attempt)
{
if (currentConnection != null)
{
//close connection on error
await tcpConnectionFactory.Release(currentConnection, true);
currentConnection = null;
}
}
}
internal class RetryResult
{
internal bool IsSuccess => Exception == null;
internal TcpServerConnection LatestConnection { get; }
internal Exception Exception { get; }
internal bool Continue { get; }
internal RetryResult(TcpServerConnection lastConnection, Exception exception, bool @continue)
{
LatestConnection = lastConnection;
Exception = exception;
Continue = @continue;
}
}
}
......@@ -9,6 +9,7 @@ using System.Text;
using System.Threading;
using System.Threading.Tasks;
using StreamExtended.Network;
using Titanium.Web.Proxy.EventArguments;
using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Http;
......@@ -69,6 +70,91 @@ namespace Titanium.Web.Proxy.Network.Tcp
return cacheKeyBuilder.ToString();
}
/// <summary>
/// Gets the connection cache key.
/// </summary>
/// <param name="args">The session event arguments.</param>
/// <param name="applicationProtocol"></param>
/// <returns></returns>
internal async Task<string> GetConnectionCacheKey(ProxyServer server, SessionEventArgsBase args,
SslApplicationProtocol applicationProtocol)
{
List<SslApplicationProtocol> applicationProtocols = null;
if (applicationProtocol != default)
{
applicationProtocols = new List<SslApplicationProtocol> { applicationProtocol };
}
ExternalProxy customUpStreamProxy = null;
bool isHttps = args.IsHttps;
if (server.GetCustomUpStreamProxyFunc != null)
{
customUpStreamProxy = await server.GetCustomUpStreamProxyFunc(args);
}
args.CustomUpStreamProxyUsed = customUpStreamProxy;
return GetConnectionCacheKey(
args.WebSession.Request.RequestUri.Host,
args.WebSession.Request.RequestUri.Port,
isHttps, applicationProtocols,
server, args.WebSession.UpStreamEndPoint ?? server.UpStreamEndPoint,
customUpStreamProxy ?? (isHttps ? server.UpStreamHttpsProxy : server.UpStreamHttpProxy));
}
/// <summary>
/// Create a server connection.
/// </summary>
/// <param name="args">The session event arguments.</param>
/// <param name="isConnect">Is this a CONNECT request.</param>
/// <param name="applicationProtocol"></param>
/// <param name="cancellationToken">The cancellation token for this async task.</param>
/// <returns></returns>
internal Task<TcpServerConnection> GetServerConnection(ProxyServer server, SessionEventArgsBase args, bool isConnect,
SslApplicationProtocol applicationProtocol, bool noCache, CancellationToken cancellationToken)
{
List<SslApplicationProtocol> applicationProtocols = null;
if (applicationProtocol != default)
{
applicationProtocols = new List<SslApplicationProtocol> { applicationProtocol };
}
return GetServerConnection(server, args, isConnect, applicationProtocols, noCache, cancellationToken);
}
/// <summary>
/// Create a server connection.
/// </summary>
/// <param name="args">The session event arguments.</param>
/// <param name="isConnect">Is this a CONNECT request.</param>
/// <param name="applicationProtocols"></param>
/// <param name="cancellationToken">The cancellation token for this async task.</param>
/// <returns></returns>
internal async Task<TcpServerConnection> GetServerConnection(ProxyServer server, SessionEventArgsBase args, bool isConnect,
List<SslApplicationProtocol> applicationProtocols, bool noCache, CancellationToken cancellationToken)
{
ExternalProxy customUpStreamProxy = null;
bool isHttps = args.IsHttps;
if (server.GetCustomUpStreamProxyFunc != null)
{
customUpStreamProxy = await server.GetCustomUpStreamProxyFunc(args);
}
args.CustomUpStreamProxyUsed = customUpStreamProxy;
return await GetServerConnection(
args.WebSession.Request.RequestUri.Host,
args.WebSession.Request.RequestUri.Port,
args.WebSession.Request.HttpVersion,
isHttps, applicationProtocols, isConnect,
server, args.WebSession.UpStreamEndPoint ?? server.UpStreamEndPoint,
customUpStreamProxy ?? (isHttps ? server.UpStreamHttpsProxy : server.UpStreamHttpProxy),
noCache, cancellationToken);
}
/// <summary>
/// Gets a TCP connection to server from connection pool.
/// </summary>
......@@ -84,7 +170,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
/// <param name="noCache">Not from cache/create new connection.</param>
/// <param name="cancellationToken">The cancellation token for this async task.</param>
/// <returns></returns>
internal async Task<TcpServerConnection> GetClient(string remoteHostName, int remotePort,
internal async Task<TcpServerConnection> GetServerConnection(string remoteHostName, int remotePort,
Version httpVersion, bool isHttps, List<SslApplicationProtocol> applicationProtocols, bool isConnect,
ProxyServer proxyServer, IPEndPoint upStreamEndPoint, ExternalProxy externalProxy,
bool noCache, CancellationToken cancellationToken)
......@@ -116,7 +202,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
}
}
var connection = await createClient(remoteHostName, remotePort, httpVersion, isHttps,
var connection = await createServerConnection(remoteHostName, remotePort, httpVersion, isHttps,
applicationProtocols, isConnect, proxyServer, upStreamEndPoint, externalProxy, cancellationToken);
connection.CacheKey = cacheKey;
......@@ -124,115 +210,6 @@ namespace Titanium.Web.Proxy.Network.Tcp
return connection;
}
/// <summary>
/// Release connection back to cache.
/// </summary>
/// <param name="connection">The Tcp server connection to return.</param>
/// <param name="close">Should we just close the connection instead of reusing?</param>
internal async Task Release(TcpServerConnection connection, bool close = false)
{
if (connection == null)
{
return;
}
if (close || connection.IsWinAuthenticated || !server.EnableConnectionPool)
{
disposalBag.Add(connection);
return;
}
connection.LastAccess = DateTime.Now;
try
{
await @lock.WaitAsync();
while (true)
{
if (cache.TryGetValue(connection.CacheKey, out var existingConnections))
{
while (existingConnections.Count >= server.MaxCachedConnections)
{
if (existingConnections.TryDequeue(out var staleConnection))
{
disposalBag.Add(staleConnection);
}
}
existingConnections.Enqueue(connection);
break;
}
if (cache.TryAdd(connection.CacheKey,
new ConcurrentQueue<TcpServerConnection>(new[] { connection })))
{
break;
}
}
}
finally
{
@lock.Release();
}
}
private async Task clearOutdatedConnections()
{
while (runCleanUpTask)
{
foreach (var item in cache)
{
var queue = item.Value;
while (queue.Count > 0)
{
if (queue.TryDequeue(out var connection))
{
var cutOff = DateTime.Now.AddSeconds(-1 * server.ConnectionTimeOutSeconds);
if (!server.EnableConnectionPool
|| connection.LastAccess < cutOff)
{
disposalBag.Add(connection);
continue;
}
queue.Enqueue(connection);
break;
}
}
}
try
{
await @lock.WaitAsync();
//clear empty queues
var emptyKeys = cache.Where(x => x.Value.Count == 0).Select(x => x.Key).ToList();
foreach (string key in emptyKeys)
{
cache.TryRemove(key, out var _);
}
}
finally
{
@lock.Release();
}
while (!disposalBag.IsEmpty)
{
if (disposalBag.TryTake(out var connection))
{
connection?.Dispose();
}
}
//cleanup every 3 seconds by default
await Task.Delay(1000 * 3);
}
}
/// <summary>
/// Creates a TCP connection to server
/// </summary>
......@@ -247,7 +224,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
/// <param name="externalProxy">The external proxy to make request via.</param>
/// <param name="cancellationToken">The cancellation token for this async task.</param>
/// <returns></returns>
private async Task<TcpServerConnection> createClient(string remoteHostName, int remotePort,
private async Task<TcpServerConnection> createServerConnection(string remoteHostName, int remotePort,
Version httpVersion, bool isHttps, List<SslApplicationProtocol> applicationProtocols, bool isConnect,
ProxyServer proxyServer, IPEndPoint upStreamEndPoint, ExternalProxy externalProxy,
CancellationToken cancellationToken)
......@@ -370,6 +347,140 @@ namespace Titanium.Web.Proxy.Network.Tcp
Version = httpVersion
};
}
/// <summary>
/// Release connection back to cache.
/// </summary>
/// <param name="connection">The Tcp server connection to return.</param>
/// <param name="close">Should we just close the connection instead of reusing?</param>
internal async Task Release(TcpServerConnection connection, bool close = false)
{
if (connection == null)
{
return;
}
if (close || connection.IsWinAuthenticated || !server.EnableConnectionPool)
{
disposalBag.Add(connection);
return;
}
connection.LastAccess = DateTime.Now;
try
{
await @lock.WaitAsync();
while (true)
{
if (cache.TryGetValue(connection.CacheKey, out var existingConnections))
{
while (existingConnections.Count >= server.MaxCachedConnections)
{
if (existingConnections.TryDequeue(out var staleConnection))
{
disposalBag.Add(staleConnection);
}
}
existingConnections.Enqueue(connection);
break;
}
if (cache.TryAdd(connection.CacheKey,
new ConcurrentQueue<TcpServerConnection>(new[] { connection })))
{
break;
}
}
}
finally
{
@lock.Release();
}
}
internal async Task Release(Task<TcpServerConnection> connectionCreateTask, bool closeServerConnection)
{
if (connectionCreateTask != null)
{
TcpServerConnection connection = null;
try
{
connection = await connectionCreateTask;
}
catch { }
finally
{
await Release(connection, closeServerConnection);
}
}
}
private async Task clearOutdatedConnections()
{
while (runCleanUpTask)
{
try
{
foreach (var item in cache)
{
var queue = item.Value;
while (queue.Count > 0)
{
if (queue.TryDequeue(out var connection))
{
var cutOff = DateTime.Now.AddSeconds(-1 * server.ConnectionTimeOutSeconds);
if (!server.EnableConnectionPool
|| connection.LastAccess < cutOff)
{
disposalBag.Add(connection);
continue;
}
queue.Enqueue(connection);
break;
}
}
}
try
{
await @lock.WaitAsync();
//clear empty queues
var emptyKeys = cache.Where(x => x.Value.Count == 0).Select(x => x.Key).ToList();
foreach (string key in emptyKeys)
{
cache.TryRemove(key, out var _);
}
}
finally
{
@lock.Release();
}
while (!disposalBag.IsEmpty)
{
if (disposalBag.TryTake(out var connection))
{
connection?.Dispose();
}
}
}
finally
{
//cleanup every 3 seconds by default
await Task.Delay(1000 * 3);
}
}
}
/// <summary>
/// Check if a TcpClient is good to be used.
/// This only checks if send is working so local socket is still connected.
......
......@@ -21,7 +21,7 @@ namespace Titanium.Web.Proxy
private async Task<bool> checkAuthorization(SessionEventArgsBase session)
{
// If we are not authorizing clients return true
if (AuthenticateUserFunc == null)
if (ProxyBasicAuthenticateFunc == null && ProxySchemeAuthenticateFunc == null)
{
return true;
}
......@@ -38,32 +38,34 @@ namespace Titanium.Web.Proxy
}
var headerValueParts = header.Value.Split(ProxyConstants.SpaceSplit);
if (headerValueParts.Length != 2 ||
!headerValueParts[0].EqualsIgnoreCase(KnownHeaders.ProxyAuthorizationBasic))
if (headerValueParts.Length != 2)
{
// Return not authorized
session.WebSession.Response = createAuthentication407Response("Proxy Authentication Invalid");
return false;
}
string decoded = Encoding.UTF8.GetString(Convert.FromBase64String(headerValueParts[1]));
int colonIndex = decoded.IndexOf(':');
if (colonIndex == -1)
if (ProxyBasicAuthenticateFunc != null)
{
// Return not authorized
session.WebSession.Response = createAuthentication407Response("Proxy Authentication Invalid");
return false;
return await authenticateUserBasic(session, headerValueParts);
}
string username = decoded.Substring(0, colonIndex);
string password = decoded.Substring(colonIndex + 1);
bool authenticated = await AuthenticateUserFunc(username, password);
if (!authenticated)
if (ProxySchemeAuthenticateFunc != null)
{
session.WebSession.Response = createAuthentication407Response("Proxy Authentication Invalid");
var result = await ProxySchemeAuthenticateFunc(session, headerValueParts[0], headerValueParts[1]);
if (result.Result == ProxyAuthenticationResult.ContinuationNeeded)
{
session.WebSession.Response = createAuthentication407Response("Proxy Authentication Invalid", result.Continuation);
return false;
}
return result.Result == ProxyAuthenticationResult.Success;
}
return authenticated;
return false;
}
catch (Exception e)
{
......@@ -76,12 +78,41 @@ namespace Titanium.Web.Proxy
}
}
private async Task<bool> authenticateUserBasic(SessionEventArgsBase session, string[] headerValueParts)
{
if (!headerValueParts[0].EqualsIgnoreCase(KnownHeaders.ProxyAuthorizationBasic))
{
// Return not authorized
session.WebSession.Response = createAuthentication407Response("Proxy Authentication Invalid");
return false;
}
string decoded = Encoding.UTF8.GetString(Convert.FromBase64String(headerValueParts[1]));
int colonIndex = decoded.IndexOf(':');
if (colonIndex == -1)
{
// Return not authorized
session.WebSession.Response = createAuthentication407Response("Proxy Authentication Invalid");
return false;
}
string username = decoded.Substring(0, colonIndex);
string password = decoded.Substring(colonIndex + 1);
bool authenticated = await ProxyBasicAuthenticateFunc(username, password);
if (!authenticated)
{
session.WebSession.Response = createAuthentication407Response("Proxy Authentication Invalid");
}
return authenticated;
}
/// <summary>
/// Create an authentication required response.
/// </summary>
/// <param name="description">Response description.</param>
/// <returns></returns>
private Response createAuthentication407Response(string description)
private Response createAuthentication407Response(string description, string continuation = null)
{
var response = new Response
{
......@@ -90,11 +121,39 @@ namespace Titanium.Web.Proxy
StatusDescription = description
};
response.Headers.AddHeader(KnownHeaders.ProxyAuthenticate, $"Basic realm=\"{ProxyRealm}\"");
if (!string.IsNullOrWhiteSpace(continuation))
{
return createContinuationResponse(response, continuation);
}
if (ProxyBasicAuthenticateFunc != null)
{
response.Headers.AddHeader(KnownHeaders.ProxyAuthenticate, $"Basic realm=\"{ProxyAuthenticationRealm}\"");
}
if (ProxySchemeAuthenticateFunc != null)
{
foreach (var scheme in ProxyAuthenticationSchemes)
{
response.Headers.AddHeader(KnownHeaders.ProxyAuthenticate, scheme);
}
}
response.Headers.AddHeader(KnownHeaders.ProxyConnection, KnownHeaders.ProxyConnectionClose);
response.Headers.FixProxyHeaders();
return response;
}
private Response createContinuationResponse(Response response, string continuation)
{
response.Headers.AddHeader(KnownHeaders.ProxyAuthenticate, continuation);
response.Headers.AddHeader(KnownHeaders.ProxyConnection, KnownHeaders.ConnectionKeepAlive);
response.Headers.FixProxyHeaders();
return response;
}
}
}
......@@ -7,7 +7,6 @@ using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
using Polly;
using StreamExtended;
using StreamExtended.Network;
using Titanium.Web.Proxy.EventArguments;
......@@ -125,7 +124,7 @@ namespace Titanium.Web.Proxy
private SystemProxyManager systemProxySettingsManager { get; }
//Number of exception retries when connection pool is enabled.
private int retries => EnableConnectionPool ? MaxCachedConnections + 1 : 0;
private int retries => EnableConnectionPool ? MaxCachedConnections : 0;
/// <summary>
/// Is the proxy currently running?
......@@ -200,7 +199,7 @@ namespace Titanium.Web.Proxy
/// <summary>
/// Realm used during Proxy Basic Authentication.
/// </summary>
public string ProxyRealm { get; set; } = "TitaniumProxy";
public string ProxyAuthenticationRealm { get; set; } = "TitaniumProxy";
/// <summary>
/// List of supported Ssl versions.
......@@ -264,11 +263,24 @@ namespace Titanium.Web.Proxy
}
/// <summary>
/// A callback to authenticate clients.
/// A callback to authenticate proxy clients via basic authentication.
/// Parameters are username and password as provided by client.
/// Should return true for successful authentication.
/// </summary>
public Func<string, string, Task<bool>> AuthenticateUserFunc { get; set; }
public Func<string, string, Task<bool>> ProxyBasicAuthenticateFunc { get; set; }
/// <summary>
/// A pluggable callback to authenticate clients by scheme instead of requiring basic authentication through ProxyBasicAuthenticateFunc.
/// Parameters are current working session, schemeType, and token as provided by a calling client.
/// Should return success for successful authentication, continuation if the package requests, or failure.
/// </summary>
public Func<SessionEventArgsBase, string, string, Task<ProxyAuthenticationContext>> ProxySchemeAuthenticateFunc { get; set; }
/// <summary>
/// A collection of scheme types, e.g. basic, NTLM, Kerberos, Negotiate, to return if scheme authentication is required.
/// Works in relation with ProxySchemeAuthenticateFunc.
/// </summary>
public IEnumerable<string> ProxyAuthenticationSchemes { get; set; } = new string[0];
/// <summary>
/// Dispose the Proxy instance.
......@@ -809,22 +821,9 @@ namespace Titanium.Web.Proxy
/// <summary>
/// Connection retry policy when using connection pool.
/// </summary>
private Policy retryPolicy<T>() where T : Exception
private RetryPolicy<T> retryPolicy<T>() where T : Exception
{
return Policy.Handle<T>()
.RetryAsync(retries,
onRetryAsync: async (ex, i, context) =>
{
if (context["connection"] != null)
{
//close connection on error
var connection = (TcpServerConnection)context["connection"];
await tcpConnectionFactory.Release(connection, true);
context["connection"] = null;
}
});
return new RetryPolicy<T>(retries, tcpConnectionFactory);
}
}
}
......@@ -196,7 +196,7 @@ namespace Titanium.Web.Proxy
// only gets hit when connection pool is disabled.
// or when prefetch task has a unexpectedly different connection.
if (connection != null
&& (await getConnectionCacheKey(args,
&& (await tcpConnectionFactory.GetConnectionCacheKey(this, args,
clientConnection.NegotiatedApplicationProtocol)
!= connection.CacheKey))
{
......@@ -204,30 +204,44 @@ namespace Titanium.Web.Proxy
connection = null;
}
//for connection pool retry fails until cache is exhausted
await retryPolicy<ServerConnectionException>().ExecuteAsync(async (context) =>
{
connection = context["connection"] as TcpServerConnection ??
await getServerConnection(args, false,
clientConnection.NegotiatedApplicationProtocol,
false, cancellationToken);
context["connection"] = connection;
//a connection generator task with captured parameters via closure.
Func<Task<TcpServerConnection>> generator = () =>
tcpConnectionFactory.GetServerConnection(this, args, isConnect: false,
applicationProtocol:clientConnection.NegotiatedApplicationProtocol,
noCache: false, cancellationToken: cancellationToken);
//for connection pool, retry fails until cache is exhausted.
var result = await retryPolicy<ServerConnectionException>().ExecuteAsync(async (serverConnection) =>
{
// if upgrading to websocket then relay the request without reading the contents
if (request.UpgradeToWebSocket)
{
await handleWebSocketUpgrade(httpCmd, args, request,
response, clientStream, clientStreamWriter,
connection, cancellationTokenSource, cancellationToken);
serverConnection, cancellationTokenSource, cancellationToken);
closeServerConnection = true;
return;
return false;
}
// construct the web request that we are going to issue on behalf of the client.
await handleHttpSessionRequestInternal(connection, args);
await handleHttpSessionRequestInternal(serverConnection, args);
return true;
}, generator, connection);
}, new Dictionary<string, object> { { "connection", connection } });
//update connection to latest used
connection = result.LatestConnection;
//throw if exception happened
if(!result.IsSuccess)
{
throw result.Exception;
}
if(!result.Continue)
{
return;
}
//user requested
if (args.WebSession.CloseServerConnection)
......@@ -251,7 +265,9 @@ namespace Titanium.Web.Proxy
//Get/release server connection for each HTTP session instead of per client connection.
//This will be more efficient especially when client is idly holding server connection
//between sessions without using it.
if (EnableConnectionPool)
//Do not release authenticated connections for performance reasons.
//Otherwise it will keep authenticating per session.
if (EnableConnectionPool && !connection.IsWinAuthenticated)
{
await tcpConnectionFactory.Release(connection);
connection = null;
......@@ -281,20 +297,7 @@ namespace Titanium.Web.Proxy
await tcpConnectionFactory.Release(connection,
closeServerConnection);
if (prefetchTask != null)
{
TcpServerConnection prefetchedConnection = null;
try
{
prefetchedConnection = await prefetchTask;
}
finally
{
await tcpConnectionFactory.Release(prefetchedConnection, closeServerConnection);
}
}
await tcpConnectionFactory.Release(prefetchTask, closeServerConnection);
}
}
......@@ -376,62 +379,6 @@ namespace Titanium.Web.Proxy
}
}
/// <summary>
/// Handle upgrade to websocket
/// </summary>
private async Task handleWebSocketUpgrade(string httpCmd,
SessionEventArgs args, Request request, Response response,
CustomBufferedStream clientStream, HttpResponseWriter clientStreamWriter,
TcpServerConnection serverConnection,
CancellationTokenSource cancellationTokenSource, CancellationToken cancellationToken)
{
// prepare the prefix content
await serverConnection.StreamWriter.WriteLineAsync(httpCmd, cancellationToken);
await serverConnection.StreamWriter.WriteHeadersAsync(request.Headers,
cancellationToken: cancellationToken);
string httpStatus;
try
{
httpStatus = await serverConnection.Stream.ReadLineAsync(cancellationToken);
if (httpStatus == null)
{
throw new ServerConnectionException("Server connection was closed.");
}
}
catch (Exception e) when (!(e is ServerConnectionException))
{
throw new ServerConnectionException("Server connection was closed.", e);
}
Response.ParseResponseLine(httpStatus, out var responseVersion,
out int responseStatusCode,
out string responseStatusDescription);
response.HttpVersion = responseVersion;
response.StatusCode = responseStatusCode;
response.StatusDescription = responseStatusDescription;
await HeaderParser.ReadHeaders(serverConnection.Stream, response.Headers,
cancellationToken);
if (!args.IsTransparent)
{
await clientStreamWriter.WriteResponseAsync(response,
cancellationToken: cancellationToken);
}
// If user requested call back then do it
if (!args.WebSession.Response.Locked)
{
await invokeBeforeResponse(args);
}
await TcpHelper.SendRaw(clientStream, serverConnection.Stream, BufferPool, BufferSize,
(buffer, offset, count) => { args.OnDataSent(buffer, offset, count); },
(buffer, offset, count) => { args.OnDataReceived(buffer, offset, count); },
cancellationTokenSource, ExceptionFunc);
}
/// <summary>
/// Prepare the request headers so that we can avoid encodings not parsable by this proxy
/// </summary>
......@@ -458,92 +405,6 @@ namespace Titanium.Web.Proxy
requestHeaders.FixProxyHeaders();
}
/// <summary>
/// Gets the connection cache key.
/// </summary>
/// <param name="args">The session event arguments.</param>
/// <param name="applicationProtocol"></param>
/// <returns></returns>
private async Task<string> getConnectionCacheKey(SessionEventArgsBase args,
SslApplicationProtocol applicationProtocol)
{
List<SslApplicationProtocol> applicationProtocols = null;
if (applicationProtocol != default)
{
applicationProtocols = new List<SslApplicationProtocol> { applicationProtocol };
}
ExternalProxy customUpStreamProxy = null;
bool isHttps = args.IsHttps;
if (GetCustomUpStreamProxyFunc != null)
{
customUpStreamProxy = await GetCustomUpStreamProxyFunc(args);
}
args.CustomUpStreamProxyUsed = customUpStreamProxy;
return tcpConnectionFactory.GetConnectionCacheKey(
args.WebSession.Request.RequestUri.Host,
args.WebSession.Request.RequestUri.Port,
isHttps, applicationProtocols,
this, args.WebSession.UpStreamEndPoint ?? UpStreamEndPoint,
customUpStreamProxy ?? (isHttps ? UpStreamHttpsProxy : UpStreamHttpProxy));
}
/// <summary>
/// Create a server connection.
/// </summary>
/// <param name="args">The session event arguments.</param>
/// <param name="isConnect">Is this a CONNECT request.</param>
/// <param name="applicationProtocol"></param>
/// <param name="cancellationToken">The cancellation token for this async task.</param>
/// <returns></returns>
private Task<TcpServerConnection> getServerConnection(SessionEventArgsBase args, bool isConnect,
SslApplicationProtocol applicationProtocol, bool noCache, CancellationToken cancellationToken)
{
List<SslApplicationProtocol> applicationProtocols = null;
if (applicationProtocol != default)
{
applicationProtocols = new List<SslApplicationProtocol> { applicationProtocol };
}
return getServerConnection(args, isConnect, applicationProtocols, noCache, cancellationToken);
}
/// <summary>
/// Create a server connection.
/// </summary>
/// <param name="args">The session event arguments.</param>
/// <param name="isConnect">Is this a CONNECT request.</param>
/// <param name="applicationProtocols"></param>
/// <param name="cancellationToken">The cancellation token for this async task.</param>
/// <returns></returns>
private async Task<TcpServerConnection> getServerConnection(SessionEventArgsBase args, bool isConnect,
List<SslApplicationProtocol> applicationProtocols, bool noCache, CancellationToken cancellationToken)
{
ExternalProxy customUpStreamProxy = null;
bool isHttps = args.IsHttps;
if (GetCustomUpStreamProxyFunc != null)
{
customUpStreamProxy = await GetCustomUpStreamProxyFunc(args);
}
args.CustomUpStreamProxyUsed = customUpStreamProxy;
return await tcpConnectionFactory.GetClient(
args.WebSession.Request.RequestUri.Host,
args.WebSession.Request.RequestUri.Port,
args.WebSession.Request.HttpVersion,
isHttps, applicationProtocols, isConnect,
this, args.WebSession.UpStreamEndPoint ?? UpStreamEndPoint,
customUpStreamProxy ?? (isHttps ? UpStreamHttpsProxy : UpStreamHttpProxy),
noCache, cancellationToken);
}
/// <summary>
/// Invoke before request handler if it is set.
/// </summary>
......
......@@ -65,9 +65,10 @@ namespace Titanium.Web.Proxy
{
//don't pass cancellation token here
//it could cause floating server connections when client exits
prefetchConnectionTask = tcpConnectionFactory.GetClient(httpsHostName, endPoint.Port,
null, true, null, false, this,
UpStreamEndPoint, UpStreamHttpsProxy, false, CancellationToken.None);
prefetchConnectionTask = tcpConnectionFactory.GetServerConnection(httpsHostName, endPoint.Port,
httpVersion: null, isHttps: true, applicationProtocols: null, isConnect: false,
proxyServer: this, upStreamEndPoint: UpStreamEndPoint, externalProxy: UpStreamHttpsProxy,
noCache: false, cancellationToken: CancellationToken.None);
SslStream sslStream = null;
......@@ -96,9 +97,10 @@ namespace Titanium.Web.Proxy
}
else
{
var connection = await tcpConnectionFactory.GetClient(httpsHostName, endPoint.Port,
null, false, null,
true, this, UpStreamEndPoint, UpStreamHttpsProxy, true, cancellationToken);
var connection = await tcpConnectionFactory.GetServerConnection(httpsHostName, endPoint.Port,
httpVersion: null, isHttps: false, applicationProtocols: null,
isConnect: true, proxyServer: this, upStreamEndPoint: UpStreamEndPoint,
externalProxy: UpStreamHttpsProxy, noCache: true, cancellationToken: cancellationToken);
try
{
......@@ -162,19 +164,9 @@ namespace Titanium.Web.Proxy
}
finally
{
if (!calledRequestHandler
&& prefetchConnectionTask != null)
if (!calledRequestHandler)
{
TcpServerConnection prefetchedConnection = null;
try
{
prefetchedConnection = await prefetchConnectionTask;
}
finally
{
await tcpConnectionFactory.Release(prefetchedConnection, closeServerConnection);
}
await tcpConnectionFactory.Release(prefetchConnectionTask, closeServerConnection);
}
clientStream.Dispose();
......
using StreamExtended.Network;
using System;
using System.Threading;
using System.Threading.Tasks;
using Titanium.Web.Proxy.EventArguments;
using Titanium.Web.Proxy.Exceptions;
using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Http;
using Titanium.Web.Proxy.Network.Tcp;
namespace Titanium.Web.Proxy
{
public partial class ProxyServer
{
/// <summary>
/// Handle upgrade to websocket
/// </summary>
private async Task handleWebSocketUpgrade(string httpCmd,
SessionEventArgs args, Request request, Response response,
CustomBufferedStream clientStream, HttpResponseWriter clientStreamWriter,
TcpServerConnection serverConnection,
CancellationTokenSource cancellationTokenSource, CancellationToken cancellationToken)
{
// prepare the prefix content
await serverConnection.StreamWriter.WriteLineAsync(httpCmd, cancellationToken);
await serverConnection.StreamWriter.WriteHeadersAsync(request.Headers,
cancellationToken: cancellationToken);
string httpStatus;
try
{
httpStatus = await serverConnection.Stream.ReadLineAsync(cancellationToken);
if (httpStatus == null)
{
throw new ServerConnectionException("Server connection was closed.");
}
}
catch (Exception e) when (!(e is ServerConnectionException))
{
throw new ServerConnectionException("Server connection was closed.", e);
}
Response.ParseResponseLine(httpStatus, out var responseVersion,
out int responseStatusCode,
out string responseStatusDescription);
response.HttpVersion = responseVersion;
response.StatusCode = responseStatusCode;
response.StatusDescription = responseStatusDescription;
await HeaderParser.ReadHeaders(serverConnection.Stream, response.Headers,
cancellationToken);
if (!args.IsTransparent)
{
await clientStreamWriter.WriteResponseAsync(response,
cancellationToken: cancellationToken);
}
// If user requested call back then do it
if (!args.WebSession.Response.Locked)
{
await invokeBeforeResponse(args);
}
await TcpHelper.SendRaw(clientStream, serverConnection.Stream, BufferPool, BufferSize,
(buffer, offset, count) => { args.OnDataSent(buffer, offset, count); },
(buffer, offset, count) => { args.OnDataReceived(buffer, offset, count); },
cancellationTokenSource, ExceptionFunc);
}
}
}
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Delegate AsyncEventHandler&lt;TEventArgs&gt;
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class BeforeSslAuthenticateEventArgs
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class CertificateSelectionEventArgs
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class CertificateValidationEventArgs
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class MultipartRequestPartSentEventArgs
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class SessionEventArgs
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class SessionEventArgsBase
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class TunnelConnectSessionEventArgs
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Namespace Titanium.Web.Proxy.EventArguments
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Delegate ExceptionHandler
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class BodyNotFoundException
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class ProxyAuthorizationException
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class ProxyException
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class ProxyHttpException
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Namespace Titanium.Web.Proxy.Exceptions
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class ConnectRequest
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class ConnectResponse
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class HeaderCollection
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class HttpWebClient
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class KnownHeaders
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class Request
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class RequestResponseBase
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class Response
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class GenericResponse
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class OkResponse
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class RedirectResponse
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Namespace Titanium.Web.Proxy.Http.Responses
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Namespace Titanium.Web.Proxy.Http
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class ExplicitProxyEndPoint
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class ExternalProxy
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class HttpHeader
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class ProxyEndPoint
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class TransparentProxyEndPoint
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Namespace Titanium.Web.Proxy.Models
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Enum CertificateEngine
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class CertificateManager
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Namespace Titanium.Web.Proxy.Network
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class ProxyServer
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......@@ -230,34 +230,6 @@ prompting for UAC if required?</p>
</h3>
<a id="Titanium_Web_Proxy_ProxyServer_AuthenticateUserFunc_" data-uid="Titanium.Web.Proxy.ProxyServer.AuthenticateUserFunc*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_AuthenticateUserFunc" data-uid="Titanium.Web.Proxy.ProxyServer.AuthenticateUserFunc">AuthenticateUserFunc</h4>
<div class="markdown level1 summary"><p>A callback to authenticate clients.
Parameters are username and password as provided by client.
Should return true for successful authentication.</p>
</div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public Func&lt;string, string, Task&lt;bool&gt;&gt; AuthenticateUserFunc { get; set; }</code></pre>
</div>
<h5 class="propertyValue">Property Value</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><a class="xref" href="https://docs.microsoft.com/dotnet/api/system.func-3">Func</a>&lt;<a class="xref" href="https://docs.microsoft.com/dotnet/api/system.string">String</a>, <a class="xref" href="https://docs.microsoft.com/dotnet/api/system.string">String</a>, <a class="xref" href="https://docs.microsoft.com/dotnet/api/system.threading.tasks.task-1">Task</a>&lt;<a class="xref" href="https://docs.microsoft.com/dotnet/api/system.boolean">Boolean</a>&gt;&gt;</td>
<td></td>
</tr>
</tbody>
</table>
<a id="Titanium_Web_Proxy_ProxyServer_BufferPool_" data-uid="Titanium.Web.Proxy.ProxyServer.BufferPool*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_BufferPool" data-uid="Titanium.Web.Proxy.ProxyServer.BufferPool">BufferPool</h4>
<div class="markdown level1 summary"><p>The buffer pool used throughout this proxy instance.
......@@ -613,14 +585,14 @@ Default value is 2.</p>
</table>
<a id="Titanium_Web_Proxy_ProxyServer_ProxyEndPoints_" data-uid="Titanium.Web.Proxy.ProxyServer.ProxyEndPoints*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_ProxyEndPoints" data-uid="Titanium.Web.Proxy.ProxyServer.ProxyEndPoints">ProxyEndPoints</h4>
<div class="markdown level1 summary"><p>A list of IpAddress and port this proxy is listening to.</p>
<a id="Titanium_Web_Proxy_ProxyServer_ProxyAuthenticationRealm_" data-uid="Titanium.Web.Proxy.ProxyServer.ProxyAuthenticationRealm*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_ProxyAuthenticationRealm" data-uid="Titanium.Web.Proxy.ProxyServer.ProxyAuthenticationRealm">ProxyAuthenticationRealm</h4>
<div class="markdown level1 summary"><p>Realm used during Proxy Basic Authentication.</p>
</div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public List&lt;ProxyEndPoint&gt; ProxyEndPoints { get; set; }</code></pre>
<pre><code class="lang-csharp hljs">public string ProxyAuthenticationRealm { get; set; }</code></pre>
</div>
<h5 class="propertyValue">Property Value</h5>
<table class="table table-bordered table-striped table-condensed">
......@@ -632,21 +604,22 @@ Default value is 2.</p>
</thead>
<tbody>
<tr>
<td><a class="xref" href="https://docs.microsoft.com/dotnet/api/system.collections.generic.list-1">List</a>&lt;<a class="xref" href="Titanium.Web.Proxy.Models.ProxyEndPoint.html">ProxyEndPoint</a>&gt;</td>
<td><a class="xref" href="https://docs.microsoft.com/dotnet/api/system.string">String</a></td>
<td></td>
</tr>
</tbody>
</table>
<a id="Titanium_Web_Proxy_ProxyServer_ProxyRealm_" data-uid="Titanium.Web.Proxy.ProxyServer.ProxyRealm*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_ProxyRealm" data-uid="Titanium.Web.Proxy.ProxyServer.ProxyRealm">ProxyRealm</h4>
<div class="markdown level1 summary"><p>Realm used during Proxy Basic Authentication.</p>
<a id="Titanium_Web_Proxy_ProxyServer_ProxyAuthenticationSchemes_" data-uid="Titanium.Web.Proxy.ProxyServer.ProxyAuthenticationSchemes*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_ProxyAuthenticationSchemes" data-uid="Titanium.Web.Proxy.ProxyServer.ProxyAuthenticationSchemes">ProxyAuthenticationSchemes</h4>
<div class="markdown level1 summary"><p>A collection of scheme types, e.g. basic, NTLM, Kerberos, Negotiate, to return if scheme authentication is required.
Works in relation with ProxySchemeAuthenticateFunc.</p>
</div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public string ProxyRealm { get; set; }</code></pre>
<pre><code class="lang-csharp hljs">public IEnumerable&lt;string&gt; ProxyAuthenticationSchemes { get; set; }</code></pre>
</div>
<h5 class="propertyValue">Property Value</h5>
<table class="table table-bordered table-striped table-condensed">
......@@ -658,7 +631,61 @@ Default value is 2.</p>
</thead>
<tbody>
<tr>
<td><a class="xref" href="https://docs.microsoft.com/dotnet/api/system.string">String</a></td>
<td><a class="xref" href="https://docs.microsoft.com/dotnet/api/system.collections.generic.ienumerable-1">IEnumerable</a>&lt;<a class="xref" href="https://docs.microsoft.com/dotnet/api/system.string">String</a>&gt;</td>
<td></td>
</tr>
</tbody>
</table>
<a id="Titanium_Web_Proxy_ProxyServer_ProxyBasicAuthenticateFunc_" data-uid="Titanium.Web.Proxy.ProxyServer.ProxyBasicAuthenticateFunc*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_ProxyBasicAuthenticateFunc" data-uid="Titanium.Web.Proxy.ProxyServer.ProxyBasicAuthenticateFunc">ProxyBasicAuthenticateFunc</h4>
<div class="markdown level1 summary"><p>A callback to authenticate proxy clients via basic authentication.
Parameters are username and password as provided by client.
Should return true for successful authentication.</p>
</div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public Func&lt;string, string, Task&lt;bool&gt;&gt; ProxyBasicAuthenticateFunc { get; set; }</code></pre>
</div>
<h5 class="propertyValue">Property Value</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><a class="xref" href="https://docs.microsoft.com/dotnet/api/system.func-3">Func</a>&lt;<a class="xref" href="https://docs.microsoft.com/dotnet/api/system.string">String</a>, <a class="xref" href="https://docs.microsoft.com/dotnet/api/system.string">String</a>, <a class="xref" href="https://docs.microsoft.com/dotnet/api/system.threading.tasks.task-1">Task</a>&lt;<a class="xref" href="https://docs.microsoft.com/dotnet/api/system.boolean">Boolean</a>&gt;&gt;</td>
<td></td>
</tr>
</tbody>
</table>
<a id="Titanium_Web_Proxy_ProxyServer_ProxyEndPoints_" data-uid="Titanium.Web.Proxy.ProxyServer.ProxyEndPoints*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_ProxyEndPoints" data-uid="Titanium.Web.Proxy.ProxyServer.ProxyEndPoints">ProxyEndPoints</h4>
<div class="markdown level1 summary"><p>A list of IpAddress and port this proxy is listening to.</p>
</div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public List&lt;ProxyEndPoint&gt; ProxyEndPoints { get; set; }</code></pre>
</div>
<h5 class="propertyValue">Property Value</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><a class="xref" href="https://docs.microsoft.com/dotnet/api/system.collections.generic.list-1">List</a>&lt;<a class="xref" href="Titanium.Web.Proxy.Models.ProxyEndPoint.html">ProxyEndPoint</a>&gt;</td>
<td></td>
</tr>
</tbody>
......@@ -691,6 +718,34 @@ Default value is 2.</p>
</table>
<a id="Titanium_Web_Proxy_ProxyServer_ProxySchemeAuthenticateFunc_" data-uid="Titanium.Web.Proxy.ProxyServer.ProxySchemeAuthenticateFunc*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_ProxySchemeAuthenticateFunc" data-uid="Titanium.Web.Proxy.ProxyServer.ProxySchemeAuthenticateFunc">ProxySchemeAuthenticateFunc</h4>
<div class="markdown level1 summary"><p>A pluggable callback to authenticate clients by scheme instead of requiring basic authentication through ProxyBasicAuthenticateFunc.
Parameters are current working session, schemeType, and token as provided by a calling client.
Should return success for successful authentication, continuation if the package requests, or failure.</p>
</div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public Func&lt;SessionEventArgsBase, string, string, Task&lt;ProxyAuthenticationContext&gt;&gt; ProxySchemeAuthenticateFunc { get; set; }</code></pre>
</div>
<h5 class="propertyValue">Property Value</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><a class="xref" href="https://docs.microsoft.com/dotnet/api/system.func-4">Func</a>&lt;<a class="xref" href="Titanium.Web.Proxy.EventArguments.SessionEventArgsBase.html">SessionEventArgsBase</a>, <a class="xref" href="https://docs.microsoft.com/dotnet/api/system.string">String</a>, <a class="xref" href="https://docs.microsoft.com/dotnet/api/system.string">String</a>, <a class="xref" href="https://docs.microsoft.com/dotnet/api/system.threading.tasks.task-1">Task</a>&lt;<span class="xref">ProxyAuthenticationContext</span>&gt;&gt;</td>
<td></td>
</tr>
</tbody>
</table>
<a id="Titanium_Web_Proxy_ProxyServer_ServerConnectionCount_" data-uid="Titanium.Web.Proxy.ProxyServer.ServerConnectionCount*"></a>
<h4 id="Titanium_Web_Proxy_ProxyServer_ServerConnectionCount" data-uid="Titanium.Web.Proxy.ProxyServer.ServerConnectionCount">ServerConnectionCount</h4>
<div class="markdown level1 summary"><p>Total number of active server connections.</p>
......
......@@ -10,7 +10,7 @@
<meta name="viewport" content="width=device-width">
<meta name="title" content="Namespace Titanium.Web.Proxy
| Titanium Web Proxy ">
<meta name="generator" content="docfx 2.35.4.0">
<meta name="generator" content="docfx 2.36.0.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
......
......@@ -192,6 +192,6 @@
"api/Titanium.Web.Proxy.ProxyServer.html": {
"href": "api/Titanium.Web.Proxy.ProxyServer.html",
"title": "Class ProxyServer | Titanium Web Proxy",
"keywords": "Class ProxyServer This class is the backbone of proxy. One can create as many instances as needed. However care should be taken to avoid using the same listening ports across multiple instances. Inheritance Object ProxyServer Implements IDisposable Inherited Members Object.ToString() Object.Equals(Object) Object.Equals(Object, Object) Object.ReferenceEquals(Object, Object) Object.GetHashCode() Object.GetType() Object.MemberwiseClone() Namespace : Titanium.Web.Proxy Assembly : Titanium.Web.Proxy.dll Syntax public class ProxyServer : IDisposable Constructors ProxyServer(Boolean, Boolean, Boolean) Initializes a new instance of ProxyServer class with provided parameters. Declaration public ProxyServer(bool userTrustRootCertificate = true, bool machineTrustRootCertificate = false, bool trustRootCertificateAsAdmin = false) Parameters Type Name Description Boolean userTrustRootCertificate Should fake HTTPS certificate be trusted by this machine's user certificate store? Boolean machineTrustRootCertificate Should fake HTTPS certificate be trusted by this machine's certificate store? Boolean trustRootCertificateAsAdmin Should we attempt to trust certificates with elevated permissions by prompting for UAC if required? ProxyServer(String, String, Boolean, Boolean, Boolean) Initializes a new instance of ProxyServer class with provided parameters. Declaration public ProxyServer(string rootCertificateName, string rootCertificateIssuerName, bool userTrustRootCertificate = true, bool machineTrustRootCertificate = false, bool trustRootCertificateAsAdmin = false) Parameters Type Name Description String rootCertificateName Name of the root certificate. String rootCertificateIssuerName Name of the root certificate issuer. Boolean userTrustRootCertificate Should fake HTTPS certificate be trusted by this machine's user certificate store? Boolean machineTrustRootCertificate Should fake HTTPS certificate be trusted by this machine's certificate store? Boolean trustRootCertificateAsAdmin Should we attempt to trust certificates with elevated permissions by prompting for UAC if required? Properties AuthenticateUserFunc A callback to authenticate clients. Parameters are username and password as provided by client. Should return true for successful authentication. Declaration public Func<string, string, Task<bool>> AuthenticateUserFunc { get; set; } Property Value Type Description Func < String , String , Task < Boolean >> BufferPool The buffer pool used throughout this proxy instance. Set custom implementations by implementing this interface. By default this uses DefaultBufferPool implementation available in StreamExtended library package. Declaration public IBufferPool BufferPool { get; set; } Property Value Type Description StreamExtended.IBufferPool BufferSize Buffer size in bytes used throughout this proxy. Default value is 8192 bytes. Declaration public int BufferSize { get; set; } Property Value Type Description Int32 CertificateManager Manages certificates used by this proxy. Declaration public CertificateManager CertificateManager { get; } Property Value Type Description CertificateManager CheckCertificateRevocation Should we check for certificare revocation during SSL authentication to servers Note: If enabled can reduce performance. Defaults to false. Declaration public X509RevocationMode CheckCertificateRevocation { get; set; } Property Value Type Description X509RevocationMode ClientConnectionCount Total number of active client connections. Declaration public int ClientConnectionCount { get; } Property Value Type Description Int32 ConnectionTimeOutSeconds Seconds client/server connection are to be kept alive when waiting for read/write to complete. This will also determine the pool eviction time when connection pool is enabled. Default value is 60 seconds. Declaration public int ConnectionTimeOutSeconds { get; set; } Property Value Type Description Int32 Enable100ContinueBehaviour Does this proxy uses the HTTP protocol 100 continue behaviour strictly? Broken 100 contunue implementations on server/client may cause problems if enabled. Defaults to false. Declaration public bool Enable100ContinueBehaviour { get; set; } Property Value Type Description Boolean EnableConnectionPool Should we enable experimental server connection pool? Defaults to disable. Declaration public bool EnableConnectionPool { get; set; } Property Value Type Description Boolean EnableWinAuth Enable disable Windows Authentication (NTLM/Kerberos). Note: NTLM/Kerberos will always send local credentials of current user running the proxy process. This is because a man in middle attack with Windows domain authentication is not currently supported. Defaults to false. Declaration public bool EnableWinAuth { get; set; } Property Value Type Description Boolean ExceptionFunc Callback for error events in this proxy instance. Declaration public ExceptionHandler ExceptionFunc { get; set; } Property Value Type Description ExceptionHandler ForwardToUpstreamGateway Gets or sets a value indicating whether requests will be chained to upstream gateway. Defaults to false. Declaration public bool ForwardToUpstreamGateway { get; set; } Property Value Type Description Boolean GetCustomUpStreamProxyFunc A callback to provide authentication credentials for up stream proxy this proxy is using for HTTP(S) requests. User should return the ExternalProxy object with valid credentials. Declaration public Func<SessionEventArgsBase, Task<ExternalProxy>> GetCustomUpStreamProxyFunc { get; set; } Property Value Type Description Func < SessionEventArgsBase , Task < ExternalProxy >> MaxCachedConnections Maximum number of concurrent connections per remote host in cache. Only valid when connection pooling is enabled. Default value is 2. Declaration public int MaxCachedConnections { get; set; } Property Value Type Description Int32 ProxyEndPoints A list of IpAddress and port this proxy is listening to. Declaration public List<ProxyEndPoint> ProxyEndPoints { get; set; } Property Value Type Description List < ProxyEndPoint > ProxyRealm Realm used during Proxy Basic Authentication. Declaration public string ProxyRealm { get; set; } Property Value Type Description String ProxyRunning Is the proxy currently running? Declaration public bool ProxyRunning { get; } Property Value Type Description Boolean ServerConnectionCount Total number of active server connections. Declaration public int ServerConnectionCount { get; } Property Value Type Description Int32 SupportedSslProtocols List of supported Ssl versions. Declaration public SslProtocols SupportedSslProtocols { get; set; } Property Value Type Description SslProtocols UpStreamEndPoint Local adapter/NIC endpoint where proxy makes request via. Defaults via any IP addresses of this machine. Declaration public IPEndPoint UpStreamEndPoint { get; set; } Property Value Type Description IPEndPoint UpStreamHttpProxy External proxy used for Http requests. Declaration public ExternalProxy UpStreamHttpProxy { get; set; } Property Value Type Description ExternalProxy UpStreamHttpsProxy External proxy used for Https requests. Declaration public ExternalProxy UpStreamHttpsProxy { get; set; } Property Value Type Description ExternalProxy Methods AddEndPoint(ProxyEndPoint) Add a proxy end point. Declaration public void AddEndPoint(ProxyEndPoint endPoint) Parameters Type Name Description ProxyEndPoint endPoint The proxy endpoint. DisableAllSystemProxies() Clear all proxy settings for current machine. Declaration public void DisableAllSystemProxies() DisableSystemHttpProxy() Clear HTTP proxy settings of current machine. Declaration public void DisableSystemHttpProxy() DisableSystemHttpsProxy() Clear HTTPS proxy settings of current machine. Declaration public void DisableSystemHttpsProxy() DisableSystemProxy(ProxyProtocolType) Clear the specified proxy setting for current machine. Declaration public void DisableSystemProxy(ProxyProtocolType protocolType) Parameters Type Name Description ProxyProtocolType protocolType Dispose() Dispose the Proxy instance. Declaration public void Dispose() RemoveEndPoint(ProxyEndPoint) Remove a proxy end point. Will throw error if the end point does'nt exist. Declaration public void RemoveEndPoint(ProxyEndPoint endPoint) Parameters Type Name Description ProxyEndPoint endPoint The existing endpoint to remove. SetAsSystemHttpProxy(ExplicitProxyEndPoint) Set the given explicit end point as the default proxy server for current machine. Declaration public void SetAsSystemHttpProxy(ExplicitProxyEndPoint endPoint) Parameters Type Name Description ExplicitProxyEndPoint endPoint The explicit endpoint. SetAsSystemHttpsProxy(ExplicitProxyEndPoint) Set the given explicit end point as the default proxy server for current machine. Declaration public void SetAsSystemHttpsProxy(ExplicitProxyEndPoint endPoint) Parameters Type Name Description ExplicitProxyEndPoint endPoint The explicit endpoint. SetAsSystemProxy(ExplicitProxyEndPoint, ProxyProtocolType) Set the given explicit end point as the default proxy server for current machine. Declaration public void SetAsSystemProxy(ExplicitProxyEndPoint endPoint, ProxyProtocolType protocolType) Parameters Type Name Description ExplicitProxyEndPoint endPoint The explicit endpoint. ProxyProtocolType protocolType The proxy protocol type. Start() Start this proxy server instance. Declaration public void Start() Stop() Stop this proxy server instance. Declaration public void Stop() Events AfterResponse Intercept after response event from server. Declaration public event AsyncEventHandler<SessionEventArgs> AfterResponse Event Type Type Description AsyncEventHandler < SessionEventArgs > BeforeRequest Intercept request event to server. Declaration public event AsyncEventHandler<SessionEventArgs> BeforeRequest Event Type Type Description AsyncEventHandler < SessionEventArgs > BeforeResponse Intercept response event from server. Declaration public event AsyncEventHandler<SessionEventArgs> BeforeResponse Event Type Type Description AsyncEventHandler < SessionEventArgs > ClientCertificateSelectionCallback Event to override client certificate selection during mutual SSL authentication. Declaration public event AsyncEventHandler<CertificateSelectionEventArgs> ClientCertificateSelectionCallback Event Type Type Description AsyncEventHandler < CertificateSelectionEventArgs > ClientConnectionCountChanged Event occurs when client connection count changed. Declaration public event EventHandler ClientConnectionCountChanged Event Type Type Description EventHandler OnClientConnectionCreate Customize TcpClient used for client connection upon create. Declaration public event AsyncEventHandler<TcpClient> OnClientConnectionCreate Event Type Type Description AsyncEventHandler < System.Net.Sockets.TcpClient > OnServerConnectionCreate Customize TcpClient used for server connection upon create. Declaration public event AsyncEventHandler<TcpClient> OnServerConnectionCreate Event Type Type Description AsyncEventHandler < System.Net.Sockets.TcpClient > ServerCertificateValidationCallback Event to override the default verification logic of remote SSL certificate received during authentication. Declaration public event AsyncEventHandler<CertificateValidationEventArgs> ServerCertificateValidationCallback Event Type Type Description AsyncEventHandler < CertificateValidationEventArgs > ServerConnectionCountChanged Event occurs when server connection count changed. Declaration public event EventHandler ServerConnectionCountChanged Event Type Type Description EventHandler Implements System.IDisposable"
"keywords": "Class ProxyServer This class is the backbone of proxy. One can create as many instances as needed. However care should be taken to avoid using the same listening ports across multiple instances. Inheritance Object ProxyServer Implements IDisposable Inherited Members Object.ToString() Object.Equals(Object) Object.Equals(Object, Object) Object.ReferenceEquals(Object, Object) Object.GetHashCode() Object.GetType() Object.MemberwiseClone() Namespace : Titanium.Web.Proxy Assembly : Titanium.Web.Proxy.dll Syntax public class ProxyServer : IDisposable Constructors ProxyServer(Boolean, Boolean, Boolean) Initializes a new instance of ProxyServer class with provided parameters. Declaration public ProxyServer(bool userTrustRootCertificate = true, bool machineTrustRootCertificate = false, bool trustRootCertificateAsAdmin = false) Parameters Type Name Description Boolean userTrustRootCertificate Should fake HTTPS certificate be trusted by this machine's user certificate store? Boolean machineTrustRootCertificate Should fake HTTPS certificate be trusted by this machine's certificate store? Boolean trustRootCertificateAsAdmin Should we attempt to trust certificates with elevated permissions by prompting for UAC if required? ProxyServer(String, String, Boolean, Boolean, Boolean) Initializes a new instance of ProxyServer class with provided parameters. Declaration public ProxyServer(string rootCertificateName, string rootCertificateIssuerName, bool userTrustRootCertificate = true, bool machineTrustRootCertificate = false, bool trustRootCertificateAsAdmin = false) Parameters Type Name Description String rootCertificateName Name of the root certificate. String rootCertificateIssuerName Name of the root certificate issuer. Boolean userTrustRootCertificate Should fake HTTPS certificate be trusted by this machine's user certificate store? Boolean machineTrustRootCertificate Should fake HTTPS certificate be trusted by this machine's certificate store? Boolean trustRootCertificateAsAdmin Should we attempt to trust certificates with elevated permissions by prompting for UAC if required? Properties BufferPool The buffer pool used throughout this proxy instance. Set custom implementations by implementing this interface. By default this uses DefaultBufferPool implementation available in StreamExtended library package. Declaration public IBufferPool BufferPool { get; set; } Property Value Type Description StreamExtended.IBufferPool BufferSize Buffer size in bytes used throughout this proxy. Default value is 8192 bytes. Declaration public int BufferSize { get; set; } Property Value Type Description Int32 CertificateManager Manages certificates used by this proxy. Declaration public CertificateManager CertificateManager { get; } Property Value Type Description CertificateManager CheckCertificateRevocation Should we check for certificare revocation during SSL authentication to servers Note: If enabled can reduce performance. Defaults to false. Declaration public X509RevocationMode CheckCertificateRevocation { get; set; } Property Value Type Description X509RevocationMode ClientConnectionCount Total number of active client connections. Declaration public int ClientConnectionCount { get; } Property Value Type Description Int32 ConnectionTimeOutSeconds Seconds client/server connection are to be kept alive when waiting for read/write to complete. This will also determine the pool eviction time when connection pool is enabled. Default value is 60 seconds. Declaration public int ConnectionTimeOutSeconds { get; set; } Property Value Type Description Int32 Enable100ContinueBehaviour Does this proxy uses the HTTP protocol 100 continue behaviour strictly? Broken 100 contunue implementations on server/client may cause problems if enabled. Defaults to false. Declaration public bool Enable100ContinueBehaviour { get; set; } Property Value Type Description Boolean EnableConnectionPool Should we enable experimental server connection pool? Defaults to disable. Declaration public bool EnableConnectionPool { get; set; } Property Value Type Description Boolean EnableWinAuth Enable disable Windows Authentication (NTLM/Kerberos). Note: NTLM/Kerberos will always send local credentials of current user running the proxy process. This is because a man in middle attack with Windows domain authentication is not currently supported. Defaults to false. Declaration public bool EnableWinAuth { get; set; } Property Value Type Description Boolean ExceptionFunc Callback for error events in this proxy instance. Declaration public ExceptionHandler ExceptionFunc { get; set; } Property Value Type Description ExceptionHandler ForwardToUpstreamGateway Gets or sets a value indicating whether requests will be chained to upstream gateway. Defaults to false. Declaration public bool ForwardToUpstreamGateway { get; set; } Property Value Type Description Boolean GetCustomUpStreamProxyFunc A callback to provide authentication credentials for up stream proxy this proxy is using for HTTP(S) requests. User should return the ExternalProxy object with valid credentials. Declaration public Func<SessionEventArgsBase, Task<ExternalProxy>> GetCustomUpStreamProxyFunc { get; set; } Property Value Type Description Func < SessionEventArgsBase , Task < ExternalProxy >> MaxCachedConnections Maximum number of concurrent connections per remote host in cache. Only valid when connection pooling is enabled. Default value is 2. Declaration public int MaxCachedConnections { get; set; } Property Value Type Description Int32 ProxyAuthenticationRealm Realm used during Proxy Basic Authentication. Declaration public string ProxyAuthenticationRealm { get; set; } Property Value Type Description String ProxyAuthenticationSchemes A collection of scheme types, e.g. basic, NTLM, Kerberos, Negotiate, to return if scheme authentication is required. Works in relation with ProxySchemeAuthenticateFunc. Declaration public IEnumerable<string> ProxyAuthenticationSchemes { get; set; } Property Value Type Description IEnumerable < String > ProxyBasicAuthenticateFunc A callback to authenticate proxy clients via basic authentication. Parameters are username and password as provided by client. Should return true for successful authentication. Declaration public Func<string, string, Task<bool>> ProxyBasicAuthenticateFunc { get; set; } Property Value Type Description Func < String , String , Task < Boolean >> ProxyEndPoints A list of IpAddress and port this proxy is listening to. Declaration public List<ProxyEndPoint> ProxyEndPoints { get; set; } Property Value Type Description List < ProxyEndPoint > ProxyRunning Is the proxy currently running? Declaration public bool ProxyRunning { get; } Property Value Type Description Boolean ProxySchemeAuthenticateFunc A pluggable callback to authenticate clients by scheme instead of requiring basic authentication through ProxyBasicAuthenticateFunc. Parameters are current working session, schemeType, and token as provided by a calling client. Should return success for successful authentication, continuation if the package requests, or failure. Declaration public Func<SessionEventArgsBase, string, string, Task<ProxyAuthenticationContext>> ProxySchemeAuthenticateFunc { get; set; } Property Value Type Description Func < SessionEventArgsBase , String , String , Task < ProxyAuthenticationContext >> ServerConnectionCount Total number of active server connections. Declaration public int ServerConnectionCount { get; } Property Value Type Description Int32 SupportedSslProtocols List of supported Ssl versions. Declaration public SslProtocols SupportedSslProtocols { get; set; } Property Value Type Description SslProtocols UpStreamEndPoint Local adapter/NIC endpoint where proxy makes request via. Defaults via any IP addresses of this machine. Declaration public IPEndPoint UpStreamEndPoint { get; set; } Property Value Type Description IPEndPoint UpStreamHttpProxy External proxy used for Http requests. Declaration public ExternalProxy UpStreamHttpProxy { get; set; } Property Value Type Description ExternalProxy UpStreamHttpsProxy External proxy used for Https requests. Declaration public ExternalProxy UpStreamHttpsProxy { get; set; } Property Value Type Description ExternalProxy Methods AddEndPoint(ProxyEndPoint) Add a proxy end point. Declaration public void AddEndPoint(ProxyEndPoint endPoint) Parameters Type Name Description ProxyEndPoint endPoint The proxy endpoint. DisableAllSystemProxies() Clear all proxy settings for current machine. Declaration public void DisableAllSystemProxies() DisableSystemHttpProxy() Clear HTTP proxy settings of current machine. Declaration public void DisableSystemHttpProxy() DisableSystemHttpsProxy() Clear HTTPS proxy settings of current machine. Declaration public void DisableSystemHttpsProxy() DisableSystemProxy(ProxyProtocolType) Clear the specified proxy setting for current machine. Declaration public void DisableSystemProxy(ProxyProtocolType protocolType) Parameters Type Name Description ProxyProtocolType protocolType Dispose() Dispose the Proxy instance. Declaration public void Dispose() RemoveEndPoint(ProxyEndPoint) Remove a proxy end point. Will throw error if the end point does'nt exist. Declaration public void RemoveEndPoint(ProxyEndPoint endPoint) Parameters Type Name Description ProxyEndPoint endPoint The existing endpoint to remove. SetAsSystemHttpProxy(ExplicitProxyEndPoint) Set the given explicit end point as the default proxy server for current machine. Declaration public void SetAsSystemHttpProxy(ExplicitProxyEndPoint endPoint) Parameters Type Name Description ExplicitProxyEndPoint endPoint The explicit endpoint. SetAsSystemHttpsProxy(ExplicitProxyEndPoint) Set the given explicit end point as the default proxy server for current machine. Declaration public void SetAsSystemHttpsProxy(ExplicitProxyEndPoint endPoint) Parameters Type Name Description ExplicitProxyEndPoint endPoint The explicit endpoint. SetAsSystemProxy(ExplicitProxyEndPoint, ProxyProtocolType) Set the given explicit end point as the default proxy server for current machine. Declaration public void SetAsSystemProxy(ExplicitProxyEndPoint endPoint, ProxyProtocolType protocolType) Parameters Type Name Description ExplicitProxyEndPoint endPoint The explicit endpoint. ProxyProtocolType protocolType The proxy protocol type. Start() Start this proxy server instance. Declaration public void Start() Stop() Stop this proxy server instance. Declaration public void Stop() Events AfterResponse Intercept after response event from server. Declaration public event AsyncEventHandler<SessionEventArgs> AfterResponse Event Type Type Description AsyncEventHandler < SessionEventArgs > BeforeRequest Intercept request event to server. Declaration public event AsyncEventHandler<SessionEventArgs> BeforeRequest Event Type Type Description AsyncEventHandler < SessionEventArgs > BeforeResponse Intercept response event from server. Declaration public event AsyncEventHandler<SessionEventArgs> BeforeResponse Event Type Type Description AsyncEventHandler < SessionEventArgs > ClientCertificateSelectionCallback Event to override client certificate selection during mutual SSL authentication. Declaration public event AsyncEventHandler<CertificateSelectionEventArgs> ClientCertificateSelectionCallback Event Type Type Description AsyncEventHandler < CertificateSelectionEventArgs > ClientConnectionCountChanged Event occurs when client connection count changed. Declaration public event EventHandler ClientConnectionCountChanged Event Type Type Description EventHandler OnClientConnectionCreate Customize TcpClient used for client connection upon create. Declaration public event AsyncEventHandler<TcpClient> OnClientConnectionCreate Event Type Type Description AsyncEventHandler < System.Net.Sockets.TcpClient > OnServerConnectionCreate Customize TcpClient used for server connection upon create. Declaration public event AsyncEventHandler<TcpClient> OnServerConnectionCreate Event Type Type Description AsyncEventHandler < System.Net.Sockets.TcpClient > ServerCertificateValidationCallback Event to override the default verification logic of remote SSL certificate received during authentication. Declaration public event AsyncEventHandler<CertificateValidationEventArgs> ServerCertificateValidationCallback Event Type Type Description AsyncEventHandler < CertificateValidationEventArgs > ServerConnectionCountChanged Event occurs when server connection count changed. Declaration public event EventHandler ServerConnectionCountChanged Event Type Type Description EventHandler Implements System.IDisposable"
}
}
......@@ -544,7 +544,7 @@ $(function () {
if ($('footer').is(':visible')) {
$(".sideaffix").css("bottom", "70px");
}
$('#affix a').click((e) => {
$('#affix a').click(function() {
var scrollspy = $('[data-spy="scroll"]').data()['bs.scrollspy'];
var target = e.target.hash;
if (scrollspy && target) {
......
......@@ -2622,19 +2622,6 @@ references:
commentId: E:Titanium.Web.Proxy.ProxyServer.AfterResponse
fullName: Titanium.Web.Proxy.ProxyServer.AfterResponse
nameWithType: ProxyServer.AfterResponse
- uid: Titanium.Web.Proxy.ProxyServer.AuthenticateUserFunc
name: AuthenticateUserFunc
href: api/Titanium.Web.Proxy.ProxyServer.html#Titanium_Web_Proxy_ProxyServer_AuthenticateUserFunc
commentId: P:Titanium.Web.Proxy.ProxyServer.AuthenticateUserFunc
fullName: Titanium.Web.Proxy.ProxyServer.AuthenticateUserFunc
nameWithType: ProxyServer.AuthenticateUserFunc
- uid: Titanium.Web.Proxy.ProxyServer.AuthenticateUserFunc*
name: AuthenticateUserFunc
href: api/Titanium.Web.Proxy.ProxyServer.html#Titanium_Web_Proxy_ProxyServer_AuthenticateUserFunc_
commentId: Overload:Titanium.Web.Proxy.ProxyServer.AuthenticateUserFunc
isSpec: "True"
fullName: Titanium.Web.Proxy.ProxyServer.AuthenticateUserFunc
nameWithType: ProxyServer.AuthenticateUserFunc
- uid: Titanium.Web.Proxy.ProxyServer.BeforeRequest
name: BeforeRequest
href: api/Titanium.Web.Proxy.ProxyServer.html#Titanium_Web_Proxy_ProxyServer_BeforeRequest
......@@ -2905,6 +2892,45 @@ references:
commentId: E:Titanium.Web.Proxy.ProxyServer.OnServerConnectionCreate
fullName: Titanium.Web.Proxy.ProxyServer.OnServerConnectionCreate
nameWithType: ProxyServer.OnServerConnectionCreate
- uid: Titanium.Web.Proxy.ProxyServer.ProxyAuthenticationRealm
name: ProxyAuthenticationRealm
href: api/Titanium.Web.Proxy.ProxyServer.html#Titanium_Web_Proxy_ProxyServer_ProxyAuthenticationRealm
commentId: P:Titanium.Web.Proxy.ProxyServer.ProxyAuthenticationRealm
fullName: Titanium.Web.Proxy.ProxyServer.ProxyAuthenticationRealm
nameWithType: ProxyServer.ProxyAuthenticationRealm
- uid: Titanium.Web.Proxy.ProxyServer.ProxyAuthenticationRealm*
name: ProxyAuthenticationRealm
href: api/Titanium.Web.Proxy.ProxyServer.html#Titanium_Web_Proxy_ProxyServer_ProxyAuthenticationRealm_
commentId: Overload:Titanium.Web.Proxy.ProxyServer.ProxyAuthenticationRealm
isSpec: "True"
fullName: Titanium.Web.Proxy.ProxyServer.ProxyAuthenticationRealm
nameWithType: ProxyServer.ProxyAuthenticationRealm
- uid: Titanium.Web.Proxy.ProxyServer.ProxyAuthenticationSchemes
name: ProxyAuthenticationSchemes
href: api/Titanium.Web.Proxy.ProxyServer.html#Titanium_Web_Proxy_ProxyServer_ProxyAuthenticationSchemes
commentId: P:Titanium.Web.Proxy.ProxyServer.ProxyAuthenticationSchemes
fullName: Titanium.Web.Proxy.ProxyServer.ProxyAuthenticationSchemes
nameWithType: ProxyServer.ProxyAuthenticationSchemes
- uid: Titanium.Web.Proxy.ProxyServer.ProxyAuthenticationSchemes*
name: ProxyAuthenticationSchemes
href: api/Titanium.Web.Proxy.ProxyServer.html#Titanium_Web_Proxy_ProxyServer_ProxyAuthenticationSchemes_
commentId: Overload:Titanium.Web.Proxy.ProxyServer.ProxyAuthenticationSchemes
isSpec: "True"
fullName: Titanium.Web.Proxy.ProxyServer.ProxyAuthenticationSchemes
nameWithType: ProxyServer.ProxyAuthenticationSchemes
- uid: Titanium.Web.Proxy.ProxyServer.ProxyBasicAuthenticateFunc
name: ProxyBasicAuthenticateFunc
href: api/Titanium.Web.Proxy.ProxyServer.html#Titanium_Web_Proxy_ProxyServer_ProxyBasicAuthenticateFunc
commentId: P:Titanium.Web.Proxy.ProxyServer.ProxyBasicAuthenticateFunc
fullName: Titanium.Web.Proxy.ProxyServer.ProxyBasicAuthenticateFunc
nameWithType: ProxyServer.ProxyBasicAuthenticateFunc
- uid: Titanium.Web.Proxy.ProxyServer.ProxyBasicAuthenticateFunc*
name: ProxyBasicAuthenticateFunc
href: api/Titanium.Web.Proxy.ProxyServer.html#Titanium_Web_Proxy_ProxyServer_ProxyBasicAuthenticateFunc_
commentId: Overload:Titanium.Web.Proxy.ProxyServer.ProxyBasicAuthenticateFunc
isSpec: "True"
fullName: Titanium.Web.Proxy.ProxyServer.ProxyBasicAuthenticateFunc
nameWithType: ProxyServer.ProxyBasicAuthenticateFunc
- uid: Titanium.Web.Proxy.ProxyServer.ProxyEndPoints
name: ProxyEndPoints
href: api/Titanium.Web.Proxy.ProxyServer.html#Titanium_Web_Proxy_ProxyServer_ProxyEndPoints
......@@ -2918,19 +2944,6 @@ references:
isSpec: "True"
fullName: Titanium.Web.Proxy.ProxyServer.ProxyEndPoints
nameWithType: ProxyServer.ProxyEndPoints
- uid: Titanium.Web.Proxy.ProxyServer.ProxyRealm
name: ProxyRealm
href: api/Titanium.Web.Proxy.ProxyServer.html#Titanium_Web_Proxy_ProxyServer_ProxyRealm
commentId: P:Titanium.Web.Proxy.ProxyServer.ProxyRealm
fullName: Titanium.Web.Proxy.ProxyServer.ProxyRealm
nameWithType: ProxyServer.ProxyRealm
- uid: Titanium.Web.Proxy.ProxyServer.ProxyRealm*
name: ProxyRealm
href: api/Titanium.Web.Proxy.ProxyServer.html#Titanium_Web_Proxy_ProxyServer_ProxyRealm_
commentId: Overload:Titanium.Web.Proxy.ProxyServer.ProxyRealm
isSpec: "True"
fullName: Titanium.Web.Proxy.ProxyServer.ProxyRealm
nameWithType: ProxyServer.ProxyRealm
- uid: Titanium.Web.Proxy.ProxyServer.ProxyRunning
name: ProxyRunning
href: api/Titanium.Web.Proxy.ProxyServer.html#Titanium_Web_Proxy_ProxyServer_ProxyRunning
......@@ -2944,6 +2957,19 @@ references:
isSpec: "True"
fullName: Titanium.Web.Proxy.ProxyServer.ProxyRunning
nameWithType: ProxyServer.ProxyRunning
- uid: Titanium.Web.Proxy.ProxyServer.ProxySchemeAuthenticateFunc
name: ProxySchemeAuthenticateFunc
href: api/Titanium.Web.Proxy.ProxyServer.html#Titanium_Web_Proxy_ProxyServer_ProxySchemeAuthenticateFunc
commentId: P:Titanium.Web.Proxy.ProxyServer.ProxySchemeAuthenticateFunc
fullName: Titanium.Web.Proxy.ProxyServer.ProxySchemeAuthenticateFunc
nameWithType: ProxyServer.ProxySchemeAuthenticateFunc
- uid: Titanium.Web.Proxy.ProxyServer.ProxySchemeAuthenticateFunc*
name: ProxySchemeAuthenticateFunc
href: api/Titanium.Web.Proxy.ProxyServer.html#Titanium_Web_Proxy_ProxyServer_ProxySchemeAuthenticateFunc_
commentId: Overload:Titanium.Web.Proxy.ProxyServer.ProxySchemeAuthenticateFunc
isSpec: "True"
fullName: Titanium.Web.Proxy.ProxyServer.ProxySchemeAuthenticateFunc
nameWithType: ProxyServer.ProxySchemeAuthenticateFunc
- uid: Titanium.Web.Proxy.ProxyServer.RemoveEndPoint(Titanium.Web.Proxy.Models.ProxyEndPoint)
name: RemoveEndPoint(ProxyEndPoint)
href: api/Titanium.Web.Proxy.ProxyServer.html#Titanium_Web_Proxy_ProxyServer_RemoveEndPoint_Titanium_Web_Proxy_Models_ProxyEndPoint_
......
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