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)
{
TcpServerConnection prefetchedConnection = null;
try
{
prefetchedConnection = await prefetchConnectionTask;
}
finally
if (!calledRequestHandler)
{
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;
}
}
}
......@@ -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,8 +38,49 @@ 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;
}
if (ProxyBasicAuthenticateFunc != null)
{
return await authenticateUserBasic(session, headerValueParts);
}
if (ProxySchemeAuthenticateFunc != null)
{
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 false;
}
catch (Exception e)
{
ExceptionFunc(new ProxyAuthorizationException("Error whilst authorizing request", session, e,
httpHeaders));
// Return not authorized
session.WebSession.Response = createAuthentication407Response("Proxy Authentication Invalid");
return false;
}
}
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");
......@@ -57,7 +98,7 @@ namespace Titanium.Web.Proxy
string username = decoded.Substring(0, colonIndex);
string password = decoded.Substring(colonIndex + 1);
bool authenticated = await AuthenticateUserFunc(username, password);
bool authenticated = await ProxyBasicAuthenticateFunc(username, password);
if (!authenticated)
{
session.WebSession.Response = createAuthentication407Response("Proxy Authentication Invalid");
......@@ -65,23 +106,13 @@ namespace Titanium.Web.Proxy
return authenticated;
}
catch (Exception e)
{
ExceptionFunc(new ProxyAuthorizationException("Error whilst authorizing request", session, e,
httpHeaders));
// Return not authorized
session.WebSession.Response = createAuthentication407Response("Proxy Authentication Invalid");
return false;
}
}
/// <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);
}
}
}
This diff is collapsed.
......@@ -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="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">
......
This diff is collapsed.
......@@ -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