Skip to content
This repository has been archived by the owner on Jul 9, 2023. It is now read-only.

Commit

Permalink
Merge pull request #711 from justcoding121/master
Browse files Browse the repository at this point in the history
stable
  • Loading branch information
honfika authored Dec 24, 2019
2 parents 30b1823 + d21ea35 commit 17abd9b
Show file tree
Hide file tree
Showing 33 changed files with 213 additions and 139 deletions.
4 changes: 2 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"name": "NetCore|Debug|Basic Example",
"type": "coreclr",
"request": "launch",
"program": "${workspaceRoot}/examples/Titanium.Web.Proxy.Examples.Basic/bin/Debug/netcoreapp2.0/Titanium.Web.Proxy.Examples.Basic.NetCore.dll",
"program": "${workspaceRoot}/examples/Titanium.Web.Proxy.Examples.Basic/bin/Debug/netcoreapp3.1/Titanium.Web.Proxy.Examples.Basic.NetCore.dll",
"args": [],
"cwd": "${workspaceRoot}",
"stopAtEntry": false,
Expand All @@ -16,7 +16,7 @@
"name": "NetCore|Release|Basic Example",
"type": "coreclr",
"request": "launch",
"program": "${workspaceRoot}/examples/Titanium.Web.Proxy.Examples.Basic/bin/Release/netcoreapp2.0/Titanium.Web.Proxy.Examples.Basic.NetCore.dll",
"program": "${workspaceRoot}/examples/Titanium.Web.Proxy.Examples.Basic/bin/Release/netcoreapp3.1/Titanium.Web.Proxy.Examples.Basic.NetCore.dll",
"args": [],
"cwd": "${workspaceRoot}",
"stopAtEntry": false,
Expand Down
11 changes: 11 additions & 0 deletions examples/Titanium.Web.Proxy.Examples.Basic/ProxyTestController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,17 @@ private async Task onRequest(object sender, SessionEventArgs e)
{
e.GetState().PipelineInfo.AppendLine(nameof(onRequest) + ":" + e.HttpClient.Request.RequestUri);

var clientLocalIp = e.ClientLocalEndPoint.Address;
if (!clientLocalIp.Equals(IPAddress.Loopback) && !clientLocalIp.Equals(IPAddress.IPv6Loopback))
{
e.HttpClient.UpStreamEndPoint = new IPEndPoint(clientLocalIp, 0);
}

if (e.HttpClient.Request.Url.Contains("yahoo.com"))
{
e.CustomUpStreamProxy = new ExternalProxy("localhost", 8888);
}

await writeToConsole("Active Client Connections:" + ((ProxyServer)sender).ClientConnectionCount);
await writeToConsole(e.HttpClient.Request.Url);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp2.1</TargetFrameworks>
<TargetFrameworks>netcoreapp3.1</TargetFrameworks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<LangVersion>7.1</LangVersion>
</PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net461;netcoreapp3.0</TargetFrameworks>
<TargetFrameworks>net461;netcoreapp3.1</TargetFrameworks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<LangVersion>7.1</LangVersion>
</PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,16 +103,16 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Win32.Registry">
<Version>4.6.0</Version>
<Version>4.7.0</Version>
</PackageReference>
<PackageReference Include="System.Numerics.Vectors">
<Version>4.5.0</Version>
</PackageReference>
<PackageReference Include="System.Runtime.CompilerServices.Unsafe">
<Version>4.6.0</Version>
<Version>4.7.0</Version>
</PackageReference>
<PackageReference Include="System.ServiceProcess.ServiceController">
<Version>4.6.0</Version>
<Version>4.7.0</Version>
</PackageReference>
<PackageReference Include="System.Threading.Tasks.Extensions">
<Version>4.5.3</Version>
Expand Down
2 changes: 1 addition & 1 deletion examples/Titanium.Web.Proxy.Examples.Wpf/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
<GridViewColumn Header="Process" DisplayMemberBinding="{Binding Process}" />
<GridViewColumn Header="SentBytes" DisplayMemberBinding="{Binding SentDataCount}" />
<GridViewColumn Header="ReceivedBytes" DisplayMemberBinding="{Binding ReceivedDataCount}" />
<GridViewColumn Header="ClientEndPoint" DisplayMemberBinding="{Binding ClientEndPoint}" />
<GridViewColumn Header="ClientRemoteEndPoint" DisplayMemberBinding="{Binding ClientRemoteEndPoint}" />
<GridViewColumn Header="ClientConnectionId" DisplayMemberBinding="{Binding ClientConnectionId}" />
<GridViewColumn Header="ServerConnectionId" DisplayMemberBinding="{Binding ServerConnectionId}" />
</GridView>
Expand Down
3 changes: 2 additions & 1 deletion examples/Titanium.Web.Proxy.Examples.Wpf/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,8 @@ private SessionListItem createSessionListItem(SessionEventArgsBase e)
ClientConnectionId = e.ClientConnectionId,
ServerConnectionId = e.ServerConnectionId,
HttpClient = e.HttpClient,
ClientEndPoint = e.ClientEndPoint,
ClientRemoteEndPoint = e.ClientRemoteEndPoint,
ClientLocalEndPoint = e.ClientLocalEndPoint,
IsTunnelConnect = isTunnelConnect
};

