Unverified Commit 0c70019f authored by honfika's avatar honfika Committed by GitHub

Merge pull request #693 from justcoding121/master

beta
parents f9a74d7b 9be5226b
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;
}
}
}
using System; using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using System.Net.Security; using System.Net.Security;
using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Titanium.Web.Proxy.EventArguments; using Titanium.Web.Proxy.EventArguments;
...@@ -64,6 +61,7 @@ namespace Titanium.Web.Proxy.Examples.Basic ...@@ -64,6 +61,7 @@ namespace Titanium.Web.Proxy.Examples.Basic
{ {
proxyServer.BeforeRequest += onRequest; proxyServer.BeforeRequest += onRequest;
proxyServer.BeforeResponse += onResponse; proxyServer.BeforeResponse += onResponse;
proxyServer.AfterResponse += onAfterResponse;
proxyServer.ServerCertificateValidationCallback += OnCertificateValidation; proxyServer.ServerCertificateValidationCallback += OnCertificateValidation;
proxyServer.ClientCertificateSelectionCallback += OnCertificateSelection; proxyServer.ClientCertificateSelectionCallback += OnCertificateSelection;
...@@ -128,19 +126,32 @@ namespace Titanium.Web.Proxy.Examples.Basic ...@@ -128,19 +126,32 @@ namespace Titanium.Web.Proxy.Examples.Basic
private async Task<IExternalProxy> onGetCustomUpStreamProxyFunc(SessionEventArgsBase arg) private async Task<IExternalProxy> onGetCustomUpStreamProxyFunc(SessionEventArgsBase arg)
{ {
arg.GetState().PipelineInfo.AppendLine(nameof(onGetCustomUpStreamProxyFunc));
// this is just to show the functionality, provided values are junk // 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<IExternalProxy> onCustomUpStreamProxyFailureFunc(SessionEventArgsBase arg) private async Task<IExternalProxy> onCustomUpStreamProxyFailureFunc(SessionEventArgsBase arg)
{ {
arg.GetState().PipelineInfo.AppendLine(nameof(onCustomUpStreamProxyFailureFunc));
// this is just to show the functionality, provided values are junk // 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) private async Task onBeforeTunnelConnectRequest(object sender, TunnelConnectSessionEventArgs e)
{ {
string hostname = e.HttpClient.Request.RequestUri.Host; string hostname = e.HttpClient.Request.RequestUri.Host;
e.GetState().PipelineInfo.AppendLine(nameof(onBeforeTunnelConnectRequest) + ":" + hostname);
await writeToConsole("Tunnel to: " + hostname); await writeToConsole("Tunnel to: " + hostname);
if (hostname.Contains("dropbox.com")) if (hostname.Contains("dropbox.com"))
...@@ -186,12 +197,16 @@ namespace Titanium.Web.Proxy.Examples.Basic ...@@ -186,12 +197,16 @@ namespace Titanium.Web.Proxy.Examples.Basic
private Task onBeforeTunnelConnectResponse(object sender, TunnelConnectSessionEventArgs e) private Task onBeforeTunnelConnectResponse(object sender, TunnelConnectSessionEventArgs e)
{ {
e.GetState().PipelineInfo.AppendLine(nameof(onBeforeTunnelConnectResponse) + ":" + e.HttpClient.Request.RequestUri);
return Task.FromResult(false); return Task.FromResult(false);
} }
// intercept & cancel redirect or update requests // intercept & cancel redirect or update requests
private async Task onRequest(object sender, SessionEventArgs e) 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("Active Client Connections:" + ((ProxyServer)sender).ClientConnectionCount);
await writeToConsole(e.HttpClient.Request.Url); await writeToConsole(e.HttpClient.Request.Url);
...@@ -233,6 +248,8 @@ namespace Titanium.Web.Proxy.Examples.Basic ...@@ -233,6 +248,8 @@ namespace Titanium.Web.Proxy.Examples.Basic
// Modify response // Modify response
private async Task multipartRequestPartSent(object sender, MultipartRequestPartSentEventArgs e) private async Task multipartRequestPartSent(object sender, MultipartRequestPartSentEventArgs e)
{ {
e.GetState().PipelineInfo.AppendLine(nameof(multipartRequestPartSent));
var session = (SessionEventArgs)sender; var session = (SessionEventArgs)sender;
await writeToConsole("Multipart form data headers:"); await writeToConsole("Multipart form data headers:");
foreach (var header in e.Headers) foreach (var header in e.Headers)
...@@ -243,6 +260,8 @@ namespace Titanium.Web.Proxy.Examples.Basic ...@@ -243,6 +260,8 @@ namespace Titanium.Web.Proxy.Examples.Basic
private async Task onResponse(object sender, SessionEventArgs e) private async Task onResponse(object sender, SessionEventArgs e)
{ {
e.GetState().PipelineInfo.AppendLine(nameof(onResponse));
if (e.HttpClient.ConnectRequest?.TunnelType == TunnelType.Websocket) if (e.HttpClient.ConnectRequest?.TunnelType == TunnelType.Websocket)
{ {
e.DataSent += WebSocket_DataSent; e.DataSent += WebSocket_DataSent;
...@@ -293,6 +312,11 @@ namespace Titanium.Web.Proxy.Examples.Basic ...@@ -293,6 +312,11 @@ namespace Titanium.Web.Proxy.Examples.Basic
//} //}
} }
private async Task onAfterResponse(object sender, SessionEventArgs e)
{
await writeToConsole($"Pipelineinfo: {e.GetState().PipelineInfo}", ConsoleColor.Yellow);
}
/// <summary> /// <summary>
/// Allows overriding default certificate validation logic /// Allows overriding default certificate validation logic
/// </summary> /// </summary>
...@@ -300,6 +324,8 @@ namespace Titanium.Web.Proxy.Examples.Basic ...@@ -300,6 +324,8 @@ namespace Titanium.Web.Proxy.Examples.Basic
/// <param name="e"></param> /// <param name="e"></param>
public Task OnCertificateValidation(object sender, CertificateValidationEventArgs e) public Task OnCertificateValidation(object sender, CertificateValidationEventArgs e)
{ {
e.GetState().PipelineInfo.AppendLine(nameof(OnCertificateValidation));
// set IsValid to true/false based on Certificate Errors // set IsValid to true/false based on Certificate Errors
if (e.SslPolicyErrors == SslPolicyErrors.None) if (e.SslPolicyErrors == SslPolicyErrors.None)
{ {
...@@ -316,6 +342,8 @@ namespace Titanium.Web.Proxy.Examples.Basic ...@@ -316,6 +342,8 @@ namespace Titanium.Web.Proxy.Examples.Basic
/// <param name="e"></param> /// <param name="e"></param>
public Task OnCertificateSelection(object sender, CertificateSelectionEventArgs e) public Task OnCertificateSelection(object sender, CertificateSelectionEventArgs e)
{ {
e.GetState().PipelineInfo.AppendLine(nameof(OnCertificateSelection));
// set e.clientCertificate to override // set e.clientCertificate to override
return Task.FromResult(0); return Task.FromResult(0);
...@@ -352,3 +380,4 @@ namespace Titanium.Web.Proxy.Examples.Basic ...@@ -352,3 +380,4 @@ namespace Titanium.Web.Proxy.Examples.Basic
//} //}
} }
} }
using System;
using System.Text;
namespace Titanium.Web.Proxy.Examples.Basic
{
public class SampleClientState
{
public StringBuilder PipelineInfo { get; } = new StringBuilder();
}
}
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_AFTER_TYPECAST_PARENTHESES/@EntryValue">False</s:Boolean> <s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_AFTER_TYPECAST_PARENTHESES/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_WITHIN_SINGLE_LINE_ARRAY_INITIALIZER_BRACES/@EntryValue">True</s:Boolean> <s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_WITHIN_SINGLE_LINE_ARRAY_INITIALIZER_BRACES/@EntryValue">True</s:Boolean>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LIMIT/@EntryValue">120</s:Int64> <s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LIMIT/@EntryValue">120</s:Int64>
<s:String x:Key="/Default/CodeStyle/CSharpUsing/MandatoryImports/=System/@EntryIndexedValue">System</s:String>
<s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForBuiltInTypes/@EntryValue">UseExplicitType</s:String> <s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForBuiltInTypes/@EntryValue">UseExplicitType</s:String>
<s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForSimpleTypes/@EntryValue">UseVar</s:String> <s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForSimpleTypes/@EntryValue">UseVar</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=BC/@EntryIndexedValue">BC</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=BC/@EntryIndexedValue">BC</s:String>
......
...@@ -12,17 +12,18 @@ namespace Titanium.Web.Proxy ...@@ -12,17 +12,18 @@ namespace Titanium.Web.Proxy
/// Call back to override server certificate validation /// Call back to override server certificate validation
/// </summary> /// </summary>
/// <param name="sender">The sender object.</param> /// <param name="sender">The sender object.</param>
/// <param name="sessionArgs">The http session.</param>
/// <param name="certificate">The remote certificate.</param> /// <param name="certificate">The remote certificate.</param>
/// <param name="chain">The certificate chain.</param> /// <param name="chain">The certificate chain.</param>
/// <param name="sslPolicyErrors">Ssl policy errors</param> /// <param name="sslPolicyErrors">Ssl policy errors</param>
/// <returns>Return true if valid certificate.</returns> /// <returns>Return true if valid certificate.</returns>
internal bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, internal bool ValidateServerCertificate(object sender, SessionEventArgsBase sessionArgs, X509Certificate certificate, X509Chain chain,
SslPolicyErrors sslPolicyErrors) SslPolicyErrors sslPolicyErrors)
{ {
// if user callback is registered then do it // if user callback is registered then do it
if (ServerCertificateValidationCallback != null) if (ServerCertificateValidationCallback != null)
{ {
var args = new CertificateValidationEventArgs(certificate, chain, sslPolicyErrors); var args = new CertificateValidationEventArgs(sessionArgs, certificate, chain, sslPolicyErrors);
// why is the sender null? // why is the sender null?
ServerCertificateValidationCallback.InvokeAsync(this, args, ExceptionFunc).Wait(); ServerCertificateValidationCallback.InvokeAsync(this, args, ExceptionFunc).Wait();
...@@ -43,12 +44,13 @@ namespace Titanium.Web.Proxy ...@@ -43,12 +44,13 @@ namespace Titanium.Web.Proxy
/// Call back to select client certificate used for mutual authentication /// Call back to select client certificate used for mutual authentication
/// </summary> /// </summary>
/// <param name="sender">The sender.</param> /// <param name="sender">The sender.</param>
/// <param name="sessionArgs">The http session.</param>
/// <param name="targetHost">The remote hostname.</param> /// <param name="targetHost">The remote hostname.</param>
/// <param name="localCertificates">Selected local certificates by SslStream.</param> /// <param name="localCertificates">Selected local certificates by SslStream.</param>
/// <param name="remoteCertificate">The remote certificate of server.</param> /// <param name="remoteCertificate">The remote certificate of server.</param>
/// <param name="acceptableIssuers">The acceptable issues for client certificate as listed by server.</param> /// <param name="acceptableIssuers">The acceptable issues for client certificate as listed by server.</param>
/// <returns></returns> /// <returns></returns>
internal X509Certificate? SelectClientCertificate(object sender, string targetHost, internal X509Certificate? SelectClientCertificate(object sender, SessionEventArgsBase sessionArgs, string targetHost,
X509CertificateCollection localCertificates, X509CertificateCollection localCertificates,
X509Certificate remoteCertificate, string[] acceptableIssuers) X509Certificate remoteCertificate, string[] acceptableIssuers)
{ {
...@@ -75,12 +77,8 @@ namespace Titanium.Web.Proxy ...@@ -75,12 +77,8 @@ namespace Titanium.Web.Proxy
// If user call back is registered // If user call back is registered
if (ClientCertificateSelectionCallback != null) 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 ClientCertificate = clientCertificate
}; };
......
using System; using System;
using System.IO; using System.IO;
using System.IO.Compression; using System.IO.Compression;
using Titanium.Web.Proxy.Http;
namespace Titanium.Web.Proxy.Compression namespace Titanium.Web.Proxy.Compression
{ {
......
using System; using System;
using System.IO; using System.IO;
using System.IO.Compression; using System.IO.Compression;
using Titanium.Web.Proxy.Http;
namespace Titanium.Web.Proxy.Compression namespace Titanium.Web.Proxy.Compression
{ {
......
using System.IO.Compression; using System;
namespace Titanium.Web.Proxy.Compression namespace Titanium.Web.Proxy.Compression
{ {
......
using System; using System;
using System.Threading; using System.Threading;
using Titanium.Web.Proxy.Network.Tcp;
namespace Titanium.Web.Proxy.EventArguments namespace Titanium.Web.Proxy.EventArguments
{ {
/// <summary> /// <summary>
/// This is used in transparent endpoint before authenticating client. /// This is used in transparent endpoint before authenticating client.
/// </summary> /// </summary>
public class BeforeSslAuthenticateEventArgs : EventArgs public class BeforeSslAuthenticateEventArgs : ProxyEventArgsBase
{ {
internal readonly CancellationTokenSource TaskCancellationSource; internal readonly CancellationTokenSource TaskCancellationSource;
internal BeforeSslAuthenticateEventArgs(CancellationTokenSource taskCancellationSource, string sniHostName) internal BeforeSslAuthenticateEventArgs(TcpClientConnection clientConnection, CancellationTokenSource taskCancellationSource, string sniHostName) : base(clientConnection)
{ {
TaskCancellationSource = taskCancellationSource; TaskCancellationSource = taskCancellationSource;
SniHostName = sniHostName; SniHostName = sniHostName;
......
...@@ -6,32 +6,42 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -6,32 +6,42 @@ namespace Titanium.Web.Proxy.EventArguments
/// <summary> /// <summary>
/// An argument passed on to user for client certificate selection during mutual SSL authentication. /// An argument passed on to user for client certificate selection during mutual SSL authentication.
/// </summary> /// </summary>
public class CertificateSelectionEventArgs : EventArgs public class CertificateSelectionEventArgs : ProxyEventArgsBase
{ {
/// <summary> public CertificateSelectionEventArgs(SessionEventArgsBase session, string targetHost,
/// The proxy server instance. X509CertificateCollection localCertificates, X509Certificate remoteCertificate, string[] acceptableIssuers) : base(session.ClientConnection)
/// </summary> {
public object? Sender { get; internal set; } Session = session;
TargetHost = targetHost;
LocalCertificates = localCertificates;
RemoteCertificate = remoteCertificate;
AcceptableIssuers = acceptableIssuers;
}
/// <value>
/// The session.
/// </value>
public SessionEventArgsBase Session { get; }
/// <summary> /// <summary>
/// The remote hostname to which we are authenticating against. /// The remote hostname to which we are authenticating against.
/// </summary> /// </summary>
public string? TargetHost { get; internal set; } public string TargetHost { get; }
/// <summary> /// <summary>
/// Local certificates in store with matching issuers requested by TargetHost website. /// Local certificates in store with matching issuers requested by TargetHost website.
/// </summary> /// </summary>
public X509CertificateCollection? LocalCertificates { get; internal set; } public X509CertificateCollection LocalCertificates { get; }
/// <summary> /// <summary>
/// Certificate of the remote server. /// Certificate of the remote server.
/// </summary> /// </summary>
public X509Certificate? RemoteCertificate { get; internal set; } public X509Certificate RemoteCertificate { get; }
/// <summary> /// <summary>
/// Acceptable issuers as listed by remote server. /// Acceptable issuers as listed by remote server.
/// </summary> /// </summary>
public string[]? AcceptableIssuers { get; internal set; } public string[] AcceptableIssuers { get; }
/// <summary> /// <summary>
/// Client Certificate we selected. Set this value to override. /// Client Certificate we selected. Set this value to override.
......
...@@ -8,15 +8,21 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -8,15 +8,21 @@ namespace Titanium.Web.Proxy.EventArguments
/// An argument passed on to the user for validating the server certificate /// An argument passed on to the user for validating the server certificate
/// during SSL authentication. /// during SSL authentication.
/// </summary> /// </summary>
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; Certificate = certificate;
Chain = chain; Chain = chain;
SslPolicyErrors = sslPolicyErrors; SslPolicyErrors = sslPolicyErrors;
} }
/// <value>
/// The session.
/// </value>
public SessionEventArgsBase Session { get; }
/// <summary> /// <summary>
/// Server certificate. /// Server certificate.
/// </summary> /// </summary>
......
using System; using Titanium.Web.Proxy.Http;
using Titanium.Web.Proxy.Http;
namespace Titanium.Web.Proxy.EventArguments namespace Titanium.Web.Proxy.EventArguments
{ {
/// <summary> /// <summary>
/// Class that wraps the multipart sent request arguments. /// Class that wraps the multipart sent request arguments.
/// </summary> /// </summary>
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; Boundary = boundary;
Headers = headers; Headers = headers;
} }
/// <value>
/// The session arguments.
/// </value>
public SessionEventArgs Session { get; }
/// <summary> /// <summary>
/// Boundary. /// Boundary.
/// </summary> /// </summary>
......
using System;
using Titanium.Web.Proxy.Network.Tcp;
namespace Titanium.Web.Proxy.EventArguments
{
/// <summary>
/// The base event arguments
/// </summary>
/// <seealso cref="System.EventArgs" />
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;
}
}
}
...@@ -8,7 +8,6 @@ using Titanium.Web.Proxy.Helpers; ...@@ -8,7 +8,6 @@ using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Http; using Titanium.Web.Proxy.Http;
using Titanium.Web.Proxy.Http.Responses; using Titanium.Web.Proxy.Http.Responses;
using Titanium.Web.Proxy.Models; using Titanium.Web.Proxy.Models;
using Titanium.Web.Proxy.Network.Tcp;
using Titanium.Web.Proxy.StreamExtended.Network; using Titanium.Web.Proxy.StreamExtended.Network;
namespace Titanium.Web.Proxy.EventArguments namespace Titanium.Web.Proxy.EventArguments
...@@ -36,8 +35,8 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -36,8 +35,8 @@ namespace Titanium.Web.Proxy.EventArguments
/// <summary> /// <summary>
/// Constructor to initialize the proxy /// Constructor to initialize the proxy
/// </summary> /// </summary>
internal SessionEventArgs(ProxyServer server, ProxyEndPoint endPoint, TcpClientConnection clientConnection, HttpClientStream clientStream, ConnectRequest? connectRequest, CancellationTokenSource cancellationTokenSource) internal SessionEventArgs(ProxyServer server, ProxyEndPoint endPoint, HttpClientStream clientStream, ConnectRequest? connectRequest, CancellationTokenSource cancellationTokenSource)
: base(server, endPoint, clientConnection, clientStream, connectRequest, new Request(), cancellationTokenSource) : base(server, endPoint, clientStream, connectRequest, new Request(), cancellationTokenSource)
{ {
} }
...@@ -127,7 +126,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -127,7 +126,7 @@ namespace Titanium.Web.Proxy.EventArguments
{ {
try try
{ {
MultipartRequestPartSent?.Invoke(this, new MultipartRequestPartSentEventArgs(boundary.ToString(), headers)); MultipartRequestPartSent?.Invoke(this, new MultipartRequestPartSentEventArgs(this, boundary.ToString(), headers));
} }
catch (Exception ex) catch (Exception ex)
{ {
......
...@@ -5,7 +5,6 @@ using System.Threading; ...@@ -5,7 +5,6 @@ using System.Threading;
using Titanium.Web.Proxy.Helpers; using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Http; using Titanium.Web.Proxy.Http;
using Titanium.Web.Proxy.Models; using Titanium.Web.Proxy.Models;
using Titanium.Web.Proxy.Network;
using Titanium.Web.Proxy.Network.Tcp; using Titanium.Web.Proxy.Network.Tcp;
using Titanium.Web.Proxy.StreamExtended.BufferPool; using Titanium.Web.Proxy.StreamExtended.BufferPool;
using Titanium.Web.Proxy.StreamExtended.Network; using Titanium.Web.Proxy.StreamExtended.Network;
...@@ -18,7 +17,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -18,7 +17,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// A proxy session ends when client terminates connection to proxy /// A proxy session ends when client terminates connection to proxy
/// or when server terminates connection from proxy. /// or when server terminates connection from proxy.
/// </summary> /// </summary>
public abstract class SessionEventArgsBase : EventArgs, IDisposable public abstract class SessionEventArgsBase : ProxyEventArgsBase, IDisposable
{ {
private static bool isWindowsAuthenticationSupported => RunTime.IsWindows; private static bool isWindowsAuthenticationSupported => RunTime.IsWindows;
...@@ -29,7 +28,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -29,7 +28,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// <summary> /// <summary>
/// Holds a reference to client /// Holds a reference to client
/// </summary> /// </summary>
internal TcpClientConnection ClientConnection { get; } internal TcpClientConnection ClientConnection => ClientStream.Connection;
internal HttpClientStream ClientStream { get; } internal HttpClientStream ClientStream { get; }
...@@ -50,7 +49,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -50,7 +49,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// Initializes a new instance of the <see cref="SessionEventArgsBase" /> class. /// Initializes a new instance of the <see cref="SessionEventArgsBase" /> class.
/// </summary> /// </summary>
private protected SessionEventArgsBase(ProxyServer server, ProxyEndPoint endPoint, 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; BufferPool = server.BufferPool;
ExceptionFunc = server.ExceptionFunc; ExceptionFunc = server.ExceptionFunc;
...@@ -58,9 +57,8 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -58,9 +57,8 @@ namespace Titanium.Web.Proxy.EventArguments
CancellationTokenSource = cancellationTokenSource; CancellationTokenSource = cancellationTokenSource;
ClientConnection = clientConnection;
ClientStream = clientStream; ClientStream = clientStream;
HttpClient = new HttpWebClient(connectRequest, request, new Lazy<int>(() => clientConnection.GetProcessId(endPoint))); HttpClient = new HttpWebClient(connectRequest, request, new Lazy<int>(() => clientStream.Connection.GetProcessId(endPoint)));
LocalEndPoint = endPoint; LocalEndPoint = endPoint;
EnableWinAuth = server.EnableWinAuth && isWindowsAuthenticationSupported; EnableWinAuth = server.EnableWinAuth && isWindowsAuthenticationSupported;
} }
......
...@@ -3,8 +3,6 @@ using System.Threading; ...@@ -3,8 +3,6 @@ using System.Threading;
using Titanium.Web.Proxy.Helpers; using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Http; using Titanium.Web.Proxy.Http;
using Titanium.Web.Proxy.Models; using Titanium.Web.Proxy.Models;
using Titanium.Web.Proxy.Network;
using Titanium.Web.Proxy.Network.Tcp;
using Titanium.Web.Proxy.StreamExtended.Network; using Titanium.Web.Proxy.StreamExtended.Network;
namespace Titanium.Web.Proxy.EventArguments namespace Titanium.Web.Proxy.EventArguments
...@@ -17,8 +15,8 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -17,8 +15,8 @@ namespace Titanium.Web.Proxy.EventArguments
private bool? isHttpsConnect; private bool? isHttpsConnect;
internal TunnelConnectSessionEventArgs(ProxyServer server, ProxyEndPoint endPoint, ConnectRequest connectRequest, internal TunnelConnectSessionEventArgs(ProxyServer server, ProxyEndPoint endPoint, ConnectRequest connectRequest,
TcpClientConnection clientConnection, HttpClientStream clientStream, CancellationTokenSource cancellationTokenSource) HttpClientStream clientStream, CancellationTokenSource cancellationTokenSource)
: base(server, endPoint, clientConnection, clientStream, connectRequest, connectRequest, cancellationTokenSource) : base(server, endPoint, clientStream, connectRequest, connectRequest, cancellationTokenSource)
{ {
} }
......
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Net; using System.Net;
using System.Net.Security; using System.Net.Security;
...@@ -14,10 +13,8 @@ using Titanium.Web.Proxy.Helpers; ...@@ -14,10 +13,8 @@ using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Http; using Titanium.Web.Proxy.Http;
using Titanium.Web.Proxy.Http2; using Titanium.Web.Proxy.Http2;
using Titanium.Web.Proxy.Models; using Titanium.Web.Proxy.Models;
using Titanium.Web.Proxy.Network;
using Titanium.Web.Proxy.Network.Tcp; using Titanium.Web.Proxy.Network.Tcp;
using Titanium.Web.Proxy.StreamExtended; using Titanium.Web.Proxy.StreamExtended;
using Titanium.Web.Proxy.StreamExtended.Network;
using SslExtensions = Titanium.Web.Proxy.Extensions.SslExtensions; using SslExtensions = Titanium.Web.Proxy.Extensions.SslExtensions;
namespace Titanium.Web.Proxy namespace Titanium.Web.Proxy
...@@ -36,7 +33,7 @@ namespace Titanium.Web.Proxy ...@@ -36,7 +33,7 @@ namespace Titanium.Web.Proxy
var cancellationTokenSource = new CancellationTokenSource(); var cancellationTokenSource = new CancellationTokenSource();
var cancellationToken = cancellationTokenSource.Token; var cancellationToken = cancellationTokenSource.Token;
var clientStream = new HttpClientStream(clientConnection.GetStream(), BufferPool); var clientStream = new HttpClientStream(clientConnection, clientConnection.GetStream(), BufferPool);
Task<TcpServerConnection>? prefetchConnectionTask = null; Task<TcpServerConnection>? prefetchConnectionTask = null;
bool closeServerConnection = false; bool closeServerConnection = false;
...@@ -72,8 +69,7 @@ namespace Titanium.Web.Proxy ...@@ -72,8 +69,7 @@ namespace Titanium.Web.Proxy
await HeaderParser.ReadHeaders(clientStream, connectRequest.Headers, cancellationToken); await HeaderParser.ReadHeaders(clientStream, connectRequest.Headers, cancellationToken);
connectArgs = new TunnelConnectSessionEventArgs(this, endPoint, connectRequest, connectArgs = new TunnelConnectSessionEventArgs(this, endPoint, connectRequest, clientStream, cancellationTokenSource);
clientConnection, clientStream, cancellationTokenSource);
clientStream.DataRead += (o, args) => connectArgs.OnDataSent(args.Buffer, args.Offset, args.Count); clientStream.DataRead += (o, args) => connectArgs.OnDataSent(args.Buffer, args.Offset, args.Count);
clientStream.DataWrite += (o, args) => connectArgs.OnDataReceived(args.Buffer, args.Offset, args.Count); clientStream.DataWrite += (o, args) => connectArgs.OnDataReceived(args.Buffer, args.Offset, args.Count);
...@@ -137,7 +133,7 @@ namespace Titanium.Web.Proxy ...@@ -137,7 +133,7 @@ namespace Titanium.Web.Proxy
if (decryptSsl && clientHelloInfo != null) if (decryptSsl && clientHelloInfo != null)
{ {
connectRequest.IsHttps = true; // todo: move this line to the previous "if" connectRequest.IsHttps = true; // todo: move this line to the previous "if"
clientConnection.SslProtocol = clientHelloInfo.SslProtocol; clientStream.Connection.SslProtocol = clientHelloInfo.SslProtocol;
bool http2Supported = false; bool http2Supported = false;
...@@ -221,11 +217,11 @@ namespace Titanium.Web.Proxy ...@@ -221,11 +217,11 @@ namespace Titanium.Web.Proxy
await sslStream.AuthenticateAsServerAsync(options, cancellationToken); await sslStream.AuthenticateAsServerAsync(options, cancellationToken);
#if NETSTANDARD2_1 #if NETSTANDARD2_1
clientConnection.NegotiatedApplicationProtocol = sslStream.NegotiatedApplicationProtocol; clientStream.Connection.NegotiatedApplicationProtocol = sslStream.NegotiatedApplicationProtocol;
#endif #endif
// HTTPS server created - we can now decrypt the client's traffic // 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 sslStream = null; // clientStream was created, no need to keep SSL stream reference
clientStream.DataRead += (o, args) => connectArgs.OnDecryptedDataSent(args.Buffer, args.Offset, args.Count); clientStream.DataRead += (o, args) => connectArgs.OnDecryptedDataSent(args.Buffer, args.Offset, args.Count);
...@@ -362,13 +358,13 @@ namespace Titanium.Web.Proxy ...@@ -362,13 +358,13 @@ namespace Titanium.Web.Proxy
var connectionPreface = new ReadOnlyMemory<byte>(Http2Helper.ConnectionPreface); var connectionPreface = new ReadOnlyMemory<byte>(Http2Helper.ConnectionPreface);
await connection.Stream.WriteAsync(connectionPreface, cancellationToken); await connection.Stream.WriteAsync(connectionPreface, cancellationToken);
await Http2Helper.SendHttp2(clientStream, connection.Stream, 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 UserData = connectArgs?.UserData
}, },
async args => { await onBeforeRequest(args); }, async args => { await onBeforeRequest(args); },
async args => { await onBeforeResponse(args); }, async args => { await onBeforeResponse(args); },
connectArgs.CancellationTokenSource, clientConnection.Id, ExceptionFunc); connectArgs.CancellationTokenSource, clientStream.Connection.Id, ExceptionFunc);
#endif #endif
} }
finally finally
...@@ -381,7 +377,7 @@ namespace Titanium.Web.Proxy ...@@ -381,7 +377,7 @@ namespace Titanium.Web.Proxy
calledRequestHandler = true; calledRequestHandler = true;
// Now create the request // Now create the request
await handleHttpSessionRequest(endPoint, clientConnection, clientStream, cancellationTokenSource, connectArgs, prefetchConnectionTask); await handleHttpSessionRequest(endPoint, clientStream, cancellationTokenSource, connectArgs, prefetchConnectionTask);
} }
catch (ProxyException e) catch (ProxyException e)
{ {
......
using System; using System;
using System.Globalization; using System.Globalization;
using Titanium.Web.Proxy.Models;
namespace Titanium.Web.Proxy.Extensions namespace Titanium.Web.Proxy.Extensions
{ {
internal static class StringExtensions 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); return str.Equals(value, StringComparison.CurrentCultureIgnoreCase);
} }
...@@ -16,12 +15,12 @@ namespace Titanium.Web.Proxy.Extensions ...@@ -16,12 +15,12 @@ namespace Titanium.Web.Proxy.Extensions
return str.Equals(value, StringComparison.CurrentCultureIgnoreCase); 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; 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); return CultureInfo.CurrentCulture.CompareInfo.IndexOf(str, value, CompareOptions.IgnoreCase);
} }
......
using System; using System;
using System.Text;
namespace Titanium.Web.Proxy.Extensions namespace Titanium.Web.Proxy.Extensions
{ {
......
...@@ -3,15 +3,19 @@ using System.IO; ...@@ -3,15 +3,19 @@ using System.IO;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Titanium.Web.Proxy.Http; using Titanium.Web.Proxy.Http;
using Titanium.Web.Proxy.Network.Tcp;
using Titanium.Web.Proxy.StreamExtended.BufferPool; using Titanium.Web.Proxy.StreamExtended.BufferPool;
namespace Titanium.Web.Proxy.Helpers namespace Titanium.Web.Proxy.Helpers
{ {
internal sealed class HttpClientStream : HttpStream 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) : base(stream, bufferPool)
{ {
Connection = connection;
} }
/// <summary> /// <summary>
......
...@@ -6,7 +6,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -6,7 +6,7 @@ namespace Titanium.Web.Proxy.Helpers
internal partial class NativeMethods internal partial class NativeMethods
{ {
// Keeps it from getting garbage collected // Keeps it from getting garbage collected
internal static ConsoleEventDelegate Handler; internal static ConsoleEventDelegate? Handler;
[DllImport("wininet.dll")] [DllImport("wininet.dll")]
internal static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer, internal static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer,
......
...@@ -211,12 +211,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -211,12 +211,7 @@ namespace Titanium.Web.Proxy.Helpers
if (protocolType.HasValue) if (protocolType.HasValue)
{ {
var endPointParts = tmp.Substring(equalsIndex + 1).Split(':'); var endPointParts = tmp.Substring(equalsIndex + 1).Split(':');
return new HttpSystemProxyValue return new HttpSystemProxyValue(endPointParts[0], int.Parse(endPointParts[1]), protocolType.Value);
{
HostName = endPointParts[0],
Port = int.Parse(endPointParts[1]),
ProtocolType = protocolType.Value
};
} }
} }
......
...@@ -9,11 +9,18 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -9,11 +9,18 @@ namespace Titanium.Web.Proxy.Helpers
{ {
internal class HttpSystemProxyValue 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() public override string ToString()
{ {
...@@ -56,7 +63,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -56,7 +63,7 @@ namespace Titanium.Web.Proxy.Helpers
AppDomain.CurrentDomain.ProcessExit += (o, args) => RestoreOriginalSettings(); AppDomain.CurrentDomain.ProcessExit += (o, args) => RestoreOriginalSettings();
if (Environment.UserInteractive && NativeMethods.GetConsoleWindow() != IntPtr.Zero) if (Environment.UserInteractive && NativeMethods.GetConsoleWindow() != IntPtr.Zero)
{ {
NativeMethods.Handler = eventType => var handler = new NativeMethods.ConsoleEventDelegate(eventType =>
{ {
if (eventType != 2) if (eventType != 2)
{ {
...@@ -65,10 +72,11 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -65,10 +72,11 @@ namespace Titanium.Web.Proxy.Helpers
RestoreOriginalSettings(); RestoreOriginalSettings();
return false; return false;
}; });
NativeMethods.Handler = handler;
// On Console exit make sure we also exit the proxy // On Console exit make sure we also exit the proxy
NativeMethods.SetConsoleCtrlHandler(NativeMethods.Handler, true); NativeMethods.SetConsoleCtrlHandler(handler, true);
} }
} }
...@@ -95,22 +103,12 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -95,22 +103,12 @@ namespace Titanium.Web.Proxy.Helpers
existingSystemProxyValues.RemoveAll(x => (protocolType & x.ProtocolType) != 0); existingSystemProxyValues.RemoveAll(x => (protocolType & x.ProtocolType) != 0);
if ((protocolType & ProxyProtocolType.Http) != 0) if ((protocolType & ProxyProtocolType.Http) != 0)
{ {
existingSystemProxyValues.Add(new HttpSystemProxyValue existingSystemProxyValues.Add(new HttpSystemProxyValue(hostname, port, ProxyProtocolType.Http));
{
HostName = hostname,
ProtocolType = ProxyProtocolType.Http,
Port = port
});
} }
if ((protocolType & ProxyProtocolType.Https) != 0) if ((protocolType & ProxyProtocolType.Https) != 0)
{ {
existingSystemProxyValues.Add(new HttpSystemProxyValue existingSystemProxyValues.Add(new HttpSystemProxyValue(hostname, port, ProxyProtocolType.Https));
{
HostName = hostname,
ProtocolType = ProxyProtocolType.Https,
Port = port
});
} }
reg.DeleteValue(regAutoConfigUrl, false); reg.DeleteValue(regAutoConfigUrl, false);
......
using System; using System;
using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Models; using Titanium.Web.Proxy.Models;
using Titanium.Web.Proxy.StreamExtended; using Titanium.Web.Proxy.StreamExtended;
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
using System.Buffers; using System.Buffers;
using System.IO; using System.IO;
using System.Text; using System.Text;
using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Models; using Titanium.Web.Proxy.Models;
using Titanium.Web.Proxy.Shared; using Titanium.Web.Proxy.Shared;
......
...@@ -4,7 +4,6 @@ using System.Collections.Generic; ...@@ -4,7 +4,6 @@ using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.ComponentModel; using System.ComponentModel;
using System.Linq; using System.Linq;
using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Models; using Titanium.Web.Proxy.Models;
namespace Titanium.Web.Proxy.Http namespace Titanium.Web.Proxy.Http
......
using System; using System;
using System.IO;
using System.Net; using System.Net;
using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; 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; using Titanium.Web.Proxy.Network.Tcp;
namespace Titanium.Web.Proxy.Http namespace Titanium.Web.Proxy.Http
......
...@@ -26,7 +26,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -26,7 +26,7 @@ namespace Titanium.Web.Proxy.Http
return String.AsSpan().EqualsIgnoreCase(value); return String.AsSpan().EqualsIgnoreCase(value);
} }
internal bool Equals(string value) internal bool Equals(string? value)
{ {
return String.EqualsIgnoreCase(value); return String.EqualsIgnoreCase(value);
} }
......
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Text;
using Titanium.Web.Proxy.Exceptions; using Titanium.Web.Proxy.Exceptions;
using Titanium.Web.Proxy.Extensions; using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Models; using Titanium.Web.Proxy.Models;
namespace Titanium.Web.Proxy.Http namespace Titanium.Web.Proxy.Http
......
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Text;
using Titanium.Web.Proxy.Extensions; using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Models; using Titanium.Web.Proxy.Models;
namespace Titanium.Web.Proxy.Http namespace Titanium.Web.Proxy.Http
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
using System; using System;
using System.IO; using System.IO;
using System.Text;
using Titanium.Web.Proxy.Models; using Titanium.Web.Proxy.Models;
namespace Titanium.Web.Proxy.Http2.Hpack namespace Titanium.Web.Proxy.Http2.Hpack
......
...@@ -141,7 +141,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack ...@@ -141,7 +141,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack
} }
Size -= removed.Size; Size -= removed.Size;
headerFields[tail++] = null; headerFields[tail++] = null!;
if (tail == headerFields.Length) if (tail == headerFields.Length)
{ {
tail = 0; tail = 0;
...@@ -157,7 +157,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack ...@@ -157,7 +157,7 @@ namespace Titanium.Web.Proxy.Http2.Hpack
{ {
while (tail != head) while (tail != head)
{ {
headerFields[tail++] = null; headerFields[tail++] = null!;
if (tail == headerFields.Length) if (tail == headerFields.Length)
{ {
tail = 0; tail = 0;
......
 #if NETSTANDARD2_1
using Titanium.Web.Proxy.Extensions;
#if NETSTANDARD2_1
/* /*
* Copyright 2014 Twitter, Inc * Copyright 2014 Twitter, Inc
* This file is a derivative work modified by Ringo Leese * This file is a derivative work modified by Ringo Leese
...@@ -20,7 +17,6 @@ using Titanium.Web.Proxy.Extensions; ...@@ -20,7 +17,6 @@ using Titanium.Web.Proxy.Extensions;
*/ */
using System; using System;
using System.IO; using System.IO;
using System.Text;
using Titanium.Web.Proxy.Models; using Titanium.Web.Proxy.Models;
namespace Titanium.Web.Proxy.Http2.Hpack namespace Titanium.Web.Proxy.Http2.Hpack
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
using System; using System;
using System.IO; using System.IO;
using System.Text;
namespace Titanium.Web.Proxy.Http2.Hpack namespace Titanium.Web.Proxy.Http2.Hpack
{ {
......
...@@ -17,8 +17,6 @@ ...@@ -17,8 +17,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text;
using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Models; using Titanium.Web.Proxy.Models;
namespace Titanium.Web.Proxy.Http2.Hpack namespace Titanium.Web.Proxy.Http2.Hpack
......
...@@ -3,7 +3,6 @@ using Titanium.Web.Proxy.Extensions; ...@@ -3,7 +3,6 @@ using Titanium.Web.Proxy.Extensions;
#if NETSTANDARD2_1 #if NETSTANDARD2_1
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Net; using System.Net;
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
using System.Net; using System.Net;
using System.Text; using System.Text;
using Titanium.Web.Proxy.Extensions; using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Http; using Titanium.Web.Proxy.Http;
namespace Titanium.Web.Proxy.Models namespace Titanium.Web.Proxy.Models
......
...@@ -16,6 +16,8 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -16,6 +16,8 @@ namespace Titanium.Web.Proxy.Network.Tcp
/// </summary> /// </summary>
internal class TcpClientConnection : IDisposable internal class TcpClientConnection : IDisposable
{ {
public object ClientUserData { get; set; }
internal TcpClientConnection(ProxyServer proxyServer, TcpClient tcpClient) internal TcpClientConnection(ProxyServer proxyServer, TcpClient tcpClient)
{ {
this.tcpClient = tcpClient; this.tcpClient = tcpClient;
......
...@@ -6,7 +6,6 @@ using System.Threading.Tasks; ...@@ -6,7 +6,6 @@ using System.Threading.Tasks;
using Titanium.Web.Proxy.Extensions; using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Helpers; using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Models; using Titanium.Web.Proxy.Models;
using Titanium.Web.Proxy.StreamExtended.Network;
namespace Titanium.Web.Proxy.Network.Tcp namespace Titanium.Web.Proxy.Network.Tcp
{ {
......
// http://pinvoke.net/default.aspx/secur32/InitializeSecurityContext.html // http://pinvoke.net/default.aspx/secur32/InitializeSecurityContext.html
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Security.Principal; using System.Security.Principal;
using Titanium.Web.Proxy.Http; using Titanium.Web.Proxy.Http;
......
...@@ -4,7 +4,6 @@ using System.Text; ...@@ -4,7 +4,6 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Titanium.Web.Proxy.EventArguments; using Titanium.Web.Proxy.EventArguments;
using Titanium.Web.Proxy.Exceptions; using Titanium.Web.Proxy.Exceptions;
using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Http; using Titanium.Web.Proxy.Http;
using Titanium.Web.Proxy.Models; using Titanium.Web.Proxy.Models;
......
...@@ -15,7 +15,6 @@ using Titanium.Web.Proxy.Models; ...@@ -15,7 +15,6 @@ using Titanium.Web.Proxy.Models;
using Titanium.Web.Proxy.Network; using Titanium.Web.Proxy.Network;
using Titanium.Web.Proxy.Network.Tcp; using Titanium.Web.Proxy.Network.Tcp;
using Titanium.Web.Proxy.StreamExtended.BufferPool; using Titanium.Web.Proxy.StreamExtended.BufferPool;
using Titanium.Web.Proxy.StreamExtended.Network;
namespace Titanium.Web.Proxy namespace Titanium.Web.Proxy
{ {
...@@ -705,7 +704,7 @@ namespace Titanium.Web.Proxy ...@@ -705,7 +704,7 @@ namespace Titanium.Web.Proxy
throw new ArgumentNullException(nameof(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"); throw new Exception("Cannot set endPoints not added to proxy as system proxy");
} }
...@@ -739,7 +738,7 @@ namespace Titanium.Web.Proxy ...@@ -739,7 +738,7 @@ namespace Titanium.Web.Proxy
try try
{ {
// based on end point type call appropriate request handlers // based on end point type call appropriate request handlers
tcpClient = endPoint.Listener.EndAcceptTcpClient(asyn); tcpClient = endPoint.Listener!.EndAcceptTcpClient(asyn);
tcpClient.NoDelay = NoDelay; tcpClient.NoDelay = NoDelay;
} }
catch (ObjectDisposedException) catch (ObjectDisposedException)
...@@ -763,7 +762,7 @@ namespace Titanium.Web.Proxy ...@@ -763,7 +762,7 @@ namespace Titanium.Web.Proxy
} }
// Get the listener that handles the client request. // Get the listener that handles the client request.
endPoint.Listener.BeginAcceptTcpClient(onAcceptConnection, endPoint); endPoint.Listener!.BeginAcceptTcpClient(onAcceptConnection, endPoint);
} }
...@@ -795,7 +794,7 @@ namespace Titanium.Web.Proxy ...@@ -795,7 +794,7 @@ namespace Titanium.Web.Proxy
tcpClient.LingerState = new LingerOption(true, TcpTimeWaitSeconds); tcpClient.LingerState = new LingerOption(true, TcpTimeWaitSeconds);
await InvokeConnectionCreateEvent(tcpClient, true); await InvokeClientConnectionCreateEvent(tcpClient);
using (var clientConnection = new TcpClientConnection(this, tcpClient)) using (var clientConnection = new TcpClientConnection(this, tcpClient))
{ {
...@@ -825,7 +824,7 @@ namespace Titanium.Web.Proxy ...@@ -825,7 +824,7 @@ namespace Titanium.Web.Proxy
/// </summary> /// </summary>
private void quitListen(ProxyEndPoint endPoint) private void quitListen(ProxyEndPoint endPoint)
{ {
endPoint.Listener.Stop(); endPoint.Listener!.Stop();
endPoint.Listener.Server.Dispose(); endPoint.Listener.Server.Dispose();
} }
...@@ -866,21 +865,28 @@ namespace Titanium.Web.Proxy ...@@ -866,21 +865,28 @@ namespace Titanium.Web.Proxy
} }
/// <summary> /// <summary>
/// Invoke client/server tcp connection events if subscribed by API user. /// Invoke client tcp connection events if subscribed by API user.
/// </summary> /// </summary>
/// <param name="client">The TcpClient object.</param> /// <param name="client">The TcpClient object.</param>
/// <param name="isClientConnection">Is this a client connection created event? If not then we would assume that its a server connection create event.</param>
/// <returns></returns> /// <returns></returns>
internal async Task InvokeConnectionCreateEvent(TcpClient client, bool isClientConnection) internal async Task InvokeClientConnectionCreateEvent(TcpClient client)
{ {
// client connection created // client connection created
if (isClientConnection && OnClientConnectionCreate != null) if (OnClientConnectionCreate != null)
{ {
await OnClientConnectionCreate.InvokeAsync(this, client, ExceptionFunc); await OnClientConnectionCreate.InvokeAsync(this, client, ExceptionFunc);
} }
}
/// <summary>
/// Invoke server tcp connection events if subscribed by API user.
/// </summary>
/// <param name="client">The TcpClient object.</param>
/// <returns></returns>
internal async Task InvokeServerConnectionCreateEvent(TcpClient client)
{
// server connection created // server connection created
if (!isClientConnection && OnServerConnectionCreate != null) if (OnServerConnectionCreate != null)
{ {
await OnServerConnectionCreate.InvokeAsync(this, client, ExceptionFunc); await OnServerConnectionCreate.InvokeAsync(this, client, ExceptionFunc);
} }
......
...@@ -14,7 +14,6 @@ using Titanium.Web.Proxy.Models; ...@@ -14,7 +14,6 @@ using Titanium.Web.Proxy.Models;
using Titanium.Web.Proxy.Network; using Titanium.Web.Proxy.Network;
using Titanium.Web.Proxy.Network.Tcp; using Titanium.Web.Proxy.Network.Tcp;
using Titanium.Web.Proxy.Shared; using Titanium.Web.Proxy.Shared;
using Titanium.Web.Proxy.StreamExtended.Network;
namespace Titanium.Web.Proxy namespace Titanium.Web.Proxy
{ {
...@@ -29,13 +28,12 @@ namespace Titanium.Web.Proxy ...@@ -29,13 +28,12 @@ namespace Titanium.Web.Proxy
/// client/server abruptly terminates connection or by normal HTTP termination. /// client/server abruptly terminates connection or by normal HTTP termination.
/// </summary> /// </summary>
/// <param name="endPoint">The proxy endpoint.</param> /// <param name="endPoint">The proxy endpoint.</param>
/// <param name="clientConnection">The client connection.</param>
/// <param name="clientStream">The client stream.</param> /// <param name="clientStream">The client stream.</param>
/// <param name="cancellationTokenSource">The cancellation token source for this async task.</param> /// <param name="cancellationTokenSource">The cancellation token source for this async task.</param>
/// <param name="connectArgs">The Connect request if this is a HTTPS request from explicit endpoint.</param> /// <param name="connectArgs">The Connect request if this is a HTTPS request from explicit endpoint.</param>
/// <param name="prefetchConnectionTask">Prefetched server connection for current client using Connect/SNI headers.</param> /// <param name="prefetchConnectionTask">Prefetched server connection for current client using Connect/SNI headers.</param>
private async Task handleHttpSessionRequest(ProxyEndPoint endPoint, TcpClientConnection clientConnection, private async Task handleHttpSessionRequest(ProxyEndPoint endPoint, HttpClientStream clientStream,
HttpClientStream clientStream, CancellationTokenSource cancellationTokenSource, TunnelConnectSessionEventArgs? connectArgs = null, CancellationTokenSource cancellationTokenSource, TunnelConnectSessionEventArgs? connectArgs = null,
Task<TcpServerConnection>? prefetchConnectionTask = null) Task<TcpServerConnection>? prefetchConnectionTask = null)
{ {
var connectRequest = connectArgs?.HttpClient.ConnectRequest; var connectRequest = connectArgs?.HttpClient.ConnectRequest;
...@@ -64,7 +62,7 @@ namespace Titanium.Web.Proxy ...@@ -64,7 +62,7 @@ namespace Titanium.Web.Proxy
return; return;
} }
var args = new SessionEventArgs(this, endPoint, clientConnection, clientStream, connectRequest, cancellationTokenSource) var args = new SessionEventArgs(this, endPoint, clientStream, connectRequest, cancellationTokenSource)
{ {
UserData = connectArgs?.UserData UserData = connectArgs?.UserData
}; };
...@@ -163,7 +161,7 @@ namespace Titanium.Web.Proxy ...@@ -163,7 +161,7 @@ namespace Titanium.Web.Proxy
// or when prefetch task has a unexpectedly different connection. // or when prefetch task has a unexpectedly different connection.
if (connection != null if (connection != null
&& (await tcpConnectionFactory.GetConnectionCacheKey(this, args, && (await tcpConnectionFactory.GetConnectionCacheKey(this, args,
clientConnection.NegotiatedApplicationProtocol) clientStream.Connection.NegotiatedApplicationProtocol)
!= connection.CacheKey)) != connection.CacheKey))
{ {
await tcpConnectionFactory.Release(connection); await tcpConnectionFactory.Release(connection);
...@@ -171,7 +169,7 @@ namespace Titanium.Web.Proxy ...@@ -171,7 +169,7 @@ namespace Titanium.Web.Proxy
} }
var result = await handleHttpSessionRequest(args, connection, var result = await handleHttpSessionRequest(args, connection,
clientConnection.NegotiatedApplicationProtocol, clientStream.Connection.NegotiatedApplicationProtocol,
cancellationToken, cancellationTokenSource); cancellationToken, cancellationTokenSource);
// update connection to latest used // update connection to latest used
......
...@@ -3,7 +3,6 @@ using System.Net; ...@@ -3,7 +3,6 @@ using System.Net;
using System.Threading.Tasks; using System.Threading.Tasks;
using Titanium.Web.Proxy.EventArguments; using Titanium.Web.Proxy.EventArguments;
using Titanium.Web.Proxy.Extensions; using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Http;
using Titanium.Web.Proxy.Network.WinAuth.Security; using Titanium.Web.Proxy.Network.WinAuth.Security;
namespace Titanium.Web.Proxy namespace Titanium.Web.Proxy
......
using System; using System;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Titanium.Web.Proxy.StreamExtended.BufferPool;
namespace Titanium.Web.Proxy.StreamExtended.Network namespace Titanium.Web.Proxy.StreamExtended.Network
{ {
......
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.StreamExtended.BufferPool; using Titanium.Web.Proxy.StreamExtended.BufferPool;
using Titanium.Web.Proxy.StreamExtended.Models; using Titanium.Web.Proxy.StreamExtended.Models;
using Titanium.Web.Proxy.StreamExtended.Network; using Titanium.Web.Proxy.StreamExtended.Network;
......
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Net.Security; using System.Net.Security;
using System.Net.Sockets; using System.Net.Sockets;
...@@ -12,10 +11,8 @@ using Titanium.Web.Proxy.Exceptions; ...@@ -12,10 +11,8 @@ using Titanium.Web.Proxy.Exceptions;
using Titanium.Web.Proxy.Extensions; using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Helpers; using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Models; using Titanium.Web.Proxy.Models;
using Titanium.Web.Proxy.Network;
using Titanium.Web.Proxy.Network.Tcp; using Titanium.Web.Proxy.Network.Tcp;
using Titanium.Web.Proxy.StreamExtended; using Titanium.Web.Proxy.StreamExtended;
using Titanium.Web.Proxy.StreamExtended.Network;
namespace Titanium.Web.Proxy namespace Titanium.Web.Proxy
{ {
...@@ -33,7 +30,7 @@ namespace Titanium.Web.Proxy ...@@ -33,7 +30,7 @@ namespace Titanium.Web.Proxy
var cancellationTokenSource = new CancellationTokenSource(); var cancellationTokenSource = new CancellationTokenSource();
var cancellationToken = cancellationTokenSource.Token; var cancellationToken = cancellationTokenSource.Token;
var clientStream = new HttpClientStream(clientConnection.GetStream(), BufferPool); var clientStream = new HttpClientStream(clientConnection, clientConnection.GetStream(), BufferPool);
SslStream? sslStream = null; SslStream? sslStream = null;
...@@ -41,13 +38,11 @@ namespace Titanium.Web.Proxy ...@@ -41,13 +38,11 @@ namespace Titanium.Web.Proxy
{ {
var clientHelloInfo = await SslTools.PeekClientHello(clientStream, BufferPool, cancellationToken); var clientHelloInfo = await SslTools.PeekClientHello(clientStream, BufferPool, cancellationToken);
string? httpsHostName = null;
if (clientHelloInfo != 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); await endPoint.InvokeBeforeSslAuthenticate(this, args, ExceptionFunc);
...@@ -58,7 +53,7 @@ namespace Titanium.Web.Proxy ...@@ -58,7 +53,7 @@ namespace Titanium.Web.Proxy
if (endPoint.DecryptSsl && args.DecryptSsl) if (endPoint.DecryptSsl && args.DecryptSsl)
{ {
clientConnection.SslProtocol = clientHelloInfo.SslProtocol; clientStream.Connection.SslProtocol = clientHelloInfo.SslProtocol;
// do client authentication using certificate // do client authentication using certificate
X509Certificate2? certificate = null; X509Certificate2? certificate = null;
...@@ -74,14 +69,13 @@ namespace Titanium.Web.Proxy ...@@ -74,14 +69,13 @@ namespace Titanium.Web.Proxy
await sslStream.AuthenticateAsServerAsync(certificate, false, SslProtocols.Tls, false); await sslStream.AuthenticateAsServerAsync(certificate, false, SslProtocols.Tls, false);
// HTTPS server created - we can now decrypt the client's traffic // 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 sslStream = null; // clientStream was created, no need to keep SSL stream reference
} }
catch (Exception e) catch (Exception e)
{ {
var certName = certificate?.GetNameInfo(X509NameType.SimpleName, false); var certName = certificate?.GetNameInfo(X509NameType.SimpleName, false);
var session = new SessionEventArgs(this, endPoint, clientConnection, clientStream, null, var session = new SessionEventArgs(this, endPoint, clientStream, null, cancellationTokenSource);
cancellationTokenSource);
throw new ProxyConnectException( throw new ProxyConnectException(
$"Couldn't authenticate host '{httpsHostName}' with certificate '{certName}'.", e, session); $"Couldn't authenticate host '{httpsHostName}' with certificate '{certName}'.", e, session);
} }
...@@ -89,9 +83,10 @@ namespace Titanium.Web.Proxy ...@@ -89,9 +83,10 @@ namespace Titanium.Web.Proxy
} }
else 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, HttpHeader.VersionUnknown, false, null,
true, this, null, UpStreamEndPoint, true, sessionArgs, UpStreamEndPoint,
UpStreamHttpsProxy, true, cancellationToken); UpStreamHttpsProxy, true, cancellationToken);
try try
...@@ -131,7 +126,7 @@ namespace Titanium.Web.Proxy ...@@ -131,7 +126,7 @@ namespace Titanium.Web.Proxy
// HTTPS server created - we can now decrypt the client's traffic // HTTPS server created - we can now decrypt the client's traffic
// Now create the request // Now create the request
await handleHttpSessionRequest(endPoint, clientConnection, clientStream, cancellationTokenSource); await handleHttpSessionRequest(endPoint, clientStream, cancellationTokenSource);
} }
catch (ProxyException e) catch (ProxyException e)
{ {
......
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Titanium.Web.Proxy.StreamExtended.BufferPool; using Titanium.Web.Proxy.StreamExtended.BufferPool;
......
...@@ -2,11 +2,9 @@ ...@@ -2,11 +2,9 @@
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Titanium.Web.Proxy.EventArguments; using Titanium.Web.Proxy.EventArguments;
using Titanium.Web.Proxy.Exceptions;
using Titanium.Web.Proxy.Helpers; using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Http; using Titanium.Web.Proxy.Http;
using Titanium.Web.Proxy.Network.Tcp; using Titanium.Web.Proxy.Network.Tcp;
using Titanium.Web.Proxy.StreamExtended.Network;
namespace Titanium.Web.Proxy namespace Titanium.Web.Proxy
{ {
......
using System; using System;
using System.Buffers;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net; using System.Net;
using System.Net.Http;
using System.Net.Sockets;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
......
using System.IO; using System.IO;
using System.Text; using System.Text;
using Titanium.Web.Proxy.Http; using Titanium.Web.Proxy.Http;
using Titanium.Web.Proxy.Shared;
namespace Titanium.Web.Proxy.IntegrationTests.Helpers namespace Titanium.Web.Proxy.IntegrationTests.Helpers
{ {
......
using System; using System;
using System.Net; using System.Net;
using System.Net.Http; using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
......
using System; using System;
using System.Collections.Generic;
using System.Net; using System.Net;
using System.Text;
using System.Threading.Tasks;
using Titanium.Web.Proxy.EventArguments;
using Titanium.Web.Proxy.Models; using Titanium.Web.Proxy.Models;
using Titanium.Web.Proxy.Network; using Titanium.Web.Proxy.Network;
......
using System; using System;
using System.Collections.Generic;
using System.Net.Http; using System.Net.Http;
using System.Text;
using Titanium.Web.Proxy.IntegrationTests.Helpers; using Titanium.Web.Proxy.IntegrationTests.Helpers;
using Titanium.Web.Proxy.IntegrationTests.Setup; using Titanium.Web.Proxy.IntegrationTests.Setup;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment