Commit 99e3b575 authored by justcoding121's avatar justcoding121

Merge branch 'develop' into beta

parents dd688aa1 38116fb9
......@@ -98,13 +98,15 @@ namespace Titanium.Web.Proxy.EventArguments
/// <summary>
/// Constructor to initialize the proxy
/// </summary>
internal SessionEventArgs(int bufferSize, ProxyEndPoint endPoint, Func<SessionEventArgs, Task> httpResponseHandler)
internal SessionEventArgs(int bufferSize,
ProxyEndPoint endPoint,
Func<SessionEventArgs, Task> httpResponseHandler)
{
this.bufferSize = bufferSize;
this.httpResponseHandler = httpResponseHandler;
ProxyClient = new ProxyClient();
WebSession = new HttpWebClient();
WebSession = new HttpWebClient(bufferSize);
WebSession.ProcessId = new Lazy<int>(() =>
{
......
using Titanium.Web.Proxy.Models;
using System.Net;
using Titanium.Web.Proxy.Models;
namespace Titanium.Web.Proxy.EventArguments
{
......@@ -6,7 +7,8 @@ namespace Titanium.Web.Proxy.EventArguments
{
public bool IsHttpsConnect { get; set; }
public TunnelConnectSessionEventArgs(ProxyEndPoint endPoint) : base(0, endPoint, null)
public TunnelConnectSessionEventArgs(int bufferSize, ProxyEndPoint endPoint)
: base(bufferSize, endPoint, null)
{
}
......
......@@ -3,7 +3,7 @@ using System.Security.Cryptography.X509Certificates;
namespace Titanium.Web.Proxy.Extensions
{
internal static class DotNetStandardExtensions
internal static class DotNet45Extensions
{
#if NET45
/// <summary>
......
......@@ -17,9 +17,9 @@ namespace Titanium.Web.Proxy.Extensions
/// <param name="input"></param>
/// <param name="output"></param>
/// <param name="onCopy"></param>
internal static async Task CopyToAsync(this Stream input, Stream output, Action<byte[], int, int> onCopy)
internal static async Task CopyToAsync(this Stream input, Stream output, Action<byte[], int, int> onCopy, int bufferSize)
{
byte[] buffer = new byte[81920];
byte[] buffer = new byte[bufferSize];
while (true)
{
int num = await input.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false);
......
......@@ -5,34 +5,6 @@ namespace Titanium.Web.Proxy.Extensions
{
internal static class TcpExtensions
{
/// <summary>
/// verifies if the underlying socket is connected before using a TcpClient connection
/// </summary>
/// <param name="client"></param>
/// <returns></returns>
internal static bool IsConnected(this Socket client)
{
// This is how you can determine whether a socket is still connected.
bool blockingState = client.Blocking;
try
{
var tmp = new byte[1];
client.Blocking = false;
client.Send(tmp, 0, 0);
return true;
}
catch (SocketException e)
{
// 10035 == WSAEWOULDBLOCK
return e.SocketErrorCode == SocketError.WouldBlock;
}
finally
{
client.Blocking = blockingState;
}
}
#if NET45
/// <summary>
......
......@@ -4,7 +4,8 @@ namespace Titanium.Web.Proxy.Helpers
{
sealed class HttpRequestWriter : HttpWriter
{
public HttpRequestWriter(Stream stream) : base(stream, true)
public HttpRequestWriter(Stream stream, int bufferSize)
: base(stream, bufferSize, true)
{
}
}
......
......@@ -12,7 +12,8 @@ namespace Titanium.Web.Proxy.Helpers
{
sealed class HttpResponseWriter : HttpWriter
{
public HttpResponseWriter(Stream stream) : base(stream, true)
public HttpResponseWriter(Stream stream, int bufferSize)
: base(stream, bufferSize, true)
{
}
......
......@@ -8,7 +8,8 @@ namespace Titanium.Web.Proxy.Helpers
{
abstract class HttpWriter : StreamWriter
{
protected HttpWriter(Stream stream, bool leaveOpen) : base(stream, Encoding.ASCII, 1024, leaveOpen)
protected HttpWriter(Stream stream, int bufferSize, bool leaveOpen)
: base(stream, Encoding.ASCII, bufferSize, leaveOpen)
{
NewLine = ProxyConstants.NewLine;
}
......
......@@ -116,12 +116,13 @@ namespace Titanium.Web.Proxy.Helpers
/// <param name="onDataSend"></param>
/// <param name="onDataReceive"></param>
/// <returns></returns>
internal static async Task SendRaw(Stream clientStream, Stream serverStream, Action<byte[], int, int> onDataSend, Action<byte[], int, int> onDataReceive)
internal static async Task SendRaw(Stream clientStream, Stream serverStream, int bufferSize,
Action<byte[], int, int> onDataSend, Action<byte[], int, int> onDataReceive)
{
//Now async relay all server=>client & client=>server data
var sendRelay = clientStream.CopyToAsync(serverStream, onDataSend);
var sendRelay = clientStream.CopyToAsync(serverStream, onDataSend, bufferSize);
var receiveRelay = serverStream.CopyToAsync(clientStream, onDataReceive);
var receiveRelay = serverStream.CopyToAsync(clientStream, onDataReceive, bufferSize);
await Task.WhenAll(sendRelay, receiveRelay);
}
......
......@@ -13,6 +13,8 @@ namespace Titanium.Web.Proxy.Http
/// </summary>
public class HttpWebClient : IDisposable
{
private int bufferSize;
/// <summary>
/// Connection to server
/// </summary>
......@@ -23,6 +25,11 @@ namespace Titanium.Web.Proxy.Http
/// </summary>
public Guid RequestId { get; }
/// <summary>
/// Override UpStreamEndPoint for this request; Local NIC via request is made
/// </summary>
public IPEndPoint UpStreamEndPoint { get; set; }
/// <summary>
/// Headers passed with Connect.
/// </summary>
......@@ -49,8 +56,10 @@ namespace Titanium.Web.Proxy.Http
/// </summary>
public bool IsHttps => Request.IsHttps;
internal HttpWebClient()
internal HttpWebClient(int bufferSize)
{
this.bufferSize = bufferSize;
RequestId = Guid.NewGuid();
Request = new Request();
Response = new Response();
......@@ -77,7 +86,7 @@ namespace Titanium.Web.Proxy.Http
byte[] requestBytes;
using (var ms = new MemoryStream())
using (var writer = new HttpRequestWriter(ms))
using (var writer = new HttpRequestWriter(ms, bufferSize))
{
var upstreamProxy = ServerConnection.UpStreamHttpProxy;
......
using StreamExtended.Network;
using System;
using System.Net;
using System.Net.Sockets;
using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Models;
......@@ -25,6 +26,11 @@ namespace Titanium.Web.Proxy.Network.Tcp
internal bool UseUpstreamProxy { get; set; }
/// <summary>
/// Local NIC via connection is made
/// </summary>
internal IPEndPoint UpStreamEndPoint { get; set; }
/// <summary>
/// Http version
/// </summary>
......
using StreamExtended.Network;
using System;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Text;
......@@ -17,19 +18,21 @@ namespace Titanium.Web.Proxy.Network.Tcp
internal class TcpConnectionFactory
{
/// <summary>
/// Creates a TCP connection to server
/// Creates a TCP connection to server
/// </summary>
/// <param name="server"></param>
/// <param name="remoteHostName"></param>
/// <param name="remotePort"></param>
/// <param name="httpVersion"></param>
/// <param name="isConnect"></param>
/// <param name="isHttps"></param>
/// <param name="isConnect"></param>
/// <param name="upStreamEndPoint"></param>
/// <param name="externalHttpProxy"></param>
/// <param name="externalHttpsProxy"></param>
/// <returns></returns>
internal async Task<TcpConnection> CreateClient(ProxyServer server, string remoteHostName, int remotePort, Version httpVersion, bool isHttps,
bool isConnect, ExternalProxy externalHttpProxy, ExternalProxy externalHttpsProxy)
internal async Task<TcpConnection> CreateClient(ProxyServer server,
string remoteHostName, int remotePort, Version httpVersion, bool isHttps,
bool isConnect, IPEndPoint upStreamEndPoint, ExternalProxy externalHttpProxy, ExternalProxy externalHttpsProxy)
{
bool useUpstreamProxy = false;
var externalProxy = isHttps ? externalHttpsProxy : externalHttpProxy;
......@@ -52,10 +55,10 @@ namespace Titanium.Web.Proxy.Network.Tcp
try
{
#if NET45
client = new TcpClient(server.UpStreamEndPoint);
client = new TcpClient(upStreamEndPoint);
#else
client = new TcpClient();
client.Client.Bind(server.UpStreamEndPoint);
client.Client.Bind(upStreamEndPoint);
#endif
//If this proxy uses another external proxy then create a tunnel request for HTTP/HTTPS connections
......@@ -72,7 +75,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
if (useUpstreamProxy && (isConnect || isHttps))
{
using (var writer = new HttpRequestWriter(stream))
using (var writer = new HttpRequestWriter(stream, server.BufferSize))
{
await writer.WriteLineAsync($"CONNECT {remoteHostName}:{remotePort} HTTP/{httpVersion}");
await writer.WriteLineAsync($"Host: {remoteHostName}:{remotePort}");
......@@ -128,6 +131,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
{
UpStreamHttpProxy = externalHttpProxy,
UpStreamHttpsProxy = externalHttpsProxy,
UpStreamEndPoint = upStreamEndPoint,
HostName = remoteHostName,
Port = remotePort,
IsHttps = isHttps,
......
......@@ -6,11 +6,11 @@ using System.Runtime.InteropServices;
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Titanium.Web.Proxy.Properties")]
[assembly: AssemblyTitle("Titanium.Web.Proxy")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Titanium.Web.Proxy.Properties")]
[assembly: AssemblyProduct("Titanium.Web.Proxy")]
[assembly: AssemblyCopyright("Copyright © Titanium 2015-2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
......
This diff is collapsed.
......@@ -37,7 +37,7 @@ namespace Titanium.Web.Proxy
var clientStream = new CustomBufferedStream(tcpClient.GetStream(), BufferSize);
var clientStreamReader = new CustomBinaryReader(clientStream, BufferSize);
var clientStreamWriter = new HttpResponseWriter(clientStream);
var clientStreamWriter = new HttpResponseWriter(clientStream, BufferSize);
Uri httpRemoteUri;
......@@ -86,7 +86,7 @@ namespace Titanium.Web.Proxy
await HeaderParser.ReadHeaders(clientStreamReader, connectRequest.RequestHeaders);
var connectArgs = new TunnelConnectSessionEventArgs(endPoint);
var connectArgs = new TunnelConnectSessionEventArgs(BufferSize, endPoint);
connectArgs.WebSession.Request = connectRequest;
connectArgs.ProxyClient.TcpClient = tcpClient;
connectArgs.ProxyClient.ClientStream = clientStream;
......@@ -147,7 +147,7 @@ namespace Titanium.Web.Proxy
clientStreamReader.Dispose();
clientStreamReader = new CustomBinaryReader(clientStream, BufferSize);
clientStreamWriter = new HttpResponseWriter(clientStream);
clientStreamWriter = new HttpResponseWriter(clientStream, BufferSize);
}
catch
{
......@@ -164,24 +164,30 @@ namespace Titanium.Web.Proxy
//create new connection
using (var connection = await GetServerConnection(connectArgs, true))
{
if (isClientHello)
try
{
if (clientStream.Available > 0)
if (isClientHello)
{
//send the buffered data
var data = new byte[clientStream.Available];
await clientStream.ReadAsync(data, 0, data.Length);
await connection.Stream.WriteAsync(data, 0, data.Length);
await connection.Stream.FlushAsync();
if (clientStream.Available > 0)
{
//send the buffered data
var data = new byte[clientStream.Available];
await clientStream.ReadAsync(data, 0, data.Length);
await connection.Stream.WriteAsync(data, 0, data.Length);
await connection.Stream.FlushAsync();
}
var serverHelloInfo = await SslTools.PeekServerHello(connection.Stream);
((ConnectResponse)connectArgs.WebSession.Response).ServerHelloInfo = serverHelloInfo;
}
var serverHelloInfo = await SslTools.PeekServerHello(connection.Stream);
((ConnectResponse)connectArgs.WebSession.Response).ServerHelloInfo = serverHelloInfo;
await TcpHelper.SendRaw(clientStream, connection.Stream, BufferSize,
(buffer, offset, count) => { connectArgs.OnDataSent(buffer, offset, count); }, (buffer, offset, count) => { connectArgs.OnDataReceived(buffer, offset, count); });
}
finally
{
UpdateServerConnectionCount(false);
}
await TcpHelper.SendRaw(clientStream, connection.Stream,
(buffer, offset, count) => { connectArgs.OnDataSent(buffer, offset, count); }, (buffer, offset, count) => { connectArgs.OnDataReceived(buffer, offset, count); });
UpdateServerConnectionCount(false);
}
return;
......@@ -243,7 +249,7 @@ namespace Titanium.Web.Proxy
}
clientStreamReader = new CustomBinaryReader(clientStream, BufferSize);
clientStreamWriter = new HttpResponseWriter(clientStream);
clientStreamWriter = new HttpResponseWriter(clientStream, BufferSize);
//now read the request line
string httpCmd = await clientStreamReader.ReadLineAsync();
......@@ -354,12 +360,15 @@ namespace Titanium.Web.Proxy
break;
}
//create a new connection if hostname changes
if (connection != null && !connection.HostName.Equals(args.WebSession.Request.RequestUri.Host, StringComparison.OrdinalIgnoreCase))
//create a new connection if hostname/upstream end point changes
if (connection != null
&& (!connection.HostName.Equals(args.WebSession.Request.RequestUri.Host, StringComparison.OrdinalIgnoreCase)
|| (args.WebSession.UpStreamEndPoint != null
&& !args.WebSession.UpStreamEndPoint.Equals(connection.UpStreamEndPoint))))
{
connection.Dispose();
UpdateServerConnectionCount(false);
connection = null;
UpdateServerConnectionCount(false);
}
if (connection == null)
......@@ -374,7 +383,7 @@ namespace Titanium.Web.Proxy
var requestHeaders = args.WebSession.Request.RequestHeaders;
byte[] requestBytes;
using (var ms = new MemoryStream())
using (var writer = new HttpRequestWriter(ms))
using (var writer = new HttpRequestWriter(ms, BufferSize))
{
writer.WriteLine(httpCmd);
writer.WriteHeaders(requestHeaders);
......@@ -402,7 +411,7 @@ namespace Titanium.Web.Proxy
await BeforeResponse.InvokeParallelAsync(this, args, ExceptionFunc);
}
await TcpHelper.SendRaw(clientStream, connection.Stream,
await TcpHelper.SendRaw(clientStream, connection.Stream, BufferSize,
(buffer, offset, count) => { args.OnDataSent(buffer, offset, count); }, (buffer, offset, count) => { args.OnDataReceived(buffer, offset, count); });
args.Dispose();
......@@ -599,6 +608,7 @@ namespace Titanium.Web.Proxy
args.WebSession.Request.RequestUri.Port,
args.WebSession.Request.HttpVersion,
args.IsHttps, isConnect,
args.WebSession.UpStreamEndPoint ?? UpStreamEndPoint,
customUpStreamHttpProxy ?? UpStreamHttpProxy,
customUpStreamHttpsProxy ?? UpStreamHttpsProxy);
}
......
......@@ -3,6 +3,10 @@
<PropertyGroup>
<TargetFramework>netstandard1.6</TargetFramework>
<RootNamespace>Titanium.Web.Proxy</RootNamespace>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<SignAssembly>True</SignAssembly>
<AssemblyOriginatorKeyFile>StrongNameKey.snk</AssemblyOriginatorKeyFile>
<DelaySign>False</DelaySign>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
......@@ -10,7 +14,6 @@
</PropertyGroup>
<ItemGroup>
<Compile Remove="Properties\AssemblyInfo.cs" />
<Compile Remove="Helpers\WinHttp\NativeMethods.WinHttp.cs" />
<Compile Remove="Helpers\WinHttp\WinHttpHandle.cs" />
<Compile Remove="Helpers\WinHttp\WinHttpWebProxyFinder.cs" />
......
......@@ -84,7 +84,7 @@
<Compile Include="Exceptions\ProxyException.cs" />
<Compile Include="Exceptions\ProxyHttpException.cs" />
<Compile Include="Extensions\ByteArrayExtensions.cs" />
<Compile Include="Extensions\DotNetStandardExtensions.cs" />
<Compile Include="Extensions\DotNet45Extensions.cs" />
<Compile Include="Extensions\FuncExtensions.cs" />
<Compile Include="Extensions\HttpWebRequestExtensions.cs" />
<Compile Include="Extensions\HttpWebResponseExtensions.cs" />
......
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