Expand Down
4 changes: 3 additions & 1 deletion examples/Titanium.Web.Proxy.Examples.Wpf/SessionListItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ public Guid ServerConnectionId

public HttpWebClient HttpClient { get; set; }

public IPEndPoint ClientEndPoint { get; set; }
public IPEndPoint ClientLocalEndPoint { get; set; }

public IPEndPoint ClientRemoteEndPoint { get; set; }

public bool IsTunnelConnect { get; set; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFrameworks>netcoreapp3.0</TargetFrameworks>
<TargetFrameworks>netcoreapp3.1</TargetFrameworks>
<UseWPF>true</UseWPF>
</PropertyGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFrameworks>net461;netcoreapp3.0</TargetFrameworks>
<TargetFrameworks>net461;netcoreapp3.1</TargetFrameworks>
<UseWPF>true</UseWPF>
</PropertyGroup>

Expand Down
12 changes: 12 additions & 0 deletions src/Titanium.Web.Proxy/EventArguments/EmptyProxyEventArgs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;
using Titanium.Web.Proxy.Network.Tcp;

namespace Titanium.Web.Proxy.EventArguments
{
public class EmptyProxyEventArgs : ProxyEventArgsBase
{
internal EmptyProxyEventArgs(TcpClientConnection clientConnection) : base(clientConnection)
{
}
}
}
6 changes: 3 additions & 3 deletions src/Titanium.Web.Proxy/EventArguments/SessionEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class SessionEventArgs : SessionEventArgsBase
/// </summary>
private bool reRequest;

private WebSocketDecoder webSocketDecoder;
private WebSocketDecoder? webSocketDecoder;

/// <summary>
/// Is this session a HTTP/2 promise?
Expand Down Expand Up @@ -190,7 +190,7 @@ private async Task readResponseBodyAsync(CancellationToken cancellationToken)
private async Task<byte[]> readBodyAsync(bool isRequest, CancellationToken cancellationToken)
{
using var bodyStream = new MemoryStream();
using var writer = new HttpStream(bodyStream, BufferPool);
using var writer = new HttpStream(bodyStream, BufferPool, cancellationToken);

if (isRequest)
{
Expand Down Expand Up @@ -221,7 +221,7 @@ internal async Task SyphonOutBodyAsync(bool isRequest, CancellationToken cancell

var reader = isRequest ? (HttpStream)ClientStream : HttpClient.Connection.Stream;

await reader.CopyBodyAsync(requestResponse, true, new NullWriter(), TransformationMode.None, null, cancellationToken);
await reader.CopyBodyAsync(requestResponse, true, NullWriter.Instance, TransformationMode.None, null, cancellationToken);
}

/// <summary>
Expand Down
29 changes: 24 additions & 5 deletions src/Titanium.Web.Proxy/EventArguments/SessionEventArgsBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ private protected SessionEventArgsBase(ProxyServer server, ProxyEndPoint endPoin

ClientStream = clientStream;
HttpClient = new HttpWebClient(connectRequest, request, new Lazy<int>(() => clientStream.Connection.GetProcessId(endPoint)));
LocalEndPoint = endPoint;
ProxyEndPoint = endPoint;
EnableWinAuth = server.EnableWinAuth && isWindowsAuthenticationSupported;
}

Expand Down Expand Up @@ -94,9 +94,17 @@ public bool EnableWinAuth
public bool IsHttps => HttpClient.Request.IsHttps;

/// <summary>
/// Client End Point.
/// Client Local End Point.
/// </summary>
public IPEndPoint ClientEndPoint => (IPEndPoint)ClientConnection.RemoteEndPoint;
public IPEndPoint ClientLocalEndPoint => (IPEndPoint)ClientConnection.LocalEndPoint;

/// <summary>
/// Client Remote End Point.
/// </summary>
public IPEndPoint ClientRemoteEndPoint => (IPEndPoint)ClientConnection.RemoteEndPoint;

[Obsolete("Use ClientRemoteEndPoint instead.")]
public IPEndPoint ClientEndPoint => ClientRemoteEndPoint;

/// <summary>
/// The web client used to communicate with server for this session.
Expand All @@ -106,6 +114,14 @@ public bool EnableWinAuth
[Obsolete("Use HttpClient instead.")]
public HttpWebClient WebSession => HttpClient;

/// <summary>
/// Gets or sets the custom up stream proxy.
/// </summary>
/// <value>
/// The custom up stream proxy.
/// </value>
public IExternalProxy? CustomUpStreamProxy { get; set; }

/// <summary>
/// Are we using a custom upstream HTTP(S) proxy?
/// </summary>
Expand All @@ -114,12 +130,15 @@ public bool EnableWinAuth
/// <summary>
/// Local endpoint via which we make the request.
/// </summary>
public ProxyEndPoint LocalEndPoint { get; }
public ProxyEndPoint ProxyEndPoint { get; }

[Obsolete("Use ProxyEndPoint instead.")]
public ProxyEndPoint LocalEndPoint => ProxyEndPoint;

/// <summary>
/// Is this a transparent endpoint?
/// </summary>
public bool IsTransparent => LocalEndPoint is TransparentProxyEndPoint;
public bool IsTransparent => ProxyEndPoint is TransparentProxyEndPoint;

/// <summary>
/// The last exception that happened.
Expand Down
22 changes: 12 additions & 10 deletions src/Titanium.Web.Proxy/ExplicitClientHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,10 @@ private async Task handleClient(ExplicitProxyEndPoint endPoint, TcpClientConnect
var cancellationTokenSource = new CancellationTokenSource();
var cancellationToken = cancellationTokenSource.Token;

var clientStream = new HttpClientStream(clientConnection, clientConnection.GetStream(), BufferPool);
var clientStream = new HttpClientStream(clientConnection, clientConnection.GetStream(), BufferPool, cancellationToken);

Task<TcpServerConnection>? prefetchConnectionTask = null;
bool closeServerConnection = false;
bool calledRequestHandler = false;

SslStream? sslStream = null;

try
{
Expand Down Expand Up @@ -191,6 +188,7 @@ private async Task handleClient(ExplicitProxyEndPoint endPoint, TcpClientConnect
}

X509Certificate2? certificate = null;
SslStream? sslStream = null;
try
{
sslStream = new SslStream(clientStream, false);
Expand Down Expand Up @@ -221,14 +219,16 @@ private async Task handleClient(ExplicitProxyEndPoint endPoint, TcpClientConnect
#endif

// HTTPS server created - we can now decrypt the client's traffic
clientStream = new HttpClientStream(clientStream.Connection, sslStream, BufferPool);
clientStream = new HttpClientStream(clientStream.Connection, sslStream, BufferPool, cancellationToken);
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.DataWrite += (o, args) => connectArgs.OnDecryptedDataReceived(args.Buffer, args.Offset, args.Count);
}
catch (Exception e)
{
sslStream?.Dispose();

var certName = certificate?.GetNameInfo(X509NameType.SimpleName, false);
throw new ProxyConnectException(
$"Couldn't authenticate host '{connectHostname}' with certificate '{certName}'.", e, connectArgs);
Expand Down Expand Up @@ -374,10 +374,11 @@ await Http2Helper.SendHttp2(clientStream, connection.Stream,
}
}

calledRequestHandler = true;
var prefetchTask = prefetchConnectionTask;
prefetchConnectionTask = null;

// Now create the request
await handleHttpSessionRequest(endPoint, clientStream, cancellationTokenSource, connectArgs, prefetchConnectionTask);
await handleHttpSessionRequest(endPoint, clientStream, cancellationTokenSource, connectArgs, prefetchTask);
}
catch (ProxyException e)
{
Expand All @@ -401,12 +402,13 @@ await Http2Helper.SendHttp2(clientStream, connection.Stream,
}
finally
{
if (!calledRequestHandler)
if (!cancellationTokenSource.IsCancellationRequested)
{
await tcpConnectionFactory.Release(prefetchConnectionTask, closeServerConnection);
cancellationTokenSource.Cancel();
}

sslStream?.Dispose();
await tcpConnectionFactory.Release(prefetchConnectionTask, closeServerConnection);

clientStream.Dispose();
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/Titanium.Web.Proxy/Extensions/StreamExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ internal static async Task CopyToAsync(this Stream input, Stream output, Action<
{
// cancellation is not working on Socket ReadAsync
// https://github.com/dotnet/corefx/issues/15033
int num = await input.ReadAsync(buffer, 0, buffer.Length, CancellationToken.None)
.withCancellation(cancellationToken);
int num = await input.ReadAsync(buffer, 0, buffer.Length, cancellationToken)
.WithCancellation(cancellationToken);
int bytesRead;
if ((bytesRead = num) != 0 && !cancellationToken.IsCancellationRequested)
{
Expand All @@ -62,7 +62,7 @@ internal static async Task CopyToAsync(this Stream input, Stream output, Action<
}
}

private static async Task<T> withCancellation<T>(this Task<T> task, CancellationToken cancellationToken) where T : struct
internal static async Task<T> WithCancellation<T>(this Task<T> task, CancellationToken cancellationToken) where T : struct
{
var tcs = new TaskCompletionSource<bool>();
using (cancellationToken.Register(s => ((TaskCompletionSource<bool>)s).TrySetResult(true), tcs))
Expand Down
4 changes: 2 additions & 2 deletions src/Titanium.Web.Proxy/Helpers/HttpClientStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ internal sealed class HttpClientStream : HttpStream
{
public TcpClientConnection Connection { get; }

internal HttpClientStream(TcpClientConnection connection, Stream stream, IBufferPool bufferPool)
: base(stream, bufferPool)
internal HttpClientStream(TcpClientConnection connection, Stream stream, IBufferPool bufferPool, CancellationToken cancellationToken)
: base(stream, bufferPool, cancellationToken)
{
Connection = connection;
}
Expand Down
4 changes: 2 additions & 2 deletions src/Titanium.Web.Proxy/Helpers/HttpServerStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ namespace Titanium.Web.Proxy.Helpers
{
internal sealed class HttpServerStream : HttpStream
{
internal HttpServerStream(Stream stream, IBufferPool bufferPool)
: base(stream, bufferPool)
internal HttpServerStream(Stream stream, IBufferPool bufferPool, CancellationToken cancellationToken)
: base(stream, bufferPool, cancellationToken)
{
}

Expand Down
Loading

0 comments on commit 17abd9b

Please sign in to comment.