From 17a4efec846e4129608434f73556d25c90657f36 Mon Sep 17 00:00:00 2001 From: Honfika Date: Sat, 20 Jul 2019 17:51:30 +0200 Subject: [PATCH 1/4] do not create wilcard certificate for ip addresses, #594 --- src/Titanium.Web.Proxy/Helpers/HttpHelper.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Titanium.Web.Proxy/Helpers/HttpHelper.cs b/src/Titanium.Web.Proxy/Helpers/HttpHelper.cs index 8527c2b89..f9751f752 100644 --- a/src/Titanium.Web.Proxy/Helpers/HttpHelper.cs +++ b/src/Titanium.Web.Proxy/Helpers/HttpHelper.cs @@ -1,4 +1,5 @@ using System; +using System.Net; using System.Text; using System.Text.RegularExpressions; using System.Threading; @@ -99,7 +100,13 @@ internal static string GetWildCardDomainName(string hostname) { // only for subdomains we need wild card // example www.google.com or gstatic.google.com - // but NOT for google.com + // but NOT for google.com or IP address + + if (IPAddress.TryParse(hostname, out _)) + { + return hostname; + } + if (hostname.Split(ProxyConstants.DotSplit).Length > 2) { int idx = hostname.IndexOf(ProxyConstants.DotSplit); From d90adbb13d685b515dca16bd245fabf21075d0ff Mon Sep 17 00:00:00 2001 From: Honfika Date: Sun, 21 Jul 2019 10:24:46 +0200 Subject: [PATCH 2/4] various fixes --- .../ProxyTestController.cs | 8 +- .../MainWindow.xaml | 1 + .../MainWindow.xaml.cs | 44 +++++- .../ExplicitClientHandler.cs | 13 +- .../Network/Tcp/TcpConnectionFactory.cs | 4 +- src/Titanium.Web.Proxy/ProxyServer.cs | 16 +- src/Titanium.Web.Proxy/RequestHandler.cs | 15 +- .../BufferPool/DefaultBufferPool.cs | 18 +-- .../StreamExtended/BufferPool/IBufferPool.cs | 1 + .../Network/CustomBufferedStream.cs | 143 +++++++++++++++--- .../StreamExtended/Network/TaskResult.cs | 58 +++++++ .../Titanium.Web.Proxy.Mono.csproj | 1 + .../Titanium.Web.Proxy.NetCore.csproj | 1 + .../Titanium.Web.Proxy.csproj | 1 + .../Titanium.Web.Proxy.nuspec | 2 + .../TransparentClientHandler.cs | 12 +- 16 files changed, 272 insertions(+), 66 deletions(-) create mode 100644 src/Titanium.Web.Proxy/StreamExtended/Network/TaskResult.cs diff --git a/examples/Titanium.Web.Proxy.Examples.Basic/ProxyTestController.cs b/examples/Titanium.Web.Proxy.Examples.Basic/ProxyTestController.cs index 04681b95c..6f1e6446c 100644 --- a/examples/Titanium.Web.Proxy.Examples.Basic/ProxyTestController.cs +++ b/examples/Titanium.Web.Proxy.Examples.Basic/ProxyTestController.cs @@ -119,7 +119,7 @@ public void Stop() private async Task onBeforeTunnelConnectRequest(object sender, TunnelConnectSessionEventArgs e) { string hostname = e.HttpClient.Request.RequestUri.Host; - await writeToConsole("Tunnel to: " + hostname); + //await writeToConsole("Tunnel to: " + hostname); if (hostname.Contains("dropbox.com")) { @@ -138,8 +138,8 @@ private Task onBeforeTunnelConnectResponse(object sender, TunnelConnectSessionEv // intecept & cancel redirect or update requests private async Task onRequest(object sender, SessionEventArgs e) { - await writeToConsole("Active Client Connections:" + ((ProxyServer)sender).ClientConnectionCount); - await writeToConsole(e.HttpClient.Request.Url); + //await writeToConsole("Active Client Connections:" + ((ProxyServer)sender).ClientConnectionCount); + //await writeToConsole(e.HttpClient.Request.Url); // store it in the UserData property // It can be a simple integer, Guid, or any type @@ -189,7 +189,7 @@ private async Task multipartRequestPartSent(object sender, MultipartRequestPartS private async Task onResponse(object sender, SessionEventArgs e) { - await writeToConsole("Active Server Connections:" + ((ProxyServer)sender).ServerConnectionCount); + //await writeToConsole("Active Server Connections:" + ((ProxyServer)sender).ServerConnectionCount); string ext = System.IO.Path.GetExtension(e.HttpClient.Request.RequestUri.AbsolutePath); diff --git a/examples/Titanium.Web.Proxy.Examples.Wpf/MainWindow.xaml b/examples/Titanium.Web.Proxy.Examples.Wpf/MainWindow.xaml index 1739dedcf..ec5e4ff33 100644 --- a/examples/Titanium.Web.Proxy.Examples.Wpf/MainWindow.xaml +++ b/examples/Titanium.Web.Proxy.Examples.Wpf/MainWindow.xaml @@ -54,6 +54,7 @@ + diff --git a/examples/Titanium.Web.Proxy.Examples.Wpf/MainWindow.xaml.cs b/examples/Titanium.Web.Proxy.Examples.Wpf/MainWindow.xaml.cs index 7293df085..e09defe8d 100644 --- a/examples/Titanium.Web.Proxy.Examples.Wpf/MainWindow.xaml.cs +++ b/examples/Titanium.Web.Proxy.Examples.Wpf/MainWindow.xaml.cs @@ -8,6 +8,7 @@ using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; +using System.Windows.Controls.Primitives; using System.Windows.Input; using System.Windows.Media.Imaging; using Titanium.Web.Proxy.EventArguments; @@ -95,7 +96,7 @@ public MainWindow() Dispatcher.Invoke(() => { ServerConnectionCount = proxyServer.ServerConnectionCount; }); }; proxyServer.Start(); - + proxyServer.SetAsSystemProxy(explicitEndPoint, ProxyProtocolType.AllHttp); InitializeComponent(); @@ -284,15 +285,26 @@ private void ListViewSessions_OnKeyDown(object sender, KeyEventArgs e) { if (e.Key == Key.Delete) { + bool isSelected = false; var selectedItems = ((ListView)sender).SelectedItems; Sessions.SuppressNotification = true; foreach (var item in selectedItems.Cast().ToArray()) { + if (item == SelectedSession) + { + isSelected = true; + } + Sessions.Remove(item); sessionDictionary.Remove(item.HttpClient); } Sessions.SuppressNotification = false; + + if (isSelected) + { + SelectedSession = null; + } } } @@ -300,6 +312,9 @@ private void selectedSessionChanged() { if (SelectedSession == null) { + TextBoxRequest.Text = null; + TextBoxResponse.Text = string.Empty; + ImageResponse.Source = null; return; } @@ -307,7 +322,7 @@ private void selectedSessionChanged() var session = SelectedSession.HttpClient; var request = session.Request; - var fullData = (request.IsBodyRead ? request.Body : null) ?? new byte[0]; + var fullData = (request.IsBodyRead ? request.Body : null) ?? Array.Empty(); var data = fullData; bool truncated = data.Length > truncateLimit; if (truncated) @@ -324,7 +339,7 @@ private void selectedSessionChanged() TextBoxRequest.Text = sb.ToString(); var response = session.Response; - fullData = (response.IsBodyRead ? response.Body : null) ?? new byte[0]; + fullData = (response.IsBodyRead ? response.Body : null) ?? Array.Empty(); data = fullData; truncated = data.Length > truncateLimit; if (truncated) @@ -348,10 +363,13 @@ private void selectedSessionChanged() try { - using (MemoryStream stream = new MemoryStream(fullData)) + if (fullData.Length > 0) { - ImageResponse.Source = - BitmapFrame.Create(stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad); + using (var stream = new MemoryStream(fullData)) + { + ImageResponse.Source = + BitmapFrame.Create(stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad); + } } } catch @@ -359,5 +377,19 @@ private void selectedSessionChanged() ImageResponse.Source = null; } } + + private void ButtonProxyOnOff_OnClick(object sender, RoutedEventArgs e) + { + var button = (ToggleButton)sender; + if (button.IsChecked == true) + { + proxyServer.SetAsSystemProxy((ExplicitProxyEndPoint)proxyServer.ProxyEndPoints[0], + ProxyProtocolType.AllHttp); + } + else + { + proxyServer.RestoreOriginalProxySettings(); + } + } } } diff --git a/src/Titanium.Web.Proxy/ExplicitClientHandler.cs b/src/Titanium.Web.Proxy/ExplicitClientHandler.cs index 3355aeb57..9bd7d4fc2 100644 --- a/src/Titanium.Web.Proxy/ExplicitClientHandler.cs +++ b/src/Titanium.Web.Proxy/ExplicitClientHandler.cs @@ -265,8 +265,8 @@ await clientStreamWriter.WriteResponseAsync(connectArgs.HttpClient.Response, try { - await clientStream.ReadAsync(data, 0, available, cancellationToken); // clientStream.Available should be at most BufferSize because it is using the same buffer size + await clientStream.ReadAsync(data, 0, available, cancellationToken); await connection.StreamWriter.WriteAsync(data, 0, available, true, cancellationToken); } finally @@ -279,10 +279,13 @@ await clientStreamWriter.WriteResponseAsync(connectArgs.HttpClient.Response, ((ConnectResponse)connectArgs.HttpClient.Response).ServerHelloInfo = serverHelloInfo; } - await TcpHelper.SendRaw(clientStream, connection.Stream, BufferPool, BufferSize, - (buffer, offset, count) => { connectArgs.OnDataSent(buffer, offset, count); }, - (buffer, offset, count) => { connectArgs.OnDataReceived(buffer, offset, count); }, - connectArgs.CancellationTokenSource, ExceptionFunc); + if (!clientStream.IsClosed && !connection.Stream.IsClosed) + { + await TcpHelper.SendRaw(clientStream, connection.Stream, BufferPool, BufferSize, + (buffer, offset, count) => { connectArgs.OnDataSent(buffer, offset, count); }, + (buffer, offset, count) => { connectArgs.OnDataReceived(buffer, offset, count); }, + connectArgs.CancellationTokenSource, ExceptionFunc); + } } finally { diff --git a/src/Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs b/src/Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs index 1d63db121..2f94734b8 100644 --- a/src/Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs +++ b/src/Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs @@ -481,6 +481,7 @@ private async Task clearOutdatedConnections() { try { + var cutOff = DateTime.Now.AddSeconds(-1 * Server.ConnectionTimeOutSeconds); foreach (var item in cache) { var queue = item.Value; @@ -489,7 +490,6 @@ private async Task clearOutdatedConnections() { if (queue.TryDequeue(out var connection)) { - var cutOff = DateTime.Now.AddSeconds(-1 * Server.ConnectionTimeOutSeconds); if (!Server.EnableConnectionPool || connection.LastAccess < cutOff) { @@ -512,7 +512,7 @@ private async Task clearOutdatedConnections() var emptyKeys = cache.Where(x => x.Value.Count == 0).Select(x => x.Key).ToList(); foreach (string key in emptyKeys) { - cache.TryRemove(key, out var _); + cache.TryRemove(key, out _); } } finally diff --git a/src/Titanium.Web.Proxy/ProxyServer.cs b/src/Titanium.Web.Proxy/ProxyServer.cs index 09868fa4d..c7c0bf5fd 100644 --- a/src/Titanium.Web.Proxy/ProxyServer.cs +++ b/src/Titanium.Web.Proxy/ProxyServer.cs @@ -516,6 +516,20 @@ public void DisableSystemHttpsProxy() DisableSystemProxy(ProxyProtocolType.Https); } + /// + /// Restores the original proxy settings. + /// + public void RestoreOriginalProxySettings() + { + if (!RunTime.IsWindows) + { + throw new NotSupportedException(@"Setting system proxy settings are only supported in Windows. + Please manually configure your operating system to use this proxy's port and address."); + } + + systemProxySettingsManager.RestoreOriginalSettings(); + } + /// /// Clear the specified proxy setting for current machine. /// @@ -524,7 +538,7 @@ public void DisableSystemProxy(ProxyProtocolType protocolType) if (!RunTime.IsWindows) { throw new NotSupportedException(@"Setting system proxy settings are only supported in Windows. - Please manually confugure you operating system to use this proxy's port and address."); + Please manually configure your operating system to use this proxy's port and address."); } systemProxySettingsManager.RemoveProxy(protocolType); diff --git a/src/Titanium.Web.Proxy/RequestHandler.cs b/src/Titanium.Web.Proxy/RequestHandler.cs index 749d0d0cf..e2d3628dd 100644 --- a/src/Titanium.Web.Proxy/RequestHandler.cs +++ b/src/Titanium.Web.Proxy/RequestHandler.cs @@ -65,6 +65,11 @@ private async Task handleHttpSessionRequest(ProxyEndPoint endPoint, TcpClientCon // (assuming HTTP connection is kept alive by client) while (true) { + if (clientStream.IsClosed) + { + return; + } + // read the request line string httpCmd = await clientStream.ReadLineAsync(cancellationToken); @@ -255,11 +260,11 @@ await clientStreamWriter.WriteResponseAsync(args.HttpClient.Response, throw new Exception("Session was terminated by user."); } - //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. - //Do not release authenticated connections for performance reasons. - //Otherwise it will keep authenticating per session. + // 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. + // Do not release authenticated connections for performance reasons. + // Otherwise it will keep authenticating per session. if (EnableConnectionPool && connection != null && !connection.IsWinAuthenticated) { diff --git a/src/Titanium.Web.Proxy/StreamExtended/BufferPool/DefaultBufferPool.cs b/src/Titanium.Web.Proxy/StreamExtended/BufferPool/DefaultBufferPool.cs index 4b6f57712..e3fbb507c 100644 --- a/src/Titanium.Web.Proxy/StreamExtended/BufferPool/DefaultBufferPool.cs +++ b/src/Titanium.Web.Proxy/StreamExtended/BufferPool/DefaultBufferPool.cs @@ -1,4 +1,5 @@ -using System.Collections.Concurrent; +using System.Buffers; +using System.Collections.Concurrent; namespace Titanium.Web.Proxy.StreamExtended.BufferPool { @@ -10,8 +11,6 @@ namespace Titanium.Web.Proxy.StreamExtended.BufferPool /// public class DefaultBufferPool : IBufferPool { - private readonly ConcurrentStack buffers = new ConcurrentStack(); - /// /// Gets a buffer. /// @@ -19,12 +18,7 @@ public class DefaultBufferPool : IBufferPool /// public byte[] GetBuffer(int bufferSize) { - if (!buffers.TryPop(out var buffer) || buffer.Length != bufferSize) - { - buffer = new byte[bufferSize]; - } - - return buffer; + return ArrayPool.Shared.Rent(bufferSize); } /// @@ -33,15 +27,11 @@ public byte[] GetBuffer(int bufferSize) /// The buffer. public void ReturnBuffer(byte[] buffer) { - if (buffer != null) - { - buffers.Push(buffer); - } + ArrayPool.Shared.Return(buffer); } public void Dispose() { - buffers.Clear(); } } } diff --git a/src/Titanium.Web.Proxy/StreamExtended/BufferPool/IBufferPool.cs b/src/Titanium.Web.Proxy/StreamExtended/BufferPool/IBufferPool.cs index 5ede12244..22ebed7e0 100644 --- a/src/Titanium.Web.Proxy/StreamExtended/BufferPool/IBufferPool.cs +++ b/src/Titanium.Web.Proxy/StreamExtended/BufferPool/IBufferPool.cs @@ -9,6 +9,7 @@ namespace Titanium.Web.Proxy.StreamExtended.BufferPool public interface IBufferPool : IDisposable { byte[] GetBuffer(int bufferSize); + void ReturnBuffer(byte[] buffer); } } diff --git a/src/Titanium.Web.Proxy/StreamExtended/Network/CustomBufferedStream.cs b/src/Titanium.Web.Proxy/StreamExtended/Network/CustomBufferedStream.cs index 36f03d383..40354d027 100644 --- a/src/Titanium.Web.Proxy/StreamExtended/Network/CustomBufferedStream.cs +++ b/src/Titanium.Web.Proxy/StreamExtended/Network/CustomBufferedStream.cs @@ -17,13 +17,14 @@ namespace Titanium.Web.Proxy.StreamExtended.Network /// public class CustomBufferedStream : Stream, ICustomStreamReader { - private readonly Stream baseStream; private readonly bool leaveOpen; private byte[] streamBuffer; // default to UTF-8 private static readonly Encoding encoding = Encoding.UTF8; + private static bool networkStreamHack = true; + private int bufferLength; private int bufferPos; @@ -40,8 +41,28 @@ public class CustomBufferedStream : Stream, ICustomStreamReader public event EventHandler DataWrite; + public Stream BaseStream { get; } + public bool IsClosed => closed; + static CustomBufferedStream() + { + // TODO: remove this hack when removing .NET 4.x support + try + { + var method = typeof(NetworkStream).GetMethod(nameof(Stream.ReadAsync), + new Type[] { typeof(byte[]), typeof(int), typeof(int), typeof(CancellationToken) }); + if (method != null && method.DeclaringType != typeof(Stream)) + { + networkStreamHack = false; + } + } + catch + { + // ignore + } + } + /// /// Initializes a new instance of the class. /// @@ -51,7 +72,7 @@ public class CustomBufferedStream : Stream, ICustomStreamReader /// to leave the stream open after disposing the object; otherwise, . public CustomBufferedStream(Stream baseStream, IBufferPool bufferPool, int bufferSize, bool leaveOpen = false) { - this.baseStream = baseStream; + BaseStream = baseStream; BufferSize = bufferSize; this.leaveOpen = leaveOpen; streamBuffer = bufferPool.GetBuffer(bufferSize); @@ -63,7 +84,7 @@ public CustomBufferedStream(Stream baseStream, IBufferPool bufferPool, int buffe /// public override void Flush() { - baseStream.Flush(); + BaseStream.Flush(); } /// @@ -78,7 +99,7 @@ public override long Seek(long offset, SeekOrigin origin) { bufferLength = 0; bufferPos = 0; - return baseStream.Seek(offset, origin); + return BaseStream.Seek(offset, origin); } /// @@ -87,7 +108,7 @@ public override long Seek(long offset, SeekOrigin origin) /// The desired length of the current stream in bytes. public override void SetLength(long value) { - baseStream.SetLength(value); + BaseStream.SetLength(value); } /// @@ -127,7 +148,7 @@ public override int Read(byte[] buffer, int offset, int count) public override void Write(byte[] buffer, int offset, int count) { OnDataWrite(buffer, offset, count); - baseStream.Write(buffer, offset, count); + BaseStream.Write(buffer, offset, count); } /// @@ -160,7 +181,7 @@ public override async Task CopyToAsync(Stream destination, int bufferSize, Cance /// public override Task FlushAsync(CancellationToken cancellationToken = default) { - return baseStream.FlushAsync(cancellationToken); + return BaseStream.FlushAsync(cancellationToken); } /// @@ -329,7 +350,7 @@ public override async Task WriteAsync(byte[] buffer, int offset, int count, Canc { OnDataWrite(buffer, offset, count); - await baseStream.WriteAsync(buffer, offset, count, cancellationToken); + await BaseStream.WriteAsync(buffer, offset, count, cancellationToken); } /// @@ -343,7 +364,7 @@ public override void WriteByte(byte value) { buffer[0] = value; OnDataWrite(buffer, 0, 1); - baseStream.Write(buffer, 0, 1); + BaseStream.Write(buffer, 0, 1); } finally { @@ -373,7 +394,7 @@ protected override void Dispose(bool disposing) closed = true; if (!leaveOpen) { - baseStream.Dispose(); + BaseStream.Dispose(); } var buffer = streamBuffer; @@ -385,27 +406,27 @@ protected override void Dispose(bool disposing) /// /// When overridden in a derived class, gets a value indicating whether the current stream supports reading. /// - public override bool CanRead => baseStream.CanRead; + public override bool CanRead => BaseStream.CanRead; /// /// When overridden in a derived class, gets a value indicating whether the current stream supports seeking. /// - public override bool CanSeek => baseStream.CanSeek; + public override bool CanSeek => BaseStream.CanSeek; /// /// When overridden in a derived class, gets a value indicating whether the current stream supports writing. /// - public override bool CanWrite => baseStream.CanWrite; + public override bool CanWrite => BaseStream.CanWrite; /// /// Gets a value that determines whether the current stream can time out. /// - public override bool CanTimeout => baseStream.CanTimeout; + public override bool CanTimeout => BaseStream.CanTimeout; /// /// When overridden in a derived class, gets the length in bytes of the stream. /// - public override long Length => baseStream.Length; + public override long Length => BaseStream.Length; /// /// Gets a value indicating whether data is available. @@ -422,8 +443,8 @@ protected override void Dispose(bool disposing) /// public override long Position { - get => baseStream.Position; - set => baseStream.Position = value; + get => BaseStream.Position; + set => BaseStream.Position = value; } /// @@ -431,8 +452,8 @@ public override long Position /// public override int ReadTimeout { - get => baseStream.ReadTimeout; - set => baseStream.ReadTimeout = value; + get => BaseStream.ReadTimeout; + set => BaseStream.ReadTimeout = value; } /// @@ -440,8 +461,8 @@ public override int ReadTimeout /// public override int WriteTimeout { - get => baseStream.WriteTimeout; - set => baseStream.WriteTimeout = value; + get => BaseStream.WriteTimeout; + set => BaseStream.WriteTimeout = value; } /// @@ -466,7 +487,7 @@ public bool FillBuffer() bool result = false; try { - int readBytes = baseStream.Read(streamBuffer, bufferLength, streamBuffer.Length - bufferLength); + int readBytes = BaseStream.Read(streamBuffer, bufferLength, streamBuffer.Length - bufferLength); result = readBytes > 0; if (result) { @@ -516,7 +537,7 @@ public async Task FillBufferAsync(CancellationToken cancellationToken = de bool result = false; try { - int readBytes = await baseStream.ReadAsync(streamBuffer, bufferLength, bytesToRead, cancellationToken); + int readBytes = await BaseStream.ReadAsync(streamBuffer, bufferLength, bytesToRead, cancellationToken); result = readBytes > 0; if (result) { @@ -622,5 +643,81 @@ private static void ResizeBuffer(ref byte[] buffer, long size) Buffer.BlockCopy(buffer, 0, newBuffer, 0, buffer.Length); buffer = newBuffer; } + + /// + /// Base Stream.BeginRead will call this.Read and block thread (we don't want this, Network stream handles async) + /// In order to really async Reading Launch this.ReadAsync as Task will fire NetworkStream.ReadAsync + /// See Threads here : + /// https://github.com/justcoding121/Stream-Extended/pull/43 + /// https://github.com/justcoding121/Titanium-Web-Proxy/issues/575 + /// + /// + public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) + { + if (!networkStreamHack) + { + return base.BeginRead(buffer, offset, count, callback, state); + } + + var vAsyncResult = this.ReadAsync(buffer, offset, count); + + vAsyncResult.ContinueWith(pAsyncResult => + { + //use TaskExtended to pass State as AsyncObject + //callback will call EndRead (otherwise, it will block) + callback?.Invoke(new TaskResult(pAsyncResult, state)); + }); + + return vAsyncResult; + } + + /// + /// override EndRead to handle async Reading (see BeginRead comment) + /// + /// + public override int EndRead(IAsyncResult asyncResult) + { + if (!networkStreamHack) + { + return base.EndRead(asyncResult); + } + + return ((TaskResult)asyncResult).Result; + } + + + /// + /// Fix the .net bug with SslStream slow WriteAsync + /// https://github.com/justcoding121/Titanium-Web-Proxy/issues/495 + /// Stream.BeginWrite + Stream.BeginRead uses the same SemaphoreSlim(1) + /// That's why we need to call NetworkStream.BeginWrite only (while read is waiting SemaphoreSlim) + /// + /// + public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) + { + if (!networkStreamHack) + { + return base.BeginWrite(buffer, offset, count, callback, state); + } + + var vAsyncResult = this.WriteAsync(buffer, offset, count); + + vAsyncResult.ContinueWith(pAsyncResult => + { + callback?.Invoke(new TaskResult(pAsyncResult, state)); + }); + + return vAsyncResult; + } + public override void EndWrite(IAsyncResult asyncResult) + { + if (!networkStreamHack) + { + base.EndWrite(asyncResult); + return; + } + + ((TaskResult)asyncResult).GetResult(); + } } } diff --git a/src/Titanium.Web.Proxy/StreamExtended/Network/TaskResult.cs b/src/Titanium.Web.Proxy/StreamExtended/Network/TaskResult.cs new file mode 100644 index 000000000..42553c2d3 --- /dev/null +++ b/src/Titanium.Web.Proxy/StreamExtended/Network/TaskResult.cs @@ -0,0 +1,58 @@ +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Titanium.Web.Proxy.StreamExtended.Network +{ + /// + /// Mimic a Task but you can set AsyncState + /// + /// + public class TaskResult : IAsyncResult + { + Task Task; + readonly object asyncState; + + public TaskResult(Task pTask, object state) + { + Task = pTask; + asyncState = state; + } + + public object AsyncState => asyncState; + + public WaitHandle AsyncWaitHandle => ((IAsyncResult)Task).AsyncWaitHandle; + + public bool CompletedSynchronously => ((IAsyncResult)Task).CompletedSynchronously; + + public bool IsCompleted => Task.IsCompleted; + + public void GetResult() { this.Task.GetAwaiter().GetResult(); } + } + + /// + /// Mimic a Task but you can set AsyncState + /// + /// + public class TaskResult : IAsyncResult + { + Task Task; + readonly object asyncState; + + public TaskResult(Task pTask, object state) + { + Task = pTask; + asyncState = state; + } + + public object AsyncState => asyncState; + + public WaitHandle AsyncWaitHandle => ((IAsyncResult)Task).AsyncWaitHandle; + + public bool CompletedSynchronously => ((IAsyncResult)Task).CompletedSynchronously; + + public bool IsCompleted => Task.IsCompleted; + + public T Result => Task.Result; + } +} diff --git a/src/Titanium.Web.Proxy/Titanium.Web.Proxy.Mono.csproj b/src/Titanium.Web.Proxy/Titanium.Web.Proxy.Mono.csproj index 29b27d8a3..636db9e7f 100644 --- a/src/Titanium.Web.Proxy/Titanium.Web.Proxy.Mono.csproj +++ b/src/Titanium.Web.Proxy/Titanium.Web.Proxy.Mono.csproj @@ -14,6 +14,7 @@ + diff --git a/src/Titanium.Web.Proxy/Titanium.Web.Proxy.NetCore.csproj b/src/Titanium.Web.Proxy/Titanium.Web.Proxy.NetCore.csproj index d912073e5..3424aa405 100644 --- a/src/Titanium.Web.Proxy/Titanium.Web.Proxy.NetCore.csproj +++ b/src/Titanium.Web.Proxy/Titanium.Web.Proxy.NetCore.csproj @@ -14,6 +14,7 @@ + diff --git a/src/Titanium.Web.Proxy/Titanium.Web.Proxy.csproj b/src/Titanium.Web.Proxy/Titanium.Web.Proxy.csproj index d912073e5..3424aa405 100644 --- a/src/Titanium.Web.Proxy/Titanium.Web.Proxy.csproj +++ b/src/Titanium.Web.Proxy/Titanium.Web.Proxy.csproj @@ -14,6 +14,7 @@ + diff --git a/src/Titanium.Web.Proxy/Titanium.Web.Proxy.nuspec b/src/Titanium.Web.Proxy/Titanium.Web.Proxy.nuspec index ebf37e733..d186b7440 100644 --- a/src/Titanium.Web.Proxy/Titanium.Web.Proxy.nuspec +++ b/src/Titanium.Web.Proxy/Titanium.Web.Proxy.nuspec @@ -18,12 +18,14 @@ + + diff --git a/src/Titanium.Web.Proxy/TransparentClientHandler.cs b/src/Titanium.Web.Proxy/TransparentClientHandler.cs index 786bebf34..4a63772d9 100644 --- a/src/Titanium.Web.Proxy/TransparentClientHandler.cs +++ b/src/Titanium.Web.Proxy/TransparentClientHandler.cs @@ -103,7 +103,6 @@ private async Task handleClient(TransparentProxyEndPoint endPoint, TcpClientConn try { - CustomBufferedStream serverStream = null; int available = clientStream.Available; if (available > 0) @@ -114,9 +113,7 @@ private async Task handleClient(TransparentProxyEndPoint endPoint, TcpClientConn { // clientStream.Available should be at most BufferSize because it is using the same buffer size await clientStream.ReadAsync(data, 0, available, cancellationToken); - serverStream = connection.Stream; - await serverStream.WriteAsync(data, 0, available, cancellationToken); - await serverStream.FlushAsync(cancellationToken); + await connection.StreamWriter.WriteAsync(data, 0, available, true, cancellationToken); } finally { @@ -124,8 +121,11 @@ private async Task handleClient(TransparentProxyEndPoint endPoint, TcpClientConn } } - await TcpHelper.SendRaw(clientStream, serverStream, BufferPool, BufferSize, - null, null, cancellationTokenSource, ExceptionFunc); + if (!clientStream.IsClosed && !connection.Stream.IsClosed) + { + await TcpHelper.SendRaw(clientStream, connection.Stream, BufferPool, BufferSize, + null, null, cancellationTokenSource, ExceptionFunc); + } } finally { From 721e395f2fec2b9eeedf15685286aa225cffabee Mon Sep 17 00:00:00 2001 From: Honfika Date: Sun, 21 Jul 2019 10:28:56 +0200 Subject: [PATCH 3/4] make a field readonly --- .../StreamExtended/Network/CustomBufferedStream.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Titanium.Web.Proxy/StreamExtended/Network/CustomBufferedStream.cs b/src/Titanium.Web.Proxy/StreamExtended/Network/CustomBufferedStream.cs index 40354d027..766a4e0ec 100644 --- a/src/Titanium.Web.Proxy/StreamExtended/Network/CustomBufferedStream.cs +++ b/src/Titanium.Web.Proxy/StreamExtended/Network/CustomBufferedStream.cs @@ -23,7 +23,7 @@ public class CustomBufferedStream : Stream, ICustomStreamReader // default to UTF-8 private static readonly Encoding encoding = Encoding.UTF8; - private static bool networkStreamHack = true; + private static readonly bool networkStreamHack = true; private int bufferLength; From 1b3d813a68f98e18cbf3e9a30bba7d76905d0188 Mon Sep 17 00:00:00 2001 From: buildbot121 Date: Sun, 21 Jul 2019 08:29:44 +0000 Subject: [PATCH 4/4] API documentation update by build server --- docs/api/Titanium.Web.Proxy.ProxyServer.html | 26 ++++++++++++++++---- docs/index.json | 2 +- docs/xrefmap.yml | 13 ++++++++++ 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/docs/api/Titanium.Web.Proxy.ProxyServer.html b/docs/api/Titanium.Web.Proxy.ProxyServer.html index addbcda01..6b938cbd6 100644 --- a/docs/api/Titanium.Web.Proxy.ProxyServer.html +++ b/docs/api/Titanium.Web.Proxy.ProxyServer.html @@ -1245,7 +1245,7 @@
Parameters
Improve this Doc - View Source + View Source

