diff --git a/examples/Titanium.Web.Proxy.Examples.Basic/ProxyEventArgsBaseExtensions.cs b/examples/Titanium.Web.Proxy.Examples.Basic/ProxyEventArgsBaseExtensions.cs new file mode 100644 index 000000000..7bda444f5 --- /dev/null +++ b/examples/Titanium.Web.Proxy.Examples.Basic/ProxyEventArgsBaseExtensions.cs @@ -0,0 +1,17 @@ +using Titanium.Web.Proxy.EventArguments; + +namespace Titanium.Web.Proxy.Examples.Basic +{ + public static class ProxyEventArgsBaseExtensions + { + public static SampleClientState GetState(this ProxyEventArgsBase args) + { + if (args.ClientUserData == null) + { + args.ClientUserData = new SampleClientState(); + } + + return (SampleClientState)args.ClientUserData; + } + } +} diff --git a/examples/Titanium.Web.Proxy.Examples.Basic/ProxyTestController.cs b/examples/Titanium.Web.Proxy.Examples.Basic/ProxyTestController.cs index def5d9448..1f9d3ed16 100644 --- a/examples/Titanium.Web.Proxy.Examples.Basic/ProxyTestController.cs +++ b/examples/Titanium.Web.Proxy.Examples.Basic/ProxyTestController.cs @@ -1,10 +1,7 @@ using System; -using System.Collections.Concurrent; -using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Security; -using System.Text; using System.Threading; using System.Threading.Tasks; using Titanium.Web.Proxy.EventArguments; @@ -64,6 +61,7 @@ public void StartProxy() { proxyServer.BeforeRequest += onRequest; proxyServer.BeforeResponse += onResponse; + proxyServer.AfterResponse += onAfterResponse; proxyServer.ServerCertificateValidationCallback += OnCertificateValidation; proxyServer.ClientCertificateSelectionCallback += OnCertificateSelection; @@ -128,19 +126,32 @@ public void Stop() private async Task onGetCustomUpStreamProxyFunc(SessionEventArgsBase arg) { + arg.GetState().PipelineInfo.AppendLine(nameof(onGetCustomUpStreamProxyFunc)); + // this is just to show the functionality, provided values are junk - return new ExternalProxy() { BypassLocalhost = false, HostName = "127.0.0.9", Port = 9090, Password = "fake", UserName = "fake", UseDefaultCredentials = false }; + return new ExternalProxy + { + BypassLocalhost = false, HostName = "127.0.0.9", Port = 9090, Password = "fake", UserName = "fake", + UseDefaultCredentials = false + }; } private async Task onCustomUpStreamProxyFailureFunc(SessionEventArgsBase arg) { + arg.GetState().PipelineInfo.AppendLine(nameof(onCustomUpStreamProxyFailureFunc)); + // this is just to show the functionality, provided values are junk - return new ExternalProxy() { BypassLocalhost = false, HostName = "127.0.0.10", Port = 9191, Password = "fake2", UserName = "fake2", UseDefaultCredentials = false }; + return new ExternalProxy + { + BypassLocalhost = false, HostName = "127.0.0.10", Port = 9191, Password = "fake2", UserName = "fake2", + UseDefaultCredentials = false + }; } private async Task onBeforeTunnelConnectRequest(object sender, TunnelConnectSessionEventArgs e) { string hostname = e.HttpClient.Request.RequestUri.Host; + e.GetState().PipelineInfo.AppendLine(nameof(onBeforeTunnelConnectRequest) + ":" + hostname); await writeToConsole("Tunnel to: " + hostname); if (hostname.Contains("dropbox.com")) @@ -186,12 +197,16 @@ private void WebSocketDataSentReceived(SessionEventArgs args, DataEventArgs e, b private Task onBeforeTunnelConnectResponse(object sender, TunnelConnectSessionEventArgs e) { + e.GetState().PipelineInfo.AppendLine(nameof(onBeforeTunnelConnectResponse) + ":" + e.HttpClient.Request.RequestUri); + return Task.FromResult(false); } // intercept & cancel redirect or update requests private async Task onRequest(object sender, SessionEventArgs e) { + e.GetState().PipelineInfo.AppendLine(nameof(onRequest) + ":" + e.HttpClient.Request.RequestUri); + await writeToConsole("Active Client Connections:" + ((ProxyServer)sender).ClientConnectionCount); await writeToConsole(e.HttpClient.Request.Url); @@ -233,6 +248,8 @@ private async Task onRequest(object sender, SessionEventArgs e) // Modify response private async Task multipartRequestPartSent(object sender, MultipartRequestPartSentEventArgs e) { + e.GetState().PipelineInfo.AppendLine(nameof(multipartRequestPartSent)); + var session = (SessionEventArgs)sender; await writeToConsole("Multipart form data headers:"); foreach (var header in e.Headers) @@ -243,6 +260,8 @@ private async Task multipartRequestPartSent(object sender, MultipartRequestPartS private async Task onResponse(object sender, SessionEventArgs e) { + e.GetState().PipelineInfo.AppendLine(nameof(onResponse)); + if (e.HttpClient.ConnectRequest?.TunnelType == TunnelType.Websocket) { e.DataSent += WebSocket_DataSent; @@ -293,6 +312,11 @@ private async Task onResponse(object sender, SessionEventArgs e) //} } + private async Task onAfterResponse(object sender, SessionEventArgs e) + { + await writeToConsole($"Pipelineinfo: {e.GetState().PipelineInfo}", ConsoleColor.Yellow); + } + /// /// Allows overriding default certificate validation logic /// @@ -300,6 +324,8 @@ private async Task onResponse(object sender, SessionEventArgs e) /// public Task OnCertificateValidation(object sender, CertificateValidationEventArgs e) { + e.GetState().PipelineInfo.AppendLine(nameof(OnCertificateValidation)); + // set IsValid to true/false based on Certificate Errors if (e.SslPolicyErrors == SslPolicyErrors.None) { @@ -316,6 +342,8 @@ public Task OnCertificateValidation(object sender, CertificateValidationEventArg /// public Task OnCertificateSelection(object sender, CertificateSelectionEventArgs e) { + e.GetState().PipelineInfo.AppendLine(nameof(OnCertificateSelection)); + // set e.clientCertificate to override return Task.FromResult(0); @@ -352,3 +380,4 @@ private async Task writeToConsole(string message, ConsoleColor? consoleColor = n //} } } + diff --git a/examples/Titanium.Web.Proxy.Examples.Basic/SampleClientState.cs b/examples/Titanium.Web.Proxy.Examples.Basic/SampleClientState.cs new file mode 100644 index 000000000..163952680 --- /dev/null +++ b/examples/Titanium.Web.Proxy.Examples.Basic/SampleClientState.cs @@ -0,0 +1,10 @@ +using System; +using System.Text; + +namespace Titanium.Web.Proxy.Examples.Basic +{ + public class SampleClientState + { + public StringBuilder PipelineInfo { get; } = new StringBuilder(); + } +} diff --git a/examples/Titanium.Web.Proxy.Examples.Wpf/MainWindow.xaml.cs b/examples/Titanium.Web.Proxy.Examples.Wpf/MainWindow.xaml.cs index 51874112c..47211f090 100644 --- a/examples/Titanium.Web.Proxy.Examples.Wpf/MainWindow.xaml.cs +++ b/examples/Titanium.Web.Proxy.Examples.Wpf/MainWindow.xaml.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; using System.IO; using System.Linq; using System.Net; diff --git a/src/Titanium.Web.Proxy.sln.DotSettings b/src/Titanium.Web.Proxy.sln.DotSettings index c94f8bdbc..b5c76c8e9 100644 --- a/src/Titanium.Web.Proxy.sln.DotSettings +++ b/src/Titanium.Web.Proxy.sln.DotSettings @@ -10,6 +10,7 @@ False True 120 + System UseExplicitType UseVar BC diff --git a/src/Titanium.Web.Proxy/CertificateHandler.cs b/src/Titanium.Web.Proxy/CertificateHandler.cs index b7efcfbe5..c409746c8 100644 --- a/src/Titanium.Web.Proxy/CertificateHandler.cs +++ b/src/Titanium.Web.Proxy/CertificateHandler.cs @@ -12,17 +12,18 @@ public partial class ProxyServer /// Call back to override server certificate validation /// /// The sender object. + /// The http session. /// The remote certificate. /// The certificate chain. /// Ssl policy errors /// Return true if valid certificate. - internal bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, + internal bool ValidateServerCertificate(object sender, SessionEventArgsBase sessionArgs, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { // if user callback is registered then do it if (ServerCertificateValidationCallback != null) { - var args = new CertificateValidationEventArgs(certificate, chain, sslPolicyErrors); + var args = new CertificateValidationEventArgs(sessionArgs, certificate, chain, sslPolicyErrors); // why is the sender null? ServerCertificateValidationCallback.InvokeAsync(this, args, ExceptionFunc).Wait(); @@ -43,12 +44,13 @@ internal bool ValidateServerCertificate(object sender, X509Certificate certifica /// Call back to select client certificate used for mutual authentication /// /// The sender. + /// The http session. /// The remote hostname. /// Selected local certificates by SslStream. /// The remote certificate of server. /// The acceptable issues for client certificate as listed by server. /// - internal X509Certificate? SelectClientCertificate(object sender, string targetHost, + internal X509Certificate? SelectClientCertificate(object sender, SessionEventArgsBase sessionArgs, string targetHost, X509CertificateCollection localCertificates, X509Certificate remoteCertificate, string[] acceptableIssuers) { @@ -75,12 +77,8 @@ internal bool ValidateServerCertificate(object sender, X509Certificate certifica // If user call back is registered if (ClientCertificateSelectionCallback != null) { - var args = new CertificateSelectionEventArgs + var args = new CertificateSelectionEventArgs(sessionArgs, targetHost, localCertificates, remoteCertificate, acceptableIssuers) { - TargetHost = targetHost, - LocalCertificates = localCertificates, - RemoteCertificate = remoteCertificate, - AcceptableIssuers = acceptableIssuers, ClientCertificate = clientCertificate }; diff --git a/src/Titanium.Web.Proxy/Compression/CompressionFactory.cs b/src/Titanium.Web.Proxy/Compression/CompressionFactory.cs index 31ec1eb43..b01d52382 100644 --- a/src/Titanium.Web.Proxy/Compression/CompressionFactory.cs +++ b/src/Titanium.Web.Proxy/Compression/CompressionFactory.cs @@ -1,7 +1,6 @@ using System; using System.IO; using System.IO.Compression; -using Titanium.Web.Proxy.Http; namespace Titanium.Web.Proxy.Compression { diff --git a/src/Titanium.Web.Proxy/Compression/DecompressionFactory.cs b/src/Titanium.Web.Proxy/Compression/DecompressionFactory.cs index 37ae18eaf..e93017f4f 100644 --- a/src/Titanium.Web.Proxy/Compression/DecompressionFactory.cs +++ b/src/Titanium.Web.Proxy/Compression/DecompressionFactory.cs @@ -1,7 +1,6 @@ using System; using System.IO; using System.IO.Compression; -using Titanium.Web.Proxy.Http; namespace Titanium.Web.Proxy.Compression { diff --git a/src/Titanium.Web.Proxy/Compression/HttpCompression.cs b/src/Titanium.Web.Proxy/Compression/HttpCompression.cs index 8cae279f0..f14fb896e 100644 --- a/src/Titanium.Web.Proxy/Compression/HttpCompression.cs +++ b/src/Titanium.Web.Proxy/Compression/HttpCompression.cs @@ -1,4 +1,4 @@ -using System.IO.Compression; +using System; namespace Titanium.Web.Proxy.Compression { diff --git a/src/Titanium.Web.Proxy/EventArguments/BeforeSslAuthenticateEventArgs.cs b/src/Titanium.Web.Proxy/EventArguments/BeforeSslAuthenticateEventArgs.cs index 191a9bf1e..be9b0214f 100644 --- a/src/Titanium.Web.Proxy/EventArguments/BeforeSslAuthenticateEventArgs.cs +++ b/src/Titanium.Web.Proxy/EventArguments/BeforeSslAuthenticateEventArgs.cs @@ -1,16 +1,17 @@ using System; using System.Threading; +using Titanium.Web.Proxy.Network.Tcp; namespace Titanium.Web.Proxy.EventArguments { /// /// This is used in transparent endpoint before authenticating client. /// - public class BeforeSslAuthenticateEventArgs : EventArgs + public class BeforeSslAuthenticateEventArgs : ProxyEventArgsBase { internal readonly CancellationTokenSource TaskCancellationSource; - internal BeforeSslAuthenticateEventArgs(CancellationTokenSource taskCancellationSource, string sniHostName) + internal BeforeSslAuthenticateEventArgs(TcpClientConnection clientConnection, CancellationTokenSource taskCancellationSource, string sniHostName) : base(clientConnection) { TaskCancellationSource = taskCancellationSource; SniHostName = sniHostName; diff --git a/src/Titanium.Web.Proxy/EventArguments/CertificateSelectionEventArgs.cs b/src/Titanium.Web.Proxy/EventArguments/CertificateSelectionEventArgs.cs index 257d80ca0..fb9ca4d51 100644 --- a/src/Titanium.Web.Proxy/EventArguments/CertificateSelectionEventArgs.cs +++ b/src/Titanium.Web.Proxy/EventArguments/CertificateSelectionEventArgs.cs @@ -6,32 +6,42 @@ namespace Titanium.Web.Proxy.EventArguments /// /// An argument passed on to user for client certificate selection during mutual SSL authentication. /// - public class CertificateSelectionEventArgs : EventArgs + public class CertificateSelectionEventArgs : ProxyEventArgsBase { - /// - /// The proxy server instance. - /// - public object? Sender { get; internal set; } + public CertificateSelectionEventArgs(SessionEventArgsBase session, string targetHost, + X509CertificateCollection localCertificates, X509Certificate remoteCertificate, string[] acceptableIssuers) : base(session.ClientConnection) + { + Session = session; + TargetHost = targetHost; + LocalCertificates = localCertificates; + RemoteCertificate = remoteCertificate; + AcceptableIssuers = acceptableIssuers; + } + + /// + /// The session. + /// + public SessionEventArgsBase Session { get; } /// /// The remote hostname to which we are authenticating against. /// - public string? TargetHost { get; internal set; } + public string TargetHost { get; } /// /// Local certificates in store with matching issuers requested by TargetHost website. /// - public X509CertificateCollection? LocalCertificates { get; internal set; } + public X509CertificateCollection LocalCertificates { get; } /// /// Certificate of the remote server. /// - public X509Certificate? RemoteCertificate { get; internal set; } + public X509Certificate RemoteCertificate { get; } /// /// Acceptable issuers as listed by remote server. /// - public string[]? AcceptableIssuers { get; internal set; } + public string[] AcceptableIssuers { get; } /// /// Client Certificate we selected. Set this value to override. diff --git a/src/Titanium.Web.Proxy/EventArguments/CertificateValidationEventArgs.cs b/src/Titanium.Web.Proxy/EventArguments/CertificateValidationEventArgs.cs index 22e9bf381..89ba18bfc 100644 --- a/src/Titanium.Web.Proxy/EventArguments/CertificateValidationEventArgs.cs +++ b/src/Titanium.Web.Proxy/EventArguments/CertificateValidationEventArgs.cs @@ -8,15 +8,21 @@ namespace Titanium.Web.Proxy.EventArguments /// An argument passed on to the user for validating the server certificate /// during SSL authentication. /// - public class CertificateValidationEventArgs : EventArgs + public class CertificateValidationEventArgs : ProxyEventArgsBase { - public CertificateValidationEventArgs(X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) + public CertificateValidationEventArgs(SessionEventArgsBase session, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) : base(session.ClientConnection) { + Session = session; Certificate = certificate; Chain = chain; SslPolicyErrors = sslPolicyErrors; } + /// + /// The session. + /// + public SessionEventArgsBase Session { get; } + /// /// Server certificate. /// diff --git a/src/Titanium.Web.Proxy/EventArguments/MultipartRequestPartSentEventArgs.cs b/src/Titanium.Web.Proxy/EventArguments/MultipartRequestPartSentEventArgs.cs index 988b19fa7..22d4ead8a 100644 --- a/src/Titanium.Web.Proxy/EventArguments/MultipartRequestPartSentEventArgs.cs +++ b/src/Titanium.Web.Proxy/EventArguments/MultipartRequestPartSentEventArgs.cs @@ -1,19 +1,24 @@ -using System; -using Titanium.Web.Proxy.Http; +using Titanium.Web.Proxy.Http; namespace Titanium.Web.Proxy.EventArguments { /// /// Class that wraps the multipart sent request arguments. /// - public class MultipartRequestPartSentEventArgs : EventArgs + public class MultipartRequestPartSentEventArgs : ProxyEventArgsBase { - internal MultipartRequestPartSentEventArgs(string boundary, HeaderCollection headers) + internal MultipartRequestPartSentEventArgs(SessionEventArgs session, string boundary, HeaderCollection headers) : base(session.ClientConnection) { + Session = session; Boundary = boundary; Headers = headers; } + /// + /// The session arguments. + /// + public SessionEventArgs Session { get; } + /// /// Boundary. /// diff --git a/src/Titanium.Web.Proxy/EventArguments/ProxyEventArgsBase.cs b/src/Titanium.Web.Proxy/EventArguments/ProxyEventArgsBase.cs new file mode 100644 index 000000000..f115896f1 --- /dev/null +++ b/src/Titanium.Web.Proxy/EventArguments/ProxyEventArgsBase.cs @@ -0,0 +1,25 @@ +using System; +using Titanium.Web.Proxy.Network.Tcp; + +namespace Titanium.Web.Proxy.EventArguments +{ + /// + /// The base event arguments + /// + /// + public abstract class ProxyEventArgsBase : EventArgs + { + private readonly TcpClientConnection clientConnection; + + public object ClientUserData + { + get => clientConnection.ClientUserData; + set => clientConnection.ClientUserData = value; + } + + internal ProxyEventArgsBase(TcpClientConnection clientConnection) + { + this.clientConnection = clientConnection; + } + } +} diff --git a/src/Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs b/src/Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs index 176d41299..c55803426 100644 --- a/src/Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs +++ b/src/Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs @@ -8,7 +8,6 @@ using Titanium.Web.Proxy.Http; using Titanium.Web.Proxy.Http.Responses; using Titanium.Web.Proxy.Models; -using Titanium.Web.Proxy.Network.Tcp; using Titanium.Web.Proxy.StreamExtended.Network; namespace Titanium.Web.Proxy.EventArguments @@ -36,8 +35,8 @@ public class SessionEventArgs : SessionEventArgsBase /// /// Constructor to initialize the proxy /// - internal SessionEventArgs(ProxyServer server, ProxyEndPoint endPoint, TcpClientConnection clientConnection, HttpClientStream clientStream, ConnectRequest? connectRequest, CancellationTokenSource cancellationTokenSource) - : base(server, endPoint, clientConnection, clientStream, connectRequest, new Request(), cancellationTokenSource) + internal SessionEventArgs(ProxyServer server, ProxyEndPoint endPoint, HttpClientStream clientStream, ConnectRequest? connectRequest, CancellationTokenSource cancellationTokenSource) + : base(server, endPoint, clientStream, connectRequest, new Request(), cancellationTokenSource) { } @@ -127,7 +126,7 @@ internal void OnMultipartRequestPartSent(ReadOnlySpan boundary, HeaderColl { try { - MultipartRequestPartSent?.Invoke(this, new MultipartRequestPartSentEventArgs(boundary.ToString(), headers)); + MultipartRequestPartSent?.Invoke(this, new MultipartRequestPartSentEventArgs(this, boundary.ToString(), headers)); } catch (Exception ex) { diff --git a/src/Titanium.Web.Proxy/EventArguments/SessionEventArgsBase.cs b/src/Titanium.Web.Proxy/EventArguments/SessionEventArgsBase.cs index b6bdb5aef..11f09245a 100644 --- a/src/Titanium.Web.Proxy/EventArguments/SessionEventArgsBase.cs +++ b/src/Titanium.Web.Proxy/EventArguments/SessionEventArgsBase.cs @@ -5,7 +5,6 @@ using Titanium.Web.Proxy.Helpers; using Titanium.Web.Proxy.Http; using Titanium.Web.Proxy.Models; -using Titanium.Web.Proxy.Network; using Titanium.Web.Proxy.Network.Tcp; using Titanium.Web.Proxy.StreamExtended.BufferPool; using Titanium.Web.Proxy.StreamExtended.Network; @@ -18,7 +17,7 @@ namespace Titanium.Web.Proxy.EventArguments /// A proxy session ends when client terminates connection to proxy /// or when server terminates connection from proxy. /// - public abstract class SessionEventArgsBase : EventArgs, IDisposable + public abstract class SessionEventArgsBase : ProxyEventArgsBase, IDisposable { private static bool isWindowsAuthenticationSupported => RunTime.IsWindows; @@ -29,7 +28,7 @@ public abstract class SessionEventArgsBase : EventArgs, IDisposable /// /// Holds a reference to client /// - internal TcpClientConnection ClientConnection { get; } + internal TcpClientConnection ClientConnection => ClientStream.Connection; internal HttpClientStream ClientStream { get; } @@ -50,7 +49,7 @@ public abstract class SessionEventArgsBase : EventArgs, IDisposable /// Initializes a new instance of the class. /// private protected SessionEventArgsBase(ProxyServer server, ProxyEndPoint endPoint, - TcpClientConnection clientConnection, HttpClientStream clientStream, ConnectRequest? connectRequest, Request request, CancellationTokenSource cancellationTokenSource) + HttpClientStream clientStream, ConnectRequest? connectRequest, Request request, CancellationTokenSource cancellationTokenSource) : base(clientStream.Connection) { BufferPool = server.BufferPool; ExceptionFunc = server.ExceptionFunc; @@ -58,9 +57,8 @@ private protected SessionEventArgsBase(ProxyServer server, ProxyEndPoint endPoin CancellationTokenSource = cancellationTokenSource; - ClientConnection = clientConnection; ClientStream = clientStream; - HttpClient = new HttpWebClient(connectRequest, request, new Lazy(() => clientConnection.GetProcessId(endPoint))); + HttpClient = new HttpWebClient(connectRequest, request, new Lazy(() => clientStream.Connection.GetProcessId(endPoint))); LocalEndPoint = endPoint; EnableWinAuth = server.EnableWinAuth && isWindowsAuthenticationSupported; } diff --git a/src/Titanium.Web.Proxy/EventArguments/TunnelConnectEventArgs.cs b/src/Titanium.Web.Proxy/EventArguments/TunnelConnectEventArgs.cs index 494b51754..e41c1aa96 100644 --- a/src/Titanium.Web.Proxy/EventArguments/TunnelConnectEventArgs.cs +++ b/src/Titanium.Web.Proxy/EventArguments/TunnelConnectEventArgs.cs @@ -3,8 +3,6 @@ using Titanium.Web.Proxy.Helpers; using Titanium.Web.Proxy.Http; using Titanium.Web.Proxy.Models; -using Titanium.Web.Proxy.Network; -using Titanium.Web.Proxy.Network.Tcp; using Titanium.Web.Proxy.StreamExtended.Network; namespace Titanium.Web.Proxy.EventArguments @@ -17,8 +15,8 @@ public class TunnelConnectSessionEventArgs : SessionEventArgsBase private bool? isHttpsConnect; internal TunnelConnectSessionEventArgs(ProxyServer server, ProxyEndPoint endPoint, ConnectRequest connectRequest, - TcpClientConnection clientConnection, HttpClientStream clientStream, CancellationTokenSource cancellationTokenSource) - : base(server, endPoint, clientConnection, clientStream, connectRequest, connectRequest, cancellationTokenSource) + HttpClientStream clientStream, CancellationTokenSource cancellationTokenSource) + : base(server, endPoint, clientStream, connectRequest, connectRequest, cancellationTokenSource) { } diff --git a/src/Titanium.Web.Proxy/ExplicitClientHandler.cs b/src/Titanium.Web.Proxy/ExplicitClientHandler.cs index 6c029bf27..ac0baa6c5 100644 --- a/src/Titanium.Web.Proxy/ExplicitClientHandler.cs +++ b/src/Titanium.Web.Proxy/ExplicitClientHandler.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.IO; using System.Net; using System.Net.Security; @@ -14,10 +13,8 @@ using Titanium.Web.Proxy.Http; using Titanium.Web.Proxy.Http2; using Titanium.Web.Proxy.Models; -using Titanium.Web.Proxy.Network; using Titanium.Web.Proxy.Network.Tcp; using Titanium.Web.Proxy.StreamExtended; -using Titanium.Web.Proxy.StreamExtended.Network; using SslExtensions = Titanium.Web.Proxy.Extensions.SslExtensions; namespace Titanium.Web.Proxy @@ -36,7 +33,7 @@ private async Task handleClient(ExplicitProxyEndPoint endPoint, TcpClientConnect var cancellationTokenSource = new CancellationTokenSource(); var cancellationToken = cancellationTokenSource.Token; - var clientStream = new HttpClientStream(clientConnection.GetStream(), BufferPool); + var clientStream = new HttpClientStream(clientConnection, clientConnection.GetStream(), BufferPool); Task? prefetchConnectionTask = null; bool closeServerConnection = false; @@ -72,8 +69,7 @@ private async Task handleClient(ExplicitProxyEndPoint endPoint, TcpClientConnect await HeaderParser.ReadHeaders(clientStream, connectRequest.Headers, cancellationToken); - connectArgs = new TunnelConnectSessionEventArgs(this, endPoint, connectRequest, - clientConnection, clientStream, cancellationTokenSource); + connectArgs = new TunnelConnectSessionEventArgs(this, endPoint, connectRequest, clientStream, cancellationTokenSource); clientStream.DataRead += (o, args) => connectArgs.OnDataSent(args.Buffer, args.Offset, args.Count); clientStream.DataWrite += (o, args) => connectArgs.OnDataReceived(args.Buffer, args.Offset, args.Count); @@ -137,7 +133,7 @@ private async Task handleClient(ExplicitProxyEndPoint endPoint, TcpClientConnect if (decryptSsl && clientHelloInfo != null) { connectRequest.IsHttps = true; // todo: move this line to the previous "if" - clientConnection.SslProtocol = clientHelloInfo.SslProtocol; + clientStream.Connection.SslProtocol = clientHelloInfo.SslProtocol; bool http2Supported = false; @@ -221,11 +217,11 @@ private async Task handleClient(ExplicitProxyEndPoint endPoint, TcpClientConnect await sslStream.AuthenticateAsServerAsync(options, cancellationToken); #if NETSTANDARD2_1 - clientConnection.NegotiatedApplicationProtocol = sslStream.NegotiatedApplicationProtocol; + clientStream.Connection.NegotiatedApplicationProtocol = sslStream.NegotiatedApplicationProtocol; #endif // HTTPS server created - we can now decrypt the client's traffic - clientStream = new HttpClientStream(sslStream, BufferPool); + clientStream = new HttpClientStream(clientStream.Connection, sslStream, BufferPool); sslStream = null; // clientStream was created, no need to keep SSL stream reference clientStream.DataRead += (o, args) => connectArgs.OnDecryptedDataSent(args.Buffer, args.Offset, args.Count); @@ -362,13 +358,13 @@ await TcpHelper.SendRaw(clientStream, connection.Stream, BufferPool, var connectionPreface = new ReadOnlyMemory(Http2Helper.ConnectionPreface); await connection.Stream.WriteAsync(connectionPreface, cancellationToken); await Http2Helper.SendHttp2(clientStream, connection.Stream, - () => new SessionEventArgs(this, endPoint, clientConnection, clientStream, connectArgs?.HttpClient.ConnectRequest, cancellationTokenSource) + () => new SessionEventArgs(this, endPoint, clientStream, connectArgs?.HttpClient.ConnectRequest, cancellationTokenSource) { UserData = connectArgs?.UserData }, async args => { await onBeforeRequest(args); }, async args => { await onBeforeResponse(args); }, - connectArgs.CancellationTokenSource, clientConnection.Id, ExceptionFunc); + connectArgs.CancellationTokenSource, clientStream.Connection.Id, ExceptionFunc); #endif } finally @@ -381,7 +377,7 @@ await Http2Helper.SendHttp2(clientStream, connection.Stream, calledRequestHandler = true; // Now create the request - await handleHttpSessionRequest(endPoint, clientConnection, clientStream, cancellationTokenSource, connectArgs, prefetchConnectionTask); + await handleHttpSessionRequest(endPoint, clientStream, cancellationTokenSource, connectArgs, prefetchConnectionTask); } catch (ProxyException e) { diff --git a/src/Titanium.Web.Proxy/Extensions/StringExtensions.cs b/src/Titanium.Web.Proxy/Extensions/StringExtensions.cs index acfd0d34d..d1d621048 100644 --- a/src/Titanium.Web.Proxy/Extensions/StringExtensions.cs +++ b/src/Titanium.Web.Proxy/Extensions/StringExtensions.cs @@ -1,12 +1,11 @@ using System; using System.Globalization; -using Titanium.Web.Proxy.Models; namespace Titanium.Web.Proxy.Extensions { internal static class StringExtensions { - internal static bool EqualsIgnoreCase(this string str, string value) + internal static bool EqualsIgnoreCase(this string str, string? value) { return str.Equals(value, StringComparison.CurrentCultureIgnoreCase); } @@ -16,12 +15,12 @@ internal static bool EqualsIgnoreCase(this ReadOnlySpan str, ReadOnlySpan< return str.Equals(value, StringComparison.CurrentCultureIgnoreCase); } - internal static bool ContainsIgnoreCase(this string str, string value) + internal static bool ContainsIgnoreCase(this string str, string? value) { return CultureInfo.CurrentCulture.CompareInfo.IndexOf(str, value, CompareOptions.IgnoreCase) >= 0; } - internal static int IndexOfIgnoreCase(this string str, string value) + internal static int IndexOfIgnoreCase(this string str, string? value) { return CultureInfo.CurrentCulture.CompareInfo.IndexOf(str, value, CompareOptions.IgnoreCase); } diff --git a/src/Titanium.Web.Proxy/Extensions/UriExtensions.cs b/src/Titanium.Web.Proxy/Extensions/UriExtensions.cs index c95ff600d..5003c622f 100644 --- a/src/Titanium.Web.Proxy/Extensions/UriExtensions.cs +++ b/src/Titanium.Web.Proxy/Extensions/UriExtensions.cs @@ -1,5 +1,4 @@ using System; -using System.Text; namespace Titanium.Web.Proxy.Extensions { diff --git a/src/Titanium.Web.Proxy/Helpers/HttpClientStream.cs b/src/Titanium.Web.Proxy/Helpers/HttpClientStream.cs index 4f0b388e6..e816ba44f 100644 --- a/src/Titanium.Web.Proxy/Helpers/HttpClientStream.cs +++ b/src/Titanium.Web.Proxy/Helpers/HttpClientStream.cs @@ -3,15 +3,19 @@ using System.Threading; using System.Threading.Tasks; using Titanium.Web.Proxy.Http; +using Titanium.Web.Proxy.Network.Tcp; using Titanium.Web.Proxy.StreamExtended.BufferPool; namespace Titanium.Web.Proxy.Helpers { internal sealed class HttpClientStream : HttpStream { - internal HttpClientStream(Stream stream, IBufferPool bufferPool) + public TcpClientConnection Connection { get; } + + internal HttpClientStream(TcpClientConnection connection, Stream stream, IBufferPool bufferPool) : base(stream, bufferPool) { + Connection = connection; } /// diff --git a/src/Titanium.Web.Proxy/Helpers/NativeMethods.SystemProxy.cs b/src/Titanium.Web.Proxy/Helpers/NativeMethods.SystemProxy.cs index 56509a458..5d1345dd6 100644 --- a/src/Titanium.Web.Proxy/Helpers/NativeMethods.SystemProxy.cs +++ b/src/Titanium.Web.Proxy/Helpers/NativeMethods.SystemProxy.cs @@ -6,7 +6,7 @@ namespace Titanium.Web.Proxy.Helpers internal partial class NativeMethods { // Keeps it from getting garbage collected - internal static ConsoleEventDelegate Handler; + internal static ConsoleEventDelegate? Handler; [DllImport("wininet.dll")] internal static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer, diff --git a/src/Titanium.Web.Proxy/Helpers/ProxyInfo.cs b/src/Titanium.Web.Proxy/Helpers/ProxyInfo.cs index 600e3a9d9..d7d8e337f 100644 --- a/src/Titanium.Web.Proxy/Helpers/ProxyInfo.cs +++ b/src/Titanium.Web.Proxy/Helpers/ProxyInfo.cs @@ -211,12 +211,7 @@ internal static List GetSystemProxyValues(string? proxySer if (protocolType.HasValue) { var endPointParts = tmp.Substring(equalsIndex + 1).Split(':'); - return new HttpSystemProxyValue - { - HostName = endPointParts[0], - Port = int.Parse(endPointParts[1]), - ProtocolType = protocolType.Value - }; + return new HttpSystemProxyValue(endPointParts[0], int.Parse(endPointParts[1]), protocolType.Value); } } diff --git a/src/Titanium.Web.Proxy/Helpers/SystemProxy.cs b/src/Titanium.Web.Proxy/Helpers/SystemProxy.cs index 81ea5224b..c9c3f32b3 100644 --- a/src/Titanium.Web.Proxy/Helpers/SystemProxy.cs +++ b/src/Titanium.Web.Proxy/Helpers/SystemProxy.cs @@ -9,11 +9,18 @@ namespace Titanium.Web.Proxy.Helpers { internal class HttpSystemProxyValue { - internal string HostName { get; set; } + internal string HostName { get; } - internal int Port { get; set; } + internal int Port { get; } - internal ProxyProtocolType ProtocolType { get; set; } + internal ProxyProtocolType ProtocolType { get; } + + public HttpSystemProxyValue(string hostName, int port, ProxyProtocolType protocolType) + { + HostName = hostName; + Port = port; + ProtocolType = protocolType; + } public override string ToString() { @@ -56,7 +63,7 @@ public SystemProxyManager() AppDomain.CurrentDomain.ProcessExit += (o, args) => RestoreOriginalSettings(); if (Environment.UserInteractive && NativeMethods.GetConsoleWindow() != IntPtr.Zero) { - NativeMethods.Handler = eventType => + var handler = new NativeMethods.ConsoleEventDelegate(eventType => { if (eventType != 2) { @@ -65,10 +72,11 @@ public SystemProxyManager() RestoreOriginalSettings(); return false; - }; + }); + NativeMethods.Handler = handler; // On Console exit make sure we also exit the proxy - NativeMethods.SetConsoleCtrlHandler(NativeMethods.Handler, true); + NativeMethods.SetConsoleCtrlHandler(handler, true); } } @@ -95,22 +103,12 @@ internal void SetProxy(string hostname, int port, ProxyProtocolType protocolType existingSystemProxyValues.RemoveAll(x => (protocolType & x.ProtocolType) != 0); if ((protocolType & ProxyProtocolType.Http) != 0) { - existingSystemProxyValues.Add(new HttpSystemProxyValue - { - HostName = hostname, - ProtocolType = ProxyProtocolType.Http, - Port = port - }); + existingSystemProxyValues.Add(new HttpSystemProxyValue(hostname, port, ProxyProtocolType.Http)); } if ((protocolType & ProxyProtocolType.Https) != 0) { - existingSystemProxyValues.Add(new HttpSystemProxyValue - { - HostName = hostname, - ProtocolType = ProxyProtocolType.Https, - Port = port - }); + existingSystemProxyValues.Add(new HttpSystemProxyValue(hostname, port, ProxyProtocolType.Https)); } reg.DeleteValue(regAutoConfigUrl, false); diff --git a/src/Titanium.Web.Proxy/Http/ConnectRequest.cs b/src/Titanium.Web.Proxy/Http/ConnectRequest.cs index 7dc1f631c..3267105d0 100644 --- a/src/Titanium.Web.Proxy/Http/ConnectRequest.cs +++ b/src/Titanium.Web.Proxy/Http/ConnectRequest.cs @@ -1,5 +1,4 @@ using System; -using Titanium.Web.Proxy.Extensions; using Titanium.Web.Proxy.Models; using Titanium.Web.Proxy.StreamExtended; diff --git a/src/Titanium.Web.Proxy/Http/HeaderBuilder.cs b/src/Titanium.Web.Proxy/Http/HeaderBuilder.cs index 008da93a1..db957395f 100644 --- a/src/Titanium.Web.Proxy/Http/HeaderBuilder.cs +++ b/src/Titanium.Web.Proxy/Http/HeaderBuilder.cs @@ -2,7 +2,6 @@ using System.Buffers; using System.IO; using System.Text; -using Titanium.Web.Proxy.Helpers; using Titanium.Web.Proxy.Models; using Titanium.Web.Proxy.Shared; diff --git a/src/Titanium.Web.Proxy/Http/HeaderCollection.cs b/src/Titanium.Web.Proxy/Http/HeaderCollection.cs index a6beb15a0..ff48e9d29 100644 --- a/src/Titanium.Web.Proxy/Http/HeaderCollection.cs +++ b/src/Titanium.Web.Proxy/Http/HeaderCollection.cs @@ -4,7 +4,6 @@ using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; -using Titanium.Web.Proxy.Extensions; using Titanium.Web.Proxy.Models; namespace Titanium.Web.Proxy.Http diff --git a/src/Titanium.Web.Proxy/Http/HttpWebClient.cs b/src/Titanium.Web.Proxy/Http/HttpWebClient.cs index 1809bc569..0ffcd4cc9 100644 --- a/src/Titanium.Web.Proxy/Http/HttpWebClient.cs +++ b/src/Titanium.Web.Proxy/Http/HttpWebClient.cs @@ -1,12 +1,7 @@ using System; -using System.IO; using System.Net; -using System.Text; using System.Threading; using System.Threading.Tasks; -using Titanium.Web.Proxy.Exceptions; -using Titanium.Web.Proxy.Extensions; -using Titanium.Web.Proxy.Models; using Titanium.Web.Proxy.Network.Tcp; namespace Titanium.Web.Proxy.Http diff --git a/src/Titanium.Web.Proxy/Http/KnownHeader.cs b/src/Titanium.Web.Proxy/Http/KnownHeader.cs index bd48df5d9..11ea59bf1 100644 --- a/src/Titanium.Web.Proxy/Http/KnownHeader.cs +++ b/src/Titanium.Web.Proxy/Http/KnownHeader.cs @@ -26,7 +26,7 @@ internal bool Equals(ReadOnlySpan value) return String.AsSpan().EqualsIgnoreCase(value); } - internal bool Equals(string value) + internal bool Equals(string? value) { return String.EqualsIgnoreCase(value); } diff --git a/src/Titanium.Web.Proxy/Http/Request.cs b/src/Titanium.Web.Proxy/Http/Request.cs index f7d42c099..dbbfa7025 100644 --- a/src/Titanium.Web.Proxy/Http/Request.cs +++ b/src/Titanium.Web.Proxy/Http/Request.cs @@ -1,9 +1,7 @@ using System; using System.ComponentModel; -using System.Text; using Titanium.Web.Proxy.Exceptions; using Titanium.Web.Proxy.Extensions; -using Titanium.Web.Proxy.Helpers; using Titanium.Web.Proxy.Models; namespace Titanium.Web.Proxy.Http diff --git a/src/Titanium.Web.Proxy/Http/Response.cs b/src/Titanium.Web.Proxy/Http/Response.cs index bef3814fc..80eb3ecd0 100644 --- a/src/Titanium.Web.Proxy/Http/Response.cs +++ b/src/Titanium.Web.Proxy/Http/Response.cs @@ -1,8 +1,6 @@ using System; using System.ComponentModel; -using System.Text; using Titanium.Web.Proxy.Extensions; -using Titanium.Web.Proxy.Helpers; using Titanium.Web.Proxy.Models; namespace Titanium.Web.Proxy.Http diff --git a/src/Titanium.Web.Proxy/Http2/Hpack/Decoder.cs b/src/Titanium.Web.Proxy/Http2/Hpack/Decoder.cs index 6bb212065..89b624409 100644 --- a/src/Titanium.Web.Proxy/Http2/Hpack/Decoder.cs +++ b/src/Titanium.Web.Proxy/Http2/Hpack/Decoder.cs @@ -17,7 +17,6 @@ using System; using System.IO; -using System.Text; using Titanium.Web.Proxy.Models; namespace Titanium.Web.Proxy.Http2.Hpack diff --git a/src/Titanium.Web.Proxy/Http2/Hpack/DynamicTable.cs b/src/Titanium.Web.Proxy/Http2/Hpack/DynamicTable.cs index 36d7c572d..44ee27d1d 100644 --- a/src/Titanium.Web.Proxy/Http2/Hpack/DynamicTable.cs +++ b/src/Titanium.Web.Proxy/Http2/Hpack/DynamicTable.cs @@ -141,7 +141,7 @@ public void Add(HttpHeader header) } Size -= removed.Size; - headerFields[tail++] = null; + headerFields[tail++] = null!; if (tail == headerFields.Length) { tail = 0; @@ -157,7 +157,7 @@ public void Clear() { while (tail != head) { - headerFields[tail++] = null; + headerFields[tail++] = null!; if (tail == headerFields.Length) { tail = 0; diff --git a/src/Titanium.Web.Proxy/Http2/Hpack/Encoder.cs b/src/Titanium.Web.Proxy/Http2/Hpack/Encoder.cs index ba447694f..07081c769 100644 --- a/src/Titanium.Web.Proxy/Http2/Hpack/Encoder.cs +++ b/src/Titanium.Web.Proxy/Http2/Hpack/Encoder.cs @@ -1,7 +1,4 @@ - - -using Titanium.Web.Proxy.Extensions; -#if NETSTANDARD2_1 +#if NETSTANDARD2_1 /* * Copyright 2014 Twitter, Inc * This file is a derivative work modified by Ringo Leese @@ -20,7 +17,6 @@ */ using System; using System.IO; -using System.Text; using Titanium.Web.Proxy.Models; namespace Titanium.Web.Proxy.Http2.Hpack diff --git a/src/Titanium.Web.Proxy/Http2/Hpack/HuffmanDecoder.cs b/src/Titanium.Web.Proxy/Http2/Hpack/HuffmanDecoder.cs index 168833370..77d7e2a2e 100644 --- a/src/Titanium.Web.Proxy/Http2/Hpack/HuffmanDecoder.cs +++ b/src/Titanium.Web.Proxy/Http2/Hpack/HuffmanDecoder.cs @@ -17,7 +17,6 @@ using System; using System.IO; -using System.Text; namespace Titanium.Web.Proxy.Http2.Hpack { diff --git a/src/Titanium.Web.Proxy/Http2/Hpack/StaticTable.cs b/src/Titanium.Web.Proxy/Http2/Hpack/StaticTable.cs index 163525d4a..49906e9d2 100644 --- a/src/Titanium.Web.Proxy/Http2/Hpack/StaticTable.cs +++ b/src/Titanium.Web.Proxy/Http2/Hpack/StaticTable.cs @@ -17,8 +17,6 @@ using System; using System.Collections.Generic; -using System.Text; -using Titanium.Web.Proxy.Extensions; using Titanium.Web.Proxy.Models; namespace Titanium.Web.Proxy.Http2.Hpack diff --git a/src/Titanium.Web.Proxy/Http2/Http2Helper.cs b/src/Titanium.Web.Proxy/Http2/Http2Helper.cs index f86898cbb..46ebe0e46 100644 --- a/src/Titanium.Web.Proxy/Http2/Http2Helper.cs +++ b/src/Titanium.Web.Proxy/Http2/Http2Helper.cs @@ -3,7 +3,6 @@ #if NETSTANDARD2_1 using System; using System.Collections.Concurrent; -using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Net; diff --git a/src/Titanium.Web.Proxy/Models/HttpHeader.cs b/src/Titanium.Web.Proxy/Models/HttpHeader.cs index 9ebde00e9..203200321 100644 --- a/src/Titanium.Web.Proxy/Models/HttpHeader.cs +++ b/src/Titanium.Web.Proxy/Models/HttpHeader.cs @@ -2,7 +2,6 @@ using System.Net; using System.Text; using Titanium.Web.Proxy.Extensions; -using Titanium.Web.Proxy.Helpers; using Titanium.Web.Proxy.Http; namespace Titanium.Web.Proxy.Models diff --git a/src/Titanium.Web.Proxy/Network/Tcp/TcpClientConnection.cs b/src/Titanium.Web.Proxy/Network/Tcp/TcpClientConnection.cs index 22d09da03..9e351a522 100644 --- a/src/Titanium.Web.Proxy/Network/Tcp/TcpClientConnection.cs +++ b/src/Titanium.Web.Proxy/Network/Tcp/TcpClientConnection.cs @@ -16,6 +16,8 @@ namespace Titanium.Web.Proxy.Network.Tcp /// internal class TcpClientConnection : IDisposable { + public object ClientUserData { get; set; } + internal TcpClientConnection(ProxyServer proxyServer, TcpClient tcpClient) { this.tcpClient = tcpClient; diff --git a/src/Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs b/src/Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs index 0c1095f0b..ba310332b 100644 --- a/src/Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs +++ b/src/Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs @@ -11,12 +11,10 @@ using System.Threading; using System.Threading.Tasks; using Titanium.Web.Proxy.EventArguments; -using Titanium.Web.Proxy.Exceptions; using Titanium.Web.Proxy.Extensions; using Titanium.Web.Proxy.Helpers; using Titanium.Web.Proxy.Http; using Titanium.Web.Proxy.Models; -using Titanium.Web.Proxy.StreamExtended.Network; namespace Titanium.Web.Proxy.Network.Tcp { @@ -139,14 +137,14 @@ internal async Task GetConnectionCacheKey(ProxyServer server, SessionEve /// /// Create a server connection. /// - /// The proxy server. + /// The proxy server. /// The session event arguments. /// Is this a CONNECT request. /// /// if set to true [no cache]. /// The cancellation token for this async task. /// - internal Task GetServerConnection(ProxyServer server, SessionEventArgsBase session, bool isConnect, + internal Task GetServerConnection(ProxyServer proxyServer, SessionEventArgsBase session, bool isConnect, SslApplicationProtocol applicationProtocol, bool noCache, CancellationToken cancellationToken) { List? applicationProtocols = null; @@ -155,28 +153,28 @@ internal Task GetServerConnection(ProxyServer server, Sessi applicationProtocols = new List { applicationProtocol }; } - return GetServerConnection(server, session, isConnect, applicationProtocols, noCache, cancellationToken); + return GetServerConnection(proxyServer, session, isConnect, applicationProtocols, noCache, cancellationToken); } /// /// Create a server connection. /// - /// The proxy server. + /// The proxy server. /// The session event arguments. /// Is this a CONNECT request. /// /// if set to true [no cache]. /// The cancellation token for this async task. /// - internal async Task GetServerConnection(ProxyServer server, SessionEventArgsBase session, bool isConnect, + internal async Task GetServerConnection(ProxyServer proxyServer, SessionEventArgsBase session, bool isConnect, List? applicationProtocols, bool noCache, CancellationToken cancellationToken) { IExternalProxy? customUpStreamProxy = null; bool isHttps = session.IsHttps; - if (server.GetCustomUpStreamProxyFunc != null) + if (proxyServer.GetCustomUpStreamProxyFunc != null) { - customUpStreamProxy = await server.GetCustomUpStreamProxyFunc(session); + customUpStreamProxy = await proxyServer.GetCustomUpStreamProxyFunc(session); } session.CustomUpStreamProxyUsed = customUpStreamProxy; @@ -207,37 +205,36 @@ internal async Task GetServerConnection(ProxyServer server, } return await GetServerConnection( - host, - port, + proxyServer, host, port, session.HttpClient.Request.HttpVersion, isHttps, applicationProtocols, isConnect, - server, session, session.HttpClient.UpStreamEndPoint ?? server.UpStreamEndPoint, - customUpStreamProxy ?? (isHttps ? server.UpStreamHttpsProxy : server.UpStreamHttpProxy), + session, session.HttpClient.UpStreamEndPoint ?? proxyServer.UpStreamEndPoint, + customUpStreamProxy ?? (isHttps ? proxyServer.UpStreamHttpsProxy : proxyServer.UpStreamHttpProxy), noCache, cancellationToken); } /// /// Gets a TCP connection to server from connection pool. /// + /// The current ProxyServer instance. /// The remote hostname. /// The remote port. /// The http version to use. /// Is this a HTTPS request. /// The list of HTTPS application level protocol to negotiate if needed. /// Is this a CONNECT request. - /// The current ProxyServer instance. - /// The session. + /// The session event arguments. /// The local upstream endpoint to make request via. /// The external proxy to make request via. /// Not from cache/create new connection. /// The cancellation token for this async task. /// - internal async Task GetServerConnection(string remoteHostName, int remotePort, + internal async Task GetServerConnection(ProxyServer proxyServer, string remoteHostName, int remotePort, Version httpVersion, bool isHttps, List? applicationProtocols, bool isConnect, - ProxyServer proxyServer, SessionEventArgsBase? session, IPEndPoint? upStreamEndPoint, IExternalProxy? externalProxy, + SessionEventArgsBase sessionArgs, IPEndPoint? upStreamEndPoint, IExternalProxy? externalProxy, bool noCache, CancellationToken cancellationToken) { - var sslProtocol = session?.ClientConnection.SslProtocol ?? SslProtocols.None; + var sslProtocol = sessionArgs.ClientConnection.SslProtocol; var cacheKey = GetConnectionCacheKey(remoteHostName, remotePort, isHttps, applicationProtocols, upStreamEndPoint, externalProxy); @@ -264,7 +261,7 @@ internal async Task GetServerConnection(string remoteHostNa } var connection = await createServerConnection(remoteHostName, remotePort, httpVersion, isHttps, sslProtocol, - applicationProtocols, isConnect, proxyServer, session, upStreamEndPoint, externalProxy, cacheKey, cancellationToken); + applicationProtocols, isConnect, proxyServer, sessionArgs, upStreamEndPoint, externalProxy, cacheKey, cancellationToken); return connection; } @@ -280,7 +277,7 @@ internal async Task GetServerConnection(string remoteHostNa /// The list of HTTPS application level protocol to negotiate if needed. /// Is this a CONNECT request. /// The current ProxyServer instance. - /// The http session. + /// The http session. /// The local upstream endpoint to make request via. /// The external proxy to make request via. /// The connection cache key @@ -288,7 +285,7 @@ internal async Task GetServerConnection(string remoteHostNa /// private async Task createServerConnection(string remoteHostName, int remotePort, Version httpVersion, bool isHttps, SslProtocols sslProtocol, List? applicationProtocols, bool isConnect, - ProxyServer proxyServer, SessionEventArgsBase? session, IPEndPoint? upStreamEndPoint, IExternalProxy? externalProxy, string cacheKey, + ProxyServer proxyServer, SessionEventArgsBase sessionArgs, IPEndPoint? upStreamEndPoint, IExternalProxy? externalProxy, string cacheKey, CancellationToken cancellationToken) { // deny connection to proxy end points to avoid infinite connection loop. @@ -346,14 +343,14 @@ private async Task createServerConnection(string remoteHost throw new Exception($"Could not resolve the hostname {hostname}"); } - if (session != null) + if (sessionArgs != null) { - session.TimeLine["Dns Resolved"] = DateTime.Now; + sessionArgs.TimeLine["Dns Resolved"] = DateTime.Now; } Array.Sort(ipAddresses, (x, y) => x.AddressFamily.CompareTo(y.AddressFamily)); - Exception lastException = null; + Exception? lastException = null; for (int i = 0; i < ipAddresses.Length; i++) { try @@ -427,26 +424,26 @@ private async Task createServerConnection(string remoteHost if (tcpClient == null) { - if (session != null && proxyServer.CustomUpStreamProxyFailureFunc != null) + if (sessionArgs != null && proxyServer.CustomUpStreamProxyFailureFunc != null) { - var newUpstreamProxy = await proxyServer.CustomUpStreamProxyFailureFunc(session); + var newUpstreamProxy = await proxyServer.CustomUpStreamProxyFailureFunc(sessionArgs); if (newUpstreamProxy != null) { - session.CustomUpStreamProxyUsed = newUpstreamProxy; - session.TimeLine["Retrying Upstream Proxy Connection"] = DateTime.Now; - return await createServerConnection(remoteHostName, remotePort, httpVersion, isHttps, sslProtocol, applicationProtocols, isConnect, proxyServer, session, upStreamEndPoint, externalProxy, cacheKey, cancellationToken); + sessionArgs.CustomUpStreamProxyUsed = newUpstreamProxy; + sessionArgs.TimeLine["Retrying Upstream Proxy Connection"] = DateTime.Now; + return await createServerConnection(remoteHostName, remotePort, httpVersion, isHttps, sslProtocol, applicationProtocols, isConnect, proxyServer, sessionArgs, upStreamEndPoint, externalProxy, cacheKey, cancellationToken); } } throw new Exception($"Could not establish connection to {hostname}", lastException); } - if (session != null) + if (sessionArgs != null) { - session.TimeLine["Connection Established"] = DateTime.Now; + sessionArgs.TimeLine["Connection Established"] = DateTime.Now; } - await proxyServer.InvokeConnectionCreateEvent(tcpClient, false); + await proxyServer.InvokeServerConnectionCreateEvent(tcpClient); stream = new HttpServerStream(tcpClient.GetStream(), proxyServer.BufferPool); @@ -483,8 +480,13 @@ private async Task createServerConnection(string remoteHost if (isHttps) { - var sslStream = new SslStream(stream, false, proxyServer.ValidateServerCertificate, - proxyServer.SelectClientCertificate); + var sslStream = new SslStream(stream, false, + (sender, certificate, chain, sslPolicyErrors) => + proxyServer.ValidateServerCertificate(sender, sessionArgs, certificate, chain, + sslPolicyErrors), + (sender, targetHost, localCertificates, remoteCertificate, acceptableIssuers) => + proxyServer.SelectClientCertificate(sender, sessionArgs, targetHost, localCertificates, + remoteCertificate, acceptableIssuers)); stream = new HttpServerStream(sslStream, proxyServer.BufferPool); var options = new SslClientAuthenticationOptions @@ -500,9 +502,9 @@ private async Task createServerConnection(string remoteHost negotiatedApplicationProtocol = sslStream.NegotiatedApplicationProtocol; #endif - if (session != null) + if (sessionArgs != null) { - session.TimeLine["HTTPS Established"] = DateTime.Now; + sessionArgs.TimeLine["HTTPS Established"] = DateTime.Now; } } } diff --git a/src/Titanium.Web.Proxy/Network/Tcp/TcpServerConnection.cs b/src/Titanium.Web.Proxy/Network/Tcp/TcpServerConnection.cs index c924ba40e..1031eecbd 100644 --- a/src/Titanium.Web.Proxy/Network/Tcp/TcpServerConnection.cs +++ b/src/Titanium.Web.Proxy/Network/Tcp/TcpServerConnection.cs @@ -6,7 +6,6 @@ using Titanium.Web.Proxy.Extensions; using Titanium.Web.Proxy.Helpers; using Titanium.Web.Proxy.Models; -using Titanium.Web.Proxy.StreamExtended.Network; namespace Titanium.Web.Proxy.Network.Tcp { diff --git a/src/Titanium.Web.Proxy/Network/WinAuth/Security/WinAuthEndPoint.cs b/src/Titanium.Web.Proxy/Network/WinAuth/Security/WinAuthEndPoint.cs index 7b584939a..fabd4470b 100644 --- a/src/Titanium.Web.Proxy/Network/WinAuth/Security/WinAuthEndPoint.cs +++ b/src/Titanium.Web.Proxy/Network/WinAuth/Security/WinAuthEndPoint.cs @@ -1,8 +1,6 @@ // http://pinvoke.net/default.aspx/secur32/InitializeSecurityContext.html using System; -using System.Collections.Generic; -using System.Linq; using System.Runtime.InteropServices; using System.Security.Principal; using Titanium.Web.Proxy.Http; diff --git a/src/Titanium.Web.Proxy/ProxyAuthorizationHandler.cs b/src/Titanium.Web.Proxy/ProxyAuthorizationHandler.cs index a70eda3fd..9712be8b2 100644 --- a/src/Titanium.Web.Proxy/ProxyAuthorizationHandler.cs +++ b/src/Titanium.Web.Proxy/ProxyAuthorizationHandler.cs @@ -4,7 +4,6 @@ using System.Threading.Tasks; using Titanium.Web.Proxy.EventArguments; using Titanium.Web.Proxy.Exceptions; -using Titanium.Web.Proxy.Extensions; using Titanium.Web.Proxy.Http; using Titanium.Web.Proxy.Models; diff --git a/src/Titanium.Web.Proxy/ProxyServer.cs b/src/Titanium.Web.Proxy/ProxyServer.cs index 64ea30829..23ddedd40 100644 --- a/src/Titanium.Web.Proxy/ProxyServer.cs +++ b/src/Titanium.Web.Proxy/ProxyServer.cs @@ -15,7 +15,6 @@ using Titanium.Web.Proxy.Network; using Titanium.Web.Proxy.Network.Tcp; using Titanium.Web.Proxy.StreamExtended.BufferPool; -using Titanium.Web.Proxy.StreamExtended.Network; namespace Titanium.Web.Proxy { @@ -705,7 +704,7 @@ private void validateEndPointAsSystemProxy(ExplicitProxyEndPoint endPoint) throw new ArgumentNullException(nameof(endPoint)); } - if (ProxyEndPoints.Contains(endPoint) == false) + if (!ProxyEndPoints.Contains(endPoint)) { throw new Exception("Cannot set endPoints not added to proxy as system proxy"); } @@ -739,7 +738,7 @@ private void onAcceptConnection(IAsyncResult asyn) try { // based on end point type call appropriate request handlers - tcpClient = endPoint.Listener.EndAcceptTcpClient(asyn); + tcpClient = endPoint.Listener!.EndAcceptTcpClient(asyn); tcpClient.NoDelay = NoDelay; } catch (ObjectDisposedException) @@ -763,7 +762,7 @@ private void onAcceptConnection(IAsyncResult asyn) } // Get the listener that handles the client request. - endPoint.Listener.BeginAcceptTcpClient(onAcceptConnection, endPoint); + endPoint.Listener!.BeginAcceptTcpClient(onAcceptConnection, endPoint); } @@ -795,7 +794,7 @@ private async Task handleClient(TcpClient tcpClient, ProxyEndPoint endPoint) tcpClient.LingerState = new LingerOption(true, TcpTimeWaitSeconds); - await InvokeConnectionCreateEvent(tcpClient, true); + await InvokeClientConnectionCreateEvent(tcpClient); using (var clientConnection = new TcpClientConnection(this, tcpClient)) { @@ -825,7 +824,7 @@ private void onException(HttpClientStream clientStream, Exception exception) /// private void quitListen(ProxyEndPoint endPoint) { - endPoint.Listener.Stop(); + endPoint.Listener!.Stop(); endPoint.Listener.Server.Dispose(); } @@ -866,21 +865,28 @@ internal void UpdateServerConnectionCount(bool increment) } /// - /// Invoke client/server tcp connection events if subscribed by API user. + /// Invoke client tcp connection events if subscribed by API user. /// /// The TcpClient object. - /// Is this a client connection created event? If not then we would assume that its a server connection create event. /// - internal async Task InvokeConnectionCreateEvent(TcpClient client, bool isClientConnection) + internal async Task InvokeClientConnectionCreateEvent(TcpClient client) { // client connection created - if (isClientConnection && OnClientConnectionCreate != null) + if (OnClientConnectionCreate != null) { await OnClientConnectionCreate.InvokeAsync(this, client, ExceptionFunc); } + } + /// + /// Invoke server tcp connection events if subscribed by API user. + /// + /// The TcpClient object. + /// + internal async Task InvokeServerConnectionCreateEvent(TcpClient client) + { // server connection created - if (!isClientConnection && OnServerConnectionCreate != null) + if (OnServerConnectionCreate != null) { await OnServerConnectionCreate.InvokeAsync(this, client, ExceptionFunc); } diff --git a/src/Titanium.Web.Proxy/RequestHandler.cs b/src/Titanium.Web.Proxy/RequestHandler.cs index be93160fb..feb41f4fc 100644 --- a/src/Titanium.Web.Proxy/RequestHandler.cs +++ b/src/Titanium.Web.Proxy/RequestHandler.cs @@ -14,7 +14,6 @@ using Titanium.Web.Proxy.Network; using Titanium.Web.Proxy.Network.Tcp; using Titanium.Web.Proxy.Shared; -using Titanium.Web.Proxy.StreamExtended.Network; namespace Titanium.Web.Proxy { @@ -29,13 +28,12 @@ public partial class ProxyServer /// client/server abruptly terminates connection or by normal HTTP termination. /// /// The proxy endpoint. - /// The client connection. /// The client stream. /// The cancellation token source for this async task. /// The Connect request if this is a HTTPS request from explicit endpoint. /// Prefetched server connection for current client using Connect/SNI headers. - private async Task handleHttpSessionRequest(ProxyEndPoint endPoint, TcpClientConnection clientConnection, - HttpClientStream clientStream, CancellationTokenSource cancellationTokenSource, TunnelConnectSessionEventArgs? connectArgs = null, + private async Task handleHttpSessionRequest(ProxyEndPoint endPoint, HttpClientStream clientStream, + CancellationTokenSource cancellationTokenSource, TunnelConnectSessionEventArgs? connectArgs = null, Task? prefetchConnectionTask = null) { var connectRequest = connectArgs?.HttpClient.ConnectRequest; @@ -64,7 +62,7 @@ private async Task handleHttpSessionRequest(ProxyEndPoint endPoint, TcpClientCon return; } - var args = new SessionEventArgs(this, endPoint, clientConnection, clientStream, connectRequest, cancellationTokenSource) + var args = new SessionEventArgs(this, endPoint, clientStream, connectRequest, cancellationTokenSource) { UserData = connectArgs?.UserData }; @@ -163,7 +161,7 @@ await HeaderParser.ReadHeaders(clientStream, args.HttpClient.Request.Headers, // or when prefetch task has a unexpectedly different connection. if (connection != null && (await tcpConnectionFactory.GetConnectionCacheKey(this, args, - clientConnection.NegotiatedApplicationProtocol) + clientStream.Connection.NegotiatedApplicationProtocol) != connection.CacheKey)) { await tcpConnectionFactory.Release(connection); @@ -171,7 +169,7 @@ await HeaderParser.ReadHeaders(clientStream, args.HttpClient.Request.Headers, } var result = await handleHttpSessionRequest(args, connection, - clientConnection.NegotiatedApplicationProtocol, + clientStream.Connection.NegotiatedApplicationProtocol, cancellationToken, cancellationTokenSource); // update connection to latest used diff --git a/src/Titanium.Web.Proxy/ResponseHandler.cs b/src/Titanium.Web.Proxy/ResponseHandler.cs index 782ec0b0b..cf3eb3168 100644 --- a/src/Titanium.Web.Proxy/ResponseHandler.cs +++ b/src/Titanium.Web.Proxy/ResponseHandler.cs @@ -3,7 +3,6 @@ using System.Threading.Tasks; using Titanium.Web.Proxy.EventArguments; using Titanium.Web.Proxy.Extensions; -using Titanium.Web.Proxy.Http; using Titanium.Web.Proxy.Network.WinAuth.Security; namespace Titanium.Web.Proxy diff --git a/src/Titanium.Web.Proxy/StreamExtended/Network/PeekStreamReader.cs b/src/Titanium.Web.Proxy/StreamExtended/Network/PeekStreamReader.cs index a301f66e8..996f2f700 100644 --- a/src/Titanium.Web.Proxy/StreamExtended/Network/PeekStreamReader.cs +++ b/src/Titanium.Web.Proxy/StreamExtended/Network/PeekStreamReader.cs @@ -1,7 +1,6 @@ using System; using System.Threading; using System.Threading.Tasks; -using Titanium.Web.Proxy.StreamExtended.BufferPool; namespace Titanium.Web.Proxy.StreamExtended.Network { diff --git a/src/Titanium.Web.Proxy/StreamExtended/SslTools.cs b/src/Titanium.Web.Proxy/StreamExtended/SslTools.cs index b31ca6c23..c6628a814 100644 --- a/src/Titanium.Web.Proxy/StreamExtended/SslTools.cs +++ b/src/Titanium.Web.Proxy/StreamExtended/SslTools.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; -using Titanium.Web.Proxy.Helpers; using Titanium.Web.Proxy.StreamExtended.BufferPool; using Titanium.Web.Proxy.StreamExtended.Models; using Titanium.Web.Proxy.StreamExtended.Network; diff --git a/src/Titanium.Web.Proxy/TransparentClientHandler.cs b/src/Titanium.Web.Proxy/TransparentClientHandler.cs index 02da48df6..e91f1ded8 100644 --- a/src/Titanium.Web.Proxy/TransparentClientHandler.cs +++ b/src/Titanium.Web.Proxy/TransparentClientHandler.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.IO; using System.Net.Security; using System.Net.Sockets; @@ -12,10 +11,8 @@ using Titanium.Web.Proxy.Extensions; using Titanium.Web.Proxy.Helpers; using Titanium.Web.Proxy.Models; -using Titanium.Web.Proxy.Network; using Titanium.Web.Proxy.Network.Tcp; using Titanium.Web.Proxy.StreamExtended; -using Titanium.Web.Proxy.StreamExtended.Network; namespace Titanium.Web.Proxy { @@ -33,7 +30,7 @@ private async Task handleClient(TransparentProxyEndPoint endPoint, TcpClientConn var cancellationTokenSource = new CancellationTokenSource(); var cancellationToken = cancellationTokenSource.Token; - var clientStream = new HttpClientStream(clientConnection.GetStream(), BufferPool); + var clientStream = new HttpClientStream(clientConnection, clientConnection.GetStream(), BufferPool); SslStream? sslStream = null; @@ -41,13 +38,11 @@ private async Task handleClient(TransparentProxyEndPoint endPoint, TcpClientConn { var clientHelloInfo = await SslTools.PeekClientHello(clientStream, BufferPool, cancellationToken); - string? httpsHostName = null; - if (clientHelloInfo != null) { - httpsHostName = clientHelloInfo.GetServerName() ?? endPoint.GenericCertificateName; + var httpsHostName = clientHelloInfo.GetServerName() ?? endPoint.GenericCertificateName; - var args = new BeforeSslAuthenticateEventArgs(cancellationTokenSource, httpsHostName); + var args = new BeforeSslAuthenticateEventArgs(clientConnection, cancellationTokenSource, httpsHostName); await endPoint.InvokeBeforeSslAuthenticate(this, args, ExceptionFunc); @@ -58,7 +53,7 @@ private async Task handleClient(TransparentProxyEndPoint endPoint, TcpClientConn if (endPoint.DecryptSsl && args.DecryptSsl) { - clientConnection.SslProtocol = clientHelloInfo.SslProtocol; + clientStream.Connection.SslProtocol = clientHelloInfo.SslProtocol; // do client authentication using certificate X509Certificate2? certificate = null; @@ -74,14 +69,13 @@ private async Task handleClient(TransparentProxyEndPoint endPoint, TcpClientConn await sslStream.AuthenticateAsServerAsync(certificate, false, SslProtocols.Tls, false); // HTTPS server created - we can now decrypt the client's traffic - clientStream = new HttpClientStream(sslStream, BufferPool); + clientStream = new HttpClientStream(clientStream.Connection, sslStream, BufferPool); sslStream = null; // clientStream was created, no need to keep SSL stream reference } catch (Exception e) { var certName = certificate?.GetNameInfo(X509NameType.SimpleName, false); - var session = new SessionEventArgs(this, endPoint, clientConnection, clientStream, null, - cancellationTokenSource); + var session = new SessionEventArgs(this, endPoint, clientStream, null, cancellationTokenSource); throw new ProxyConnectException( $"Couldn't authenticate host '{httpsHostName}' with certificate '{certName}'.", e, session); } @@ -89,9 +83,10 @@ private async Task handleClient(TransparentProxyEndPoint endPoint, TcpClientConn } else { - var connection = await tcpConnectionFactory.GetServerConnection(httpsHostName, endPoint.Port, + var sessionArgs = new SessionEventArgs(this, endPoint, clientStream, null, cancellationTokenSource); + var connection = await tcpConnectionFactory.GetServerConnection(this, httpsHostName, endPoint.Port, HttpHeader.VersionUnknown, false, null, - true, this, null, UpStreamEndPoint, + true, sessionArgs, UpStreamEndPoint, UpStreamHttpsProxy, true, cancellationToken); try @@ -131,7 +126,7 @@ await TcpHelper.SendRaw(clientStream, connection.Stream, BufferPool, // HTTPS server created - we can now decrypt the client's traffic // Now create the request - await handleHttpSessionRequest(endPoint, clientConnection, clientStream, cancellationTokenSource); + await handleHttpSessionRequest(endPoint, clientStream, cancellationTokenSource); } catch (ProxyException e) { diff --git a/src/Titanium.Web.Proxy/WebSocketDecoder.cs b/src/Titanium.Web.Proxy/WebSocketDecoder.cs index c65648ba2..c21c01187 100644 --- a/src/Titanium.Web.Proxy/WebSocketDecoder.cs +++ b/src/Titanium.Web.Proxy/WebSocketDecoder.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Runtime.InteropServices; using Titanium.Web.Proxy.StreamExtended.BufferPool; diff --git a/src/Titanium.Web.Proxy/WebSocketHandler.cs b/src/Titanium.Web.Proxy/WebSocketHandler.cs index e0c7df4bf..97ad90384 100644 --- a/src/Titanium.Web.Proxy/WebSocketHandler.cs +++ b/src/Titanium.Web.Proxy/WebSocketHandler.cs @@ -2,11 +2,9 @@ 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; -using Titanium.Web.Proxy.StreamExtended.Network; namespace Titanium.Web.Proxy { diff --git a/tests/Titanium.Web.Proxy.IntegrationTests/ExpectContinueTests.cs b/tests/Titanium.Web.Proxy.IntegrationTests/ExpectContinueTests.cs index e6ba4463f..7dd29b7c1 100644 --- a/tests/Titanium.Web.Proxy.IntegrationTests/ExpectContinueTests.cs +++ b/tests/Titanium.Web.Proxy.IntegrationTests/ExpectContinueTests.cs @@ -1,11 +1,5 @@ using System; -using System.Buffers; -using System.Collections.Generic; -using System.IO; -using System.Linq; using System.Net; -using System.Net.Http; -using System.Net.Sockets; using System.Text; using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/tests/Titanium.Web.Proxy.IntegrationTests/Helpers/HttpMessageParsing.cs b/tests/Titanium.Web.Proxy.IntegrationTests/Helpers/HttpMessageParsing.cs index 81dba1b7f..fe518385e 100644 --- a/tests/Titanium.Web.Proxy.IntegrationTests/Helpers/HttpMessageParsing.cs +++ b/tests/Titanium.Web.Proxy.IntegrationTests/Helpers/HttpMessageParsing.cs @@ -1,7 +1,6 @@ using System.IO; using System.Text; using Titanium.Web.Proxy.Http; -using Titanium.Web.Proxy.Shared; namespace Titanium.Web.Proxy.IntegrationTests.Helpers { diff --git a/tests/Titanium.Web.Proxy.IntegrationTests/NestedProxyTests.cs b/tests/Titanium.Web.Proxy.IntegrationTests/NestedProxyTests.cs index 2ed0d10e9..3f1f8a2ca 100644 --- a/tests/Titanium.Web.Proxy.IntegrationTests/NestedProxyTests.cs +++ b/tests/Titanium.Web.Proxy.IntegrationTests/NestedProxyTests.cs @@ -1,8 +1,6 @@ using System; using System.Net; using System.Net.Http; -using System.Net.Http.Headers; -using System.Text; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/tests/Titanium.Web.Proxy.IntegrationTests/Setup/TestProxyServer.cs b/tests/Titanium.Web.Proxy.IntegrationTests/Setup/TestProxyServer.cs index f6eb0bfc6..7a8d80c3d 100644 --- a/tests/Titanium.Web.Proxy.IntegrationTests/Setup/TestProxyServer.cs +++ b/tests/Titanium.Web.Proxy.IntegrationTests/Setup/TestProxyServer.cs @@ -1,9 +1,5 @@ using System; -using System.Collections.Generic; using System.Net; -using System.Text; -using System.Threading.Tasks; -using Titanium.Web.Proxy.EventArguments; using Titanium.Web.Proxy.Models; using Titanium.Web.Proxy.Network; diff --git a/tests/Titanium.Web.Proxy.IntegrationTests/Setup/TestSuite.cs b/tests/Titanium.Web.Proxy.IntegrationTests/Setup/TestSuite.cs index 96016d64d..0ad344270 100644 --- a/tests/Titanium.Web.Proxy.IntegrationTests/Setup/TestSuite.cs +++ b/tests/Titanium.Web.Proxy.IntegrationTests/Setup/TestSuite.cs @@ -1,7 +1,5 @@ using System; -using System.Collections.Generic; using System.Net.Http; -using System.Text; using Titanium.Web.Proxy.IntegrationTests.Helpers; using Titanium.Web.Proxy.IntegrationTests.Setup;