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

stable #711

Merged
merged 8 commits into from
Dec 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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