DisableAllSystemProxies()

@@ -1293,7 +1293,7 @@
Declaration
Improve this Doc - View Source + View Source

DisableSystemProxy(ProxyProtocolType)

@@ -1326,7 +1326,7 @@
Parameters
Improve this Doc - View Source + View Source

Dispose()

@@ -1372,6 +1372,22 @@
Parameters
+ + | + Improve this Doc + + + View Source + + +

RestoreOriginalProxySettings()

+

Restores the original proxy settings.

+
+
+
Declaration
+
+
public void RestoreOriginalProxySettings()
+
| Improve this Doc @@ -1485,7 +1501,7 @@
Parameters
Improve this Doc
- View Source + View Source

Start()

@@ -1501,7 +1517,7 @@
Declaration
Improve this Doc - View Source + View Source

Stop()

diff --git a/docs/index.json b/docs/index.json index fe5747d49..895f512f7 100644 --- a/docs/index.json +++ b/docs/index.json @@ -277,6 +277,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.Equals(Object) Object.Equals(Object, Object) Object.GetHashCode() Object.GetType() Object.MemberwiseClone() Object.ReferenceEquals(Object, Object) Object.ToString() Namespace : Titanium.Web.Proxy Assembly : Titanium.Web.Proxy.dll Syntax public class ProxyServer : IDisposable Constructors | Improve this Doc View Source 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? | Improve this Doc View Source 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 | Improve this Doc View Source 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 IBufferPool | Improve this Doc View Source 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 | Improve this Doc View Source CertificateManager Manages certificates used by this proxy. Declaration public CertificateManager CertificateManager { get; } Property Value Type Description CertificateManager | Improve this Doc View Source CheckCertificateRevocation Should we check for certificate 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 | Improve this Doc View Source ClientConnectionCount Total number of active client connections. Declaration public int ClientConnectionCount { get; } Property Value Type Description Int32 | Improve this Doc View Source 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 | Improve this Doc View Source Enable100ContinueBehaviour Does this proxy uses the HTTP protocol 100 continue behaviour strictly? Broken 100 continue implementations on server/client may cause problems if enabled. Defaults to false. Declaration public bool Enable100ContinueBehaviour { get; set; } Property Value Type Description Boolean | Improve this Doc View Source EnableConnectionPool Should we enable experimental server connection pool? Defaults to true. Declaration public bool EnableConnectionPool { get; set; } Property Value Type Description Boolean | Improve this Doc View Source EnableHttp2 Enable disable HTTP/2 support. Warning: HTTP/2 support is very limited only enabled when both client and server supports it (no protocol changing in proxy) cannot modify the request/response (e.g header modifications in BeforeRequest/Response events are ignored) Declaration public bool EnableHttp2 { get; set; } Property Value Type Description Boolean | Improve this Doc View Source EnableTcpServerConnectionPrefetch Should we enable tcp server connection prefetching? When enabled, as soon as we receive a client connection we concurrently initiate corresponding server connection process using CONNECT hostname or SNI hostname on a separate task so that after parsing client request we will have the server connection immediately ready or in the process of getting ready. If a server connection is available in cache then this prefetch task will immediately return with the available connection from cache. Defaults to true. Declaration public bool EnableTcpServerConnectionPrefetch { get; set; } Property Value Type Description Boolean | Improve this Doc View Source 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 | Improve this Doc View Source ExceptionFunc Callback for error events in this proxy instance. Declaration public ExceptionHandler ExceptionFunc { get; set; } Property Value Type Description ExceptionHandler | Improve this Doc View Source 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 | Improve this Doc View Source 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> GetCustomUpStreamProxyFunc { get; set; } Property Value Type Description Func < SessionEventArgsBase , Task < ExternalProxy >> | Improve this Doc View Source 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 | Improve this Doc View Source NoDelay Gets or sets a Boolean value that specifies whether server and client stream Sockets are using the Nagle algorithm. Defaults to true, no nagle algorithm is used. Declaration public bool NoDelay { get; set; } Property Value Type Description Boolean | Improve this Doc View Source ProxyAuthenticationRealm Realm used during Proxy Basic Authentication. Declaration public string ProxyAuthenticationRealm { get; set; } Property Value Type Description String | Improve this Doc View Source 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 ProxyAuthenticationSchemes { get; set; } Property Value Type Description IEnumerable < String > | Improve this Doc View Source 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> ProxyBasicAuthenticateFunc { get; set; } Property Value Type Description Func < SessionEventArgsBase , String , String , Task < Boolean >> | Improve this Doc View Source ProxyEndPoints A list of IpAddress and port this proxy is listening to. Declaration public List ProxyEndPoints { get; set; } Property Value Type Description List < ProxyEndPoint > | Improve this Doc View Source ProxyRunning Is the proxy currently running? Declaration public bool ProxyRunning { get; } Property Value Type Description Boolean | Improve this Doc View Source 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> ProxySchemeAuthenticateFunc { get; set; } Property Value Type Description Func < SessionEventArgsBase , String , String , Task < ProxyAuthenticationContext >> | Improve this Doc View Source ReuseSocket Should we reuse client/server tcp sockets. Default is true (disabled for linux/macOS due to bug in .Net core). Declaration public bool ReuseSocket { get; set; } Property Value Type Description Boolean | Improve this Doc View Source ServerConnectionCount Total number of active server connections. Declaration public int ServerConnectionCount { get; } Property Value Type Description Int32 | Improve this Doc View Source SupportedSslProtocols List of supported Ssl versions. Declaration public SslProtocols SupportedSslProtocols { get; set; } Property Value Type Description SslProtocols | Improve this Doc View Source TcpTimeWaitSeconds Number of seconds to linger when Tcp connection is in TIME_WAIT state. Default value is 30. Declaration public int TcpTimeWaitSeconds { get; set; } Property Value Type Description Int32 | Improve this Doc View Source ThreadPoolWorkerThread Customize the minimum ThreadPool size (increase it on a server) Declaration public int ThreadPoolWorkerThread { get; set; } Property Value Type Description Int32 | Improve this Doc View Source 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 | Improve this Doc View Source UpStreamHttpProxy External proxy used for Http requests. Declaration public ExternalProxy UpStreamHttpProxy { get; set; } Property Value Type Description ExternalProxy | Improve this Doc View Source UpStreamHttpsProxy External proxy used for Https requests. Declaration public ExternalProxy UpStreamHttpsProxy { get; set; } Property Value Type Description ExternalProxy Methods | Improve this Doc View Source AddEndPoint(ProxyEndPoint) Add a proxy end point. Declaration public void AddEndPoint(ProxyEndPoint endPoint) Parameters Type Name Description ProxyEndPoint endPoint The proxy endpoint. | Improve this Doc View Source DisableAllSystemProxies() Clear all proxy settings for current machine. Declaration public void DisableAllSystemProxies() | Improve this Doc View Source DisableSystemHttpProxy() Clear HTTP proxy settings of current machine. Declaration public void DisableSystemHttpProxy() | Improve this Doc View Source DisableSystemHttpsProxy() Clear HTTPS proxy settings of current machine. Declaration public void DisableSystemHttpsProxy() | Improve this Doc View Source DisableSystemProxy(ProxyProtocolType) Clear the specified proxy setting for current machine. Declaration public void DisableSystemProxy(ProxyProtocolType protocolType) Parameters Type Name Description ProxyProtocolType protocolType | Improve this Doc View Source Dispose() Dispose the Proxy instance. Declaration public void Dispose() | Improve this Doc View Source RemoveEndPoint(ProxyEndPoint) Remove a proxy end point. Will throw error if the end point doesn't exist. Declaration public void RemoveEndPoint(ProxyEndPoint endPoint) Parameters Type Name Description ProxyEndPoint endPoint The existing endpoint to remove. | Improve this Doc View Source 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. | Improve this Doc View Source 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. | Improve this Doc View Source 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. | Improve this Doc View Source Start() Start this proxy server instance. Declaration public void Start() | Improve this Doc View Source Stop() Stop this proxy server instance. Declaration public void Stop() Events | Improve this Doc View Source AfterResponse Intercept after response event from server. Declaration public event AsyncEventHandler AfterResponse Event Type Type Description AsyncEventHandler < SessionEventArgs > | Improve this Doc View Source BeforeRequest Intercept request event to server. Declaration public event AsyncEventHandler BeforeRequest Event Type Type Description AsyncEventHandler < SessionEventArgs > | Improve this Doc View Source BeforeResponse Intercept response event from server. Declaration public event AsyncEventHandler BeforeResponse Event Type Type Description AsyncEventHandler < SessionEventArgs > | Improve this Doc View Source ClientCertificateSelectionCallback Event to override client certificate selection during mutual SSL authentication. Declaration public event AsyncEventHandler ClientCertificateSelectionCallback Event Type Type Description AsyncEventHandler < CertificateSelectionEventArgs > | Improve this Doc View Source ClientConnectionCountChanged Event occurs when client connection count changed. Declaration public event EventHandler ClientConnectionCountChanged Event Type Type Description EventHandler | Improve this Doc View Source OnClientConnectionCreate Customize TcpClient used for client connection upon create. Declaration public event AsyncEventHandler OnClientConnectionCreate Event Type Type Description AsyncEventHandler < TcpClient > | Improve this Doc View Source OnServerConnectionCreate Customize TcpClient used for server connection upon create. Declaration public event AsyncEventHandler OnServerConnectionCreate Event Type Type Description AsyncEventHandler < TcpClient > | Improve this Doc View Source ServerCertificateValidationCallback Event to override the default verification logic of remote SSL certificate received during authentication. Declaration public event AsyncEventHandler ServerCertificateValidationCallback Event Type Type Description AsyncEventHandler < CertificateValidationEventArgs > | Improve this Doc View Source 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.Equals(Object) Object.Equals(Object, Object) Object.GetHashCode() Object.GetType() Object.MemberwiseClone() Object.ReferenceEquals(Object, Object) Object.ToString() Namespace : Titanium.Web.Proxy Assembly : Titanium.Web.Proxy.dll Syntax public class ProxyServer : IDisposable Constructors | Improve this Doc View Source 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? | Improve this Doc View Source 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 | Improve this Doc View Source 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 IBufferPool | Improve this Doc View Source 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 | Improve this Doc View Source CertificateManager Manages certificates used by this proxy. Declaration public CertificateManager CertificateManager { get; } Property Value Type Description CertificateManager | Improve this Doc View Source CheckCertificateRevocation Should we check for certificate 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 | Improve this Doc View Source ClientConnectionCount Total number of active client connections. Declaration public int ClientConnectionCount { get; } Property Value Type Description Int32 | Improve this Doc View Source 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 | Improve this Doc View Source Enable100ContinueBehaviour Does this proxy uses the HTTP protocol 100 continue behaviour strictly? Broken 100 continue implementations on server/client may cause problems if enabled. Defaults to false. Declaration public bool Enable100ContinueBehaviour { get; set; } Property Value Type Description Boolean | Improve this Doc View Source EnableConnectionPool Should we enable experimental server connection pool? Defaults to true. Declaration public bool EnableConnectionPool { get; set; } Property Value Type Description Boolean | Improve this Doc View Source EnableHttp2 Enable disable HTTP/2 support. Warning: HTTP/2 support is very limited only enabled when both client and server supports it (no protocol changing in proxy) cannot modify the request/response (e.g header modifications in BeforeRequest/Response events are ignored) Declaration public bool EnableHttp2 { get; set; } Property Value Type Description Boolean | Improve this Doc View Source EnableTcpServerConnectionPrefetch Should we enable tcp server connection prefetching? When enabled, as soon as we receive a client connection we concurrently initiate corresponding server connection process using CONNECT hostname or SNI hostname on a separate task so that after parsing client request we will have the server connection immediately ready or in the process of getting ready. If a server connection is available in cache then this prefetch task will immediately return with the available connection from cache. Defaults to true. Declaration public bool EnableTcpServerConnectionPrefetch { get; set; } Property Value Type Description Boolean | Improve this Doc View Source 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 | Improve this Doc View Source ExceptionFunc Callback for error events in this proxy instance. Declaration public ExceptionHandler ExceptionFunc { get; set; } Property Value Type Description ExceptionHandler | Improve this Doc View Source 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 | Improve this Doc View Source 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> GetCustomUpStreamProxyFunc { get; set; } Property Value Type Description Func < SessionEventArgsBase , Task < ExternalProxy >> | Improve this Doc View Source 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 | Improve this Doc View Source NoDelay Gets or sets a Boolean value that specifies whether server and client stream Sockets are using the Nagle algorithm. Defaults to true, no nagle algorithm is used. Declaration public bool NoDelay { get; set; } Property Value Type Description Boolean | Improve this Doc View Source ProxyAuthenticationRealm Realm used during Proxy Basic Authentication. Declaration public string ProxyAuthenticationRealm { get; set; } Property Value Type Description String | Improve this Doc View Source 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 ProxyAuthenticationSchemes { get; set; } Property Value Type Description IEnumerable < String > | Improve this Doc View Source 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> ProxyBasicAuthenticateFunc { get; set; } Property Value Type Description Func < SessionEventArgsBase , String , String , Task < Boolean >> | Improve this Doc View Source ProxyEndPoints A list of IpAddress and port this proxy is listening to. Declaration public List ProxyEndPoints { get; set; } Property Value Type Description List < ProxyEndPoint > | Improve this Doc View Source ProxyRunning Is the proxy currently running? Declaration public bool ProxyRunning { get; } Property Value Type Description Boolean | Improve this Doc View Source 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> ProxySchemeAuthenticateFunc { get; set; } Property Value Type Description Func < SessionEventArgsBase , String , String , Task < ProxyAuthenticationContext >> | Improve this Doc View Source ReuseSocket Should we reuse client/server tcp sockets. Default is true (disabled for linux/macOS due to bug in .Net core). Declaration public bool ReuseSocket { get; set; } Property Value Type Description Boolean | Improve this Doc View Source ServerConnectionCount Total number of active server connections. Declaration public int ServerConnectionCount { get; } Property Value Type Description Int32 | Improve this Doc View Source SupportedSslProtocols List of supported Ssl versions. Declaration public SslProtocols SupportedSslProtocols { get; set; } Property Value Type Description SslProtocols | Improve this Doc View Source TcpTimeWaitSeconds Number of seconds to linger when Tcp connection is in TIME_WAIT state. Default value is 30. Declaration public int TcpTimeWaitSeconds { get; set; } Property Value Type Description Int32 | Improve this Doc View Source ThreadPoolWorkerThread Customize the minimum ThreadPool size (increase it on a server) Declaration public int ThreadPoolWorkerThread { get; set; } Property Value Type Description Int32 | Improve this Doc View Source 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 | Improve this Doc View Source UpStreamHttpProxy External proxy used for Http requests. Declaration public ExternalProxy UpStreamHttpProxy { get; set; } Property Value Type Description ExternalProxy | Improve this Doc View Source UpStreamHttpsProxy External proxy used for Https requests. Declaration public ExternalProxy UpStreamHttpsProxy { get; set; } Property Value Type Description ExternalProxy Methods | Improve this Doc View Source AddEndPoint(ProxyEndPoint) Add a proxy end point. Declaration public void AddEndPoint(ProxyEndPoint endPoint) Parameters Type Name Description ProxyEndPoint endPoint The proxy endpoint. | Improve this Doc View Source DisableAllSystemProxies() Clear all proxy settings for current machine. Declaration public void DisableAllSystemProxies() | Improve this Doc View Source DisableSystemHttpProxy() Clear HTTP proxy settings of current machine. Declaration public void DisableSystemHttpProxy() | Improve this Doc View Source DisableSystemHttpsProxy() Clear HTTPS proxy settings of current machine. Declaration public void DisableSystemHttpsProxy() | Improve this Doc View Source DisableSystemProxy(ProxyProtocolType) Clear the specified proxy setting for current machine. Declaration public void DisableSystemProxy(ProxyProtocolType protocolType) Parameters Type Name Description ProxyProtocolType protocolType | Improve this Doc View Source Dispose() Dispose the Proxy instance. Declaration public void Dispose() | Improve this Doc View Source RemoveEndPoint(ProxyEndPoint) Remove a proxy end point. Will throw error if the end point doesn't exist. Declaration public void RemoveEndPoint(ProxyEndPoint endPoint) Parameters Type Name Description ProxyEndPoint endPoint The existing endpoint to remove. | Improve this Doc View Source RestoreOriginalProxySettings() Restores the original proxy settings. Declaration public void RestoreOriginalProxySettings() | Improve this Doc View Source 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. | Improve this Doc View Source 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. | Improve this Doc View Source 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. | Improve this Doc View Source Start() Start this proxy server instance. Declaration public void Start() | Improve this Doc View Source Stop() Stop this proxy server instance. Declaration public void Stop() Events | Improve this Doc View Source AfterResponse Intercept after response event from server. Declaration public event AsyncEventHandler AfterResponse Event Type Type Description AsyncEventHandler < SessionEventArgs > | Improve this Doc View Source BeforeRequest Intercept request event to server. Declaration public event AsyncEventHandler BeforeRequest Event Type Type Description AsyncEventHandler < SessionEventArgs > | Improve this Doc View Source BeforeResponse Intercept response event from server. Declaration public event AsyncEventHandler BeforeResponse Event Type Type Description AsyncEventHandler < SessionEventArgs > | Improve this Doc View Source ClientCertificateSelectionCallback Event to override client certificate selection during mutual SSL authentication. Declaration public event AsyncEventHandler ClientCertificateSelectionCallback Event Type Type Description AsyncEventHandler < CertificateSelectionEventArgs > | Improve this Doc View Source ClientConnectionCountChanged Event occurs when client connection count changed. Declaration public event EventHandler ClientConnectionCountChanged Event Type Type Description EventHandler | Improve this Doc View Source OnClientConnectionCreate Customize TcpClient used for client connection upon create. Declaration public event AsyncEventHandler OnClientConnectionCreate Event Type Type Description AsyncEventHandler < TcpClient > | Improve this Doc View Source OnServerConnectionCreate Customize TcpClient used for server connection upon create. Declaration public event AsyncEventHandler OnServerConnectionCreate Event Type Type Description AsyncEventHandler < TcpClient > | Improve this Doc View Source ServerCertificateValidationCallback Event to override the default verification logic of remote SSL certificate received during authentication. Declaration public event AsyncEventHandler ServerCertificateValidationCallback Event Type Type Description AsyncEventHandler < CertificateValidationEventArgs > | Improve this Doc View Source ServerConnectionCountChanged Event occurs when server connection count changed. Declaration public event EventHandler ServerConnectionCountChanged Event Type Type Description EventHandler Implements System.IDisposable" } } diff --git a/docs/xrefmap.yml b/docs/xrefmap.yml index 64e7f4b74..e5b3def1c 100644 --- a/docs/xrefmap.yml +++ b/docs/xrefmap.yml @@ -3744,6 +3744,19 @@ references: isSpec: "True" fullName: Titanium.Web.Proxy.ProxyServer.RemoveEndPoint nameWithType: ProxyServer.RemoveEndPoint +- uid: Titanium.Web.Proxy.ProxyServer.RestoreOriginalProxySettings + name: RestoreOriginalProxySettings() + href: api/Titanium.Web.Proxy.ProxyServer.html#Titanium_Web_Proxy_ProxyServer_RestoreOriginalProxySettings + commentId: M:Titanium.Web.Proxy.ProxyServer.RestoreOriginalProxySettings + fullName: Titanium.Web.Proxy.ProxyServer.RestoreOriginalProxySettings() + nameWithType: ProxyServer.RestoreOriginalProxySettings() +- uid: Titanium.Web.Proxy.ProxyServer.RestoreOriginalProxySettings* + name: RestoreOriginalProxySettings + href: api/Titanium.Web.Proxy.ProxyServer.html#Titanium_Web_Proxy_ProxyServer_RestoreOriginalProxySettings_ + commentId: Overload:Titanium.Web.Proxy.ProxyServer.RestoreOriginalProxySettings + isSpec: "True" + fullName: Titanium.Web.Proxy.ProxyServer.RestoreOriginalProxySettings + nameWithType: ProxyServer.RestoreOriginalProxySettings - uid: Titanium.Web.Proxy.ProxyServer.ReuseSocket name: ReuseSocket href: api/Titanium.Web.Proxy.ProxyServer.html#Titanium_Web_Proxy_ProxyServer_ReuseSocket