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

beta #712

Merged
merged 2 commits into from
Dec 24, 2019
Merged

beta #712

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
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,12 @@ public void StartProxy()
//};

//proxyServer.AddEndPoint(transparentEndPoint);
//proxyServer.UpStreamHttpProxy = new ExternalProxy() { HostName = "localhost", Port = 8888 };
//proxyServer.UpStreamHttpsProxy = new ExternalProxy() { HostName = "localhost", Port = 8888 };
//proxyServer.UpStreamHttpProxy = new ExternalProxy("localhost", 8888);
//proxyServer.UpStreamHttpsProxy = new ExternalProxy("localhost", 8888);

// SOCKS proxy
//proxyServer.UpStreamHttpProxy = new ExternalProxy("46.63.0.17", 4145) { ProxyType = ExternalProxyType.Socks4 };
//proxyServer.UpStreamHttpsProxy = new ExternalProxy("46.63.0.17", 4145) { ProxyType = ExternalProxyType.Socks4 };

foreach (var endPoint in proxyServer.ProxyEndPoints)
{
Expand Down
26 changes: 3 additions & 23 deletions src/Titanium.Web.Proxy/Extensions/TcpExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,18 @@ namespace Titanium.Web.Proxy.Extensions
{
internal static class TcpExtensions
{
internal static void CloseSocket(this TcpClient tcpClient)
{
if (tcpClient == null)
{
return;
}

try
{
tcpClient.Close();
}
catch
{
// ignored
}
}


/// <summary>
/// Check if a TcpClient is good to be used.
/// This only checks if send is working so local socket is still connected.
/// Receive can only be verified by doing a valid read from server without exceptions.
/// So in our case we should retry with new connection from pool if first read after getting the connection fails.
/// https://msdn.microsoft.com/en-us/library/system.net.sockets.socket.connected(v=vs.110).aspx
/// </summary>
/// <param name="client"></param>
/// <param name="socket"></param>
/// <returns></returns>
internal static bool IsGoodConnection(this TcpClient client)
internal static bool IsGoodConnection(this Socket socket)
{
var socket = client.Client;

if (!client.Connected || !socket.Connected)
if (!socket.Connected)
{
return false;
}
Expand Down
25 changes: 12 additions & 13 deletions src/Titanium.Web.Proxy/Http/HttpWebClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using Titanium.Web.Proxy.Models;
using Titanium.Web.Proxy.Network.Tcp;

namespace Titanium.Web.Proxy.Http
Expand Down Expand Up @@ -103,10 +104,14 @@ internal async Task SendRequest(bool enable100ContinueBehaviour, bool isTranspar
{
var upstreamProxy = Connection.UpStreamProxy;

bool useUpstreamProxy = upstreamProxy != null && Connection.IsHttps == false;
bool useUpstreamProxy = upstreamProxy != null && upstreamProxy.ProxyType == ExternalProxyType.Http &&
!Connection.IsHttps;

var serverStream = Connection.Stream;

string? upstreamProxyUserName = null;
string? upstreamProxyPassword = null;

string url;
if (!useUpstreamProxy || isTransparent)
{
Expand All @@ -115,19 +120,13 @@ internal async Task SendRequest(bool enable100ContinueBehaviour, bool isTranspar
else
{
url = Request.RequestUri.ToString();
}

string? upstreamProxyUserName = null;
string? upstreamProxyPassword = null;

// Send Authentication to Upstream proxy if needed
if (!isTransparent && upstreamProxy != null
&& Connection.IsHttps == false
&& !string.IsNullOrEmpty(upstreamProxy.UserName)
&& upstreamProxy.Password != null)
{
upstreamProxyUserName = upstreamProxy.UserName;
upstreamProxyPassword = upstreamProxy.Password;
// Send Authentication to Upstream proxy if needed
if (!string.IsNullOrEmpty(upstreamProxy!.UserName) && upstreamProxy.Password != null)
{
upstreamProxyUserName = upstreamProxy.UserName;
upstreamProxyPassword = upstreamProxy.Password;
}
}

// prepare the request & headers
Expand Down
14 changes: 14 additions & 0 deletions src/Titanium.Web.Proxy/Models/ExternalProxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ public class ExternalProxy : IExternalProxy
/// </summary>
public bool BypassLocalhost { get; set; }

public ExternalProxyType ProxyType { get; set; }

/// <summary>
/// Username.
/// </summary>
Expand Down Expand Up @@ -111,4 +113,16 @@ public override string ToString()
return $"{HostName}:{Port}";
}
}

public enum ExternalProxyType
{
/// <summary>A HTTP/HTTPS proxy server.</summary>
Http,

/// <summary>A SOCKS4[A] proxy server.</summary>
Socks4,

/// <summary>A SOCKS5 proxy server.</summary>
Socks5
}
}
2 changes: 2 additions & 0 deletions src/Titanium.Web.Proxy/Models/IExternalProxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ public interface IExternalProxy
/// </summary>
bool BypassLocalhost { get; set; }

ExternalProxyType ProxyType { get; set; }

/// <summary>
/// Username.
/// </summary>
Expand Down
22 changes: 15 additions & 7 deletions src/Titanium.Web.Proxy/Network/Tcp/TcpClientConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ internal class TcpClientConnection : IDisposable
{
public object ClientUserData { get; set; }

internal TcpClientConnection(ProxyServer proxyServer, TcpClient tcpClient)
internal TcpClientConnection(ProxyServer proxyServer, Socket tcpClientSocket)
{
this.tcpClient = tcpClient;
this.tcpClientSocket = tcpClientSocket;
this.proxyServer = proxyServer;
this.proxyServer.UpdateClientConnectionCount(true);
}
Expand All @@ -29,21 +29,21 @@ internal TcpClientConnection(ProxyServer proxyServer, TcpClient tcpClient)

public Guid Id { get; } = Guid.NewGuid();

public EndPoint LocalEndPoint => tcpClient.Client.LocalEndPoint;
public EndPoint LocalEndPoint => tcpClientSocket.LocalEndPoint;

public EndPoint RemoteEndPoint => tcpClient.Client.RemoteEndPoint;
public EndPoint RemoteEndPoint => tcpClientSocket.RemoteEndPoint;

internal SslProtocols SslProtocol { get; set; }

internal SslApplicationProtocol NegotiatedApplicationProtocol { get; set; }

private readonly TcpClient tcpClient;
private readonly Socket tcpClientSocket;

private int? processId;

public Stream GetStream()
{
return tcpClient.GetStream();
return new NetworkStream(tcpClientSocket, true);
}

public int GetProcessId(ProxyEndPoint endPoint)
Expand Down Expand Up @@ -86,7 +86,15 @@ public void Dispose()
// This way we can push tcp Time_Wait to client side when possible.
await Task.Delay(1000);
proxyServer.UpdateClientConnectionCount(false);
tcpClient.CloseSocket();

try
{
tcpClientSocket.Close();
}
catch
{
// ignore
}
});
}
}
Expand Down
Loading