Commit 65357243 authored by Honfika's avatar Honfika

small fixes and improvements

parent ba428196
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
<GridViewColumn Header="Process" DisplayMemberBinding="{Binding Process}" /> <GridViewColumn Header="Process" DisplayMemberBinding="{Binding Process}" />
<GridViewColumn Header="SentBytes" DisplayMemberBinding="{Binding SentDataCount}" /> <GridViewColumn Header="SentBytes" DisplayMemberBinding="{Binding SentDataCount}" />
<GridViewColumn Header="ReceivedBytes" DisplayMemberBinding="{Binding ReceivedDataCount}" /> <GridViewColumn Header="ReceivedBytes" DisplayMemberBinding="{Binding ReceivedDataCount}" />
<GridViewColumn Header="ClientEndPoint" DisplayMemberBinding="{Binding ClientEndPoint}" />
</GridView> </GridView>
</ListView.View> </ListView.View>
</ListView> </ListView>
......
...@@ -226,10 +226,11 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -226,10 +226,11 @@ namespace Titanium.Web.Proxy.Examples.Wpf
{ {
Number = lastSessionNumber, Number = lastSessionNumber,
HttpClient = e.HttpClient, HttpClient = e.HttpClient,
ClientEndPoint = e.ClientEndPoint,
IsTunnelConnect = isTunnelConnect IsTunnelConnect = isTunnelConnect
}; };
if (isTunnelConnect || e.HttpClient.Request.UpgradeToWebSocket) //if (isTunnelConnect || e.HttpClient.Request.UpgradeToWebSocket)
{ {
e.DataReceived += (sender, args) => e.DataReceived += (sender, args) =>
{ {
......
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Net;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using Titanium.Web.Proxy.Examples.Wpf.Annotations; using Titanium.Web.Proxy.Examples.Wpf.Annotations;
using Titanium.Web.Proxy.Http; using Titanium.Web.Proxy.Http;
...@@ -22,6 +23,8 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -22,6 +23,8 @@ namespace Titanium.Web.Proxy.Examples.Wpf
public HttpWebClient HttpClient { get; set; } public HttpWebClient HttpClient { get; set; }
public IPEndPoint ClientEndPoint { get; set; }
public bool IsTunnelConnect { get; set; } public bool IsTunnelConnect { get; set; }
public string StatusCode public string StatusCode
......
...@@ -132,7 +132,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -132,7 +132,7 @@ namespace Titanium.Web.Proxy.EventArguments
{ {
if (bytesRemaining != -1) if (bytesRemaining != -1)
{ {
var buffer = bufferPool.GetBuffer(baseStream.BufferSize); var buffer = bufferPool.GetBuffer();
try try
{ {
int res = await ReadAsync(buffer, 0, buffer.Length); int res = await ReadAsync(buffer, 0, buffer.Length);
......
...@@ -121,7 +121,6 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -121,7 +121,6 @@ namespace Titanium.Web.Proxy.EventArguments
// Now set the flag to true // Now set the flag to true
// So that next time we can deliver body from cache // So that next time we can deliver body from cache
request.IsBodyRead = true; request.IsBodyRead = true;
OnDataSent(body, 0, body.Length);
} }
} }
} }
...@@ -194,7 +193,6 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -194,7 +193,6 @@ namespace Titanium.Web.Proxy.EventArguments
// Now set the flag to true // Now set the flag to true
// So that next time we can deliver body from cache // So that next time we can deliver body from cache
response.IsBodyRead = true; response.IsBodyRead = true;
OnDataReceived(body, 0, body.Length);
} }
} }
} }
...@@ -203,7 +201,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -203,7 +201,7 @@ namespace Titanium.Web.Proxy.EventArguments
{ {
using (var bodyStream = new MemoryStream()) using (var bodyStream = new MemoryStream())
{ {
var writer = new HttpWriter(bodyStream, BufferPool, BufferSize); var writer = new HttpWriter(bodyStream, BufferPool);
if (isRequest) if (isRequest)
{ {
...@@ -235,7 +233,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -235,7 +233,7 @@ namespace Titanium.Web.Proxy.EventArguments
using (var bodyStream = new MemoryStream()) using (var bodyStream = new MemoryStream())
{ {
var writer = new HttpWriter(bodyStream, BufferPool, BufferSize); var writer = new HttpWriter(bodyStream, BufferPool);
await copyBodyAsync(isRequest, true, writer, TransformationMode.None, null, cancellationToken); await copyBodyAsync(isRequest, true, writer, TransformationMode.None, null, cancellationToken);
} }
} }
...@@ -256,7 +254,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -256,7 +254,7 @@ namespace Titanium.Web.Proxy.EventArguments
var reader = getStreamReader(true); var reader = getStreamReader(true);
string boundary = HttpHelper.GetBoundaryFromContentType(request.ContentType); string boundary = HttpHelper.GetBoundaryFromContentType(request.ContentType);
using (var copyStream = new CopyStream(reader, writer, BufferPool, BufferSize)) using (var copyStream = new CopyStream(reader, writer, BufferPool))
{ {
while (contentLength > copyStream.ReadBytes) while (contentLength > copyStream.ReadBytes)
{ {
...@@ -317,7 +315,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -317,7 +315,7 @@ namespace Titanium.Web.Proxy.EventArguments
try try
{ {
using (var bufStream = new CustomBufferedStream(s, BufferPool, BufferSize, true)) using (var bufStream = new CustomBufferedStream(s, BufferPool, true))
{ {
await writer.CopyBodyAsync(bufStream, false, -1, onCopy, cancellationToken); await writer.CopyBodyAsync(bufStream, false, -1, onCopy, cancellationToken);
} }
...@@ -339,7 +337,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -339,7 +337,7 @@ namespace Titanium.Web.Proxy.EventArguments
{ {
int bufferDataLength = 0; int bufferDataLength = 0;
var buffer = BufferPool.GetBuffer(BufferSize); var buffer = BufferPool.GetBuffer();
try try
{ {
int boundaryLength = boundary.Length + 4; int boundaryLength = boundary.Length + 4;
......
...@@ -21,10 +21,11 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -21,10 +21,11 @@ namespace Titanium.Web.Proxy.EventArguments
public abstract class SessionEventArgsBase : EventArgs, IDisposable public abstract class SessionEventArgsBase : EventArgs, IDisposable
{ {
internal readonly CancellationTokenSource CancellationTokenSource; internal readonly CancellationTokenSource CancellationTokenSource;
internal TcpServerConnection ServerConnection => HttpClient.Connection; internal TcpServerConnection ServerConnection => HttpClient.Connection;
internal TcpClientConnection ClientConnection => ProxyClient.Connection; internal TcpClientConnection ClientConnection => ProxyClient.Connection;
protected readonly int BufferSize;
protected readonly IBufferPool BufferPool; protected readonly IBufferPool BufferPool;
protected readonly ExceptionHandler ExceptionFunc; protected readonly ExceptionHandler ExceptionFunc;
...@@ -36,10 +37,8 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -36,10 +37,8 @@ namespace Titanium.Web.Proxy.EventArguments
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="SessionEventArgsBase" /> class. /// Initializes a new instance of the <see cref="SessionEventArgsBase" /> class.
/// </summary> /// </summary>
private SessionEventArgsBase(ProxyServer server, ProxyEndPoint endPoint, private SessionEventArgsBase(ProxyServer server)
CancellationTokenSource cancellationTokenSource)
{ {
BufferSize = server.BufferSize;
BufferPool = server.BufferPool; BufferPool = server.BufferPool;
ExceptionFunc = server.ExceptionFunc; ExceptionFunc = server.ExceptionFunc;
TimeLine["Session Created"] = DateTime.Now; TimeLine["Session Created"] = DateTime.Now;
...@@ -47,7 +46,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -47,7 +46,7 @@ namespace Titanium.Web.Proxy.EventArguments
protected SessionEventArgsBase(ProxyServer server, ProxyEndPoint endPoint, protected SessionEventArgsBase(ProxyServer server, ProxyEndPoint endPoint,
CancellationTokenSource cancellationTokenSource, CancellationTokenSource cancellationTokenSource,
Request request) : this(server, endPoint, cancellationTokenSource) Request request) : this(server)
{ {
CancellationTokenSource = cancellationTokenSource; CancellationTokenSource = cancellationTokenSource;
......
...@@ -35,8 +35,8 @@ namespace Titanium.Web.Proxy ...@@ -35,8 +35,8 @@ namespace Titanium.Web.Proxy
var cancellationTokenSource = new CancellationTokenSource(); var cancellationTokenSource = new CancellationTokenSource();
var cancellationToken = cancellationTokenSource.Token; var cancellationToken = cancellationTokenSource.Token;
var clientStream = new CustomBufferedStream(clientConnection.GetStream(), BufferPool, BufferSize); var clientStream = new CustomBufferedStream(clientConnection.GetStream(), BufferPool);
var clientStreamWriter = new HttpResponseWriter(clientStream, BufferPool, BufferSize); var clientStreamWriter = new HttpResponseWriter(clientStream, BufferPool);
Task<TcpServerConnection> prefetchConnectionTask = null; Task<TcpServerConnection> prefetchConnectionTask = null;
bool closeServerConnection = false; bool closeServerConnection = false;
...@@ -50,7 +50,7 @@ namespace Titanium.Web.Proxy ...@@ -50,7 +50,7 @@ namespace Titanium.Web.Proxy
TunnelConnectSessionEventArgs connectArgs = null; TunnelConnectSessionEventArgs connectArgs = null;
// Client wants to create a secure tcp tunnel (probably its a HTTPS or Websocket request) // Client wants to create a secure tcp tunnel (probably its a HTTPS or Websocket request)
if (await HttpHelper.IsConnectMethod(clientStream, BufferPool, BufferSize, cancellationToken) == 1) if (await HttpHelper.IsConnectMethod(clientStream, BufferPool, cancellationToken) == 1)
{ {
// read the first line HTTP command // read the first line HTTP command
string httpCmd = await clientStream.ReadLineAsync(cancellationToken); string httpCmd = await clientStream.ReadLineAsync(cancellationToken);
...@@ -75,6 +75,8 @@ namespace Titanium.Web.Proxy ...@@ -75,6 +75,8 @@ namespace Titanium.Web.Proxy
connectArgs = new TunnelConnectSessionEventArgs(this, endPoint, connectRequest, connectArgs = new TunnelConnectSessionEventArgs(this, endPoint, connectRequest,
cancellationTokenSource); cancellationTokenSource);
clientStream.DataRead += (o, args) => connectArgs.OnDataSent(args.Buffer, args.Offset, args.Count);
clientStream.DataWrite += (o, args) => connectArgs.OnDataReceived(args.Buffer, args.Offset, args.Count);
connectArgs.ProxyClient.Connection = clientConnection; connectArgs.ProxyClient.Connection = clientConnection;
connectArgs.ProxyClient.ClientStream = clientStream; connectArgs.ProxyClient.ClientStream = clientStream;
...@@ -213,8 +215,8 @@ namespace Titanium.Web.Proxy ...@@ -213,8 +215,8 @@ namespace Titanium.Web.Proxy
#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 CustomBufferedStream(sslStream, BufferPool, BufferSize); clientStream = new CustomBufferedStream(sslStream, BufferPool);
clientStreamWriter = new HttpResponseWriter(clientStream, BufferPool, BufferSize); clientStreamWriter = new HttpResponseWriter(clientStream, BufferPool);
} }
catch (Exception e) catch (Exception e)
{ {
...@@ -223,7 +225,7 @@ namespace Titanium.Web.Proxy ...@@ -223,7 +225,7 @@ namespace Titanium.Web.Proxy
$"Couldn't authenticate host '{connectHostname}' with certificate '{certName}'.", e, connectArgs); $"Couldn't authenticate host '{connectHostname}' with certificate '{certName}'.", e, connectArgs);
} }
if (await HttpHelper.IsConnectMethod(clientStream, BufferPool, BufferSize, cancellationToken) == -1) if (await HttpHelper.IsConnectMethod(clientStream, BufferPool, cancellationToken) == -1)
{ {
decryptSsl = false; decryptSsl = false;
} }
...@@ -263,7 +265,7 @@ namespace Titanium.Web.Proxy ...@@ -263,7 +265,7 @@ namespace Titanium.Web.Proxy
if (available > 0) if (available > 0)
{ {
// send the buffered data // send the buffered data
var data = BufferPool.GetBuffer(BufferSize); var data = BufferPool.GetBuffer();
try try
{ {
...@@ -283,10 +285,8 @@ namespace Titanium.Web.Proxy ...@@ -283,10 +285,8 @@ namespace Titanium.Web.Proxy
if (!clientStream.IsClosed && !connection.Stream.IsClosed) if (!clientStream.IsClosed && !connection.Stream.IsClosed)
{ {
await TcpHelper.SendRaw(clientStream, connection.Stream, BufferPool, BufferSize, await TcpHelper.SendRaw(clientStream, connection.Stream, BufferPool,
(buffer, offset, count) => { connectArgs.OnDataSent(buffer, offset, count); }, null, null, connectArgs.CancellationTokenSource, ExceptionFunc);
(buffer, offset, count) => { connectArgs.OnDataReceived(buffer, offset, count); },
connectArgs.CancellationTokenSource, ExceptionFunc);
} }
} }
finally finally
...@@ -298,7 +298,7 @@ namespace Titanium.Web.Proxy ...@@ -298,7 +298,7 @@ namespace Titanium.Web.Proxy
} }
} }
if (connectArgs != null && await HttpHelper.IsPriMethod(clientStream, BufferPool, BufferSize, cancellationToken) == 1) if (connectArgs != null && await HttpHelper.IsPriMethod(clientStream, BufferPool, cancellationToken) == 1)
{ {
// todo // todo
string httpCmd = await clientStream.ReadLineAsync(cancellationToken); string httpCmd = await clientStream.ReadLineAsync(cancellationToken);
...@@ -335,7 +335,7 @@ namespace Titanium.Web.Proxy ...@@ -335,7 +335,7 @@ namespace Titanium.Web.Proxy
await connection.StreamWriter.WriteLineAsync("SM", cancellationToken); await connection.StreamWriter.WriteLineAsync("SM", cancellationToken);
await connection.StreamWriter.WriteLineAsync(cancellationToken); await connection.StreamWriter.WriteLineAsync(cancellationToken);
#if NETCOREAPP2_1 #if NETCOREAPP2_1
await Http2Helper.SendHttp2(clientStream, connection.Stream, BufferSize, await Http2Helper.SendHttp2(clientStream, connection.Stream, BufferPool.BufferSize,
(buffer, offset, count) => { connectArgs.OnDataSent(buffer, offset, count); }, (buffer, offset, count) => { connectArgs.OnDataSent(buffer, offset, count); },
(buffer, offset, count) => { connectArgs.OnDataReceived(buffer, offset, count); }, (buffer, offset, count) => { connectArgs.OnDataReceived(buffer, offset, count); },
() => new SessionEventArgs(this, endPoint, cancellationTokenSource) () => new SessionEventArgs(this, endPoint, cancellationTokenSource)
...@@ -357,6 +357,7 @@ namespace Titanium.Web.Proxy ...@@ -357,6 +357,7 @@ namespace Titanium.Web.Proxy
} }
calledRequestHandler = true; calledRequestHandler = true;
// Now create the request // Now create the request
await handleHttpSessionRequest(endPoint, clientConnection, clientStream, clientStreamWriter, await handleHttpSessionRequest(endPoint, clientConnection, clientStream, clientStreamWriter,
cancellationTokenSource, connectHostname, connectArgs, prefetchConnectionTask); cancellationTokenSource, connectHostname, connectArgs, prefetchConnectionTask);
......
...@@ -18,11 +18,10 @@ namespace Titanium.Web.Proxy.Extensions ...@@ -18,11 +18,10 @@ namespace Titanium.Web.Proxy.Extensions
/// <param name="output"></param> /// <param name="output"></param>
/// <param name="onCopy"></param> /// <param name="onCopy"></param>
/// <param name="bufferPool"></param> /// <param name="bufferPool"></param>
/// <param name="bufferSize"></param>
internal static Task CopyToAsync(this Stream input, Stream output, Action<byte[], int, int> onCopy, internal static Task CopyToAsync(this Stream input, Stream output, Action<byte[], int, int> onCopy,
IBufferPool bufferPool, int bufferSize) IBufferPool bufferPool)
{ {
return CopyToAsync(input, output, onCopy, bufferPool, bufferSize, CancellationToken.None); return CopyToAsync(input, output, onCopy, bufferPool, CancellationToken.None);
} }
/// <summary> /// <summary>
...@@ -32,12 +31,11 @@ namespace Titanium.Web.Proxy.Extensions ...@@ -32,12 +31,11 @@ namespace Titanium.Web.Proxy.Extensions
/// <param name="output"></param> /// <param name="output"></param>
/// <param name="onCopy"></param> /// <param name="onCopy"></param>
/// <param name="bufferPool"></param> /// <param name="bufferPool"></param>
/// <param name="bufferSize"></param>
/// <param name="cancellationToken"></param> /// <param name="cancellationToken"></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,
IBufferPool bufferPool, int bufferSize, CancellationToken cancellationToken) IBufferPool bufferPool, CancellationToken cancellationToken)
{ {
var buffer = bufferPool.GetBuffer(bufferSize); var buffer = bufferPool.GetBuffer();
try try
{ {
while (!cancellationToken.IsCancellationRequested) while (!cancellationToken.IsCancellationRequested)
......
...@@ -12,5 +12,5 @@ namespace Titanium.Web.Proxy.Extensions ...@@ -12,5 +12,5 @@ namespace Titanium.Web.Proxy.Extensions
return uri.IsWellFormedOriginalString() ? uri.PathAndQuery : uri.GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped); return uri.IsWellFormedOriginalString() ? uri.PathAndQuery : uri.GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
} }
} }
} }
...@@ -128,39 +128,35 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -128,39 +128,35 @@ namespace Titanium.Web.Proxy.Helpers
/// <summary> /// <summary>
/// Determines whether is connect method. /// Determines whether is connect method.
/// </summary> /// </summary>
/// <param name="clientStreamReader">The client stream reader.</param>
/// <returns>1: when CONNECT, 0: when valid HTTP method, -1: otherwise</returns> /// <returns>1: when CONNECT, 0: when valid HTTP method, -1: otherwise</returns>
internal static Task<int> IsConnectMethod(ICustomStreamReader clientStreamReader, IBufferPool bufferPool, int bufferSize, CancellationToken cancellationToken = default) internal static Task<int> IsConnectMethod(ICustomStreamReader clientStreamReader, IBufferPool bufferPool, CancellationToken cancellationToken = default)
{ {
return startsWith(clientStreamReader, bufferPool, bufferSize, "CONNECT", cancellationToken); return startsWith(clientStreamReader, bufferPool, "CONNECT", cancellationToken);
} }
/// <summary> /// <summary>
/// Determines whether is pri method (HTTP/2). /// Determines whether is pri method (HTTP/2).
/// </summary> /// </summary>
/// <param name="clientStreamReader">The client stream reader.</param>
/// <returns>1: when PRI, 0: when valid HTTP method, -1: otherwise</returns> /// <returns>1: when PRI, 0: when valid HTTP method, -1: otherwise</returns>
internal static Task<int> IsPriMethod(ICustomStreamReader clientStreamReader, IBufferPool bufferPool, int bufferSize, CancellationToken cancellationToken = default) internal static Task<int> IsPriMethod(ICustomStreamReader clientStreamReader, IBufferPool bufferPool, CancellationToken cancellationToken = default)
{ {
return startsWith(clientStreamReader, bufferPool, bufferSize, "PRI", cancellationToken); return startsWith(clientStreamReader, bufferPool, "PRI", cancellationToken);
} }
/// <summary> /// <summary>
/// Determines whether the stream starts with the given string. /// Determines whether the stream starts with the given string.
/// </summary> /// </summary>
/// <param name="clientStreamReader">The client stream reader.</param>
/// <param name="expectedStart">The expected start.</param>
/// <returns> /// <returns>
/// 1: when starts with the given string, 0: when valid HTTP method, -1: otherwise /// 1: when starts with the given string, 0: when valid HTTP method, -1: otherwise
/// </returns> /// </returns>
private static async Task<int> startsWith(ICustomStreamReader clientStreamReader, IBufferPool bufferPool, int bufferSize, string expectedStart, CancellationToken cancellationToken = default) private static async Task<int> startsWith(ICustomStreamReader clientStreamReader, IBufferPool bufferPool, string expectedStart, CancellationToken cancellationToken = default)
{ {
int iRet = -1; int iRet = -1;
const int lengthToCheck = 10; const int lengthToCheck = 10;
byte[] buffer = null; byte[] buffer = null;
try try
{ {
buffer = bufferPool.GetBuffer(Math.Max(bufferSize, lengthToCheck)); buffer = bufferPool.GetBuffer(Math.Max(bufferPool.BufferSize, lengthToCheck));
int peeked = await clientStreamReader.PeekBytesAsync(buffer, 0, 0, lengthToCheck, cancellationToken); int peeked = await clientStreamReader.PeekBytesAsync(buffer, 0, 0, lengthToCheck, cancellationToken);
......
...@@ -8,8 +8,8 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -8,8 +8,8 @@ namespace Titanium.Web.Proxy.Helpers
{ {
internal sealed class HttpRequestWriter : HttpWriter internal sealed class HttpRequestWriter : HttpWriter
{ {
internal HttpRequestWriter(Stream stream, IBufferPool bufferPool, int bufferSize) internal HttpRequestWriter(Stream stream, IBufferPool bufferPool)
: base(stream, bufferPool, bufferSize) : base(stream, bufferPool)
{ {
} }
......
...@@ -9,8 +9,8 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -9,8 +9,8 @@ namespace Titanium.Web.Proxy.Helpers
{ {
internal sealed class HttpResponseWriter : HttpWriter internal sealed class HttpResponseWriter : HttpWriter
{ {
internal HttpResponseWriter(Stream stream, IBufferPool bufferPool, int bufferSize) internal HttpResponseWriter(Stream stream, IBufferPool bufferPool)
: base(stream, bufferPool, bufferSize) : base(stream, bufferPool)
{ {
} }
......
...@@ -20,15 +20,12 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -20,15 +20,12 @@ namespace Titanium.Web.Proxy.Helpers
private static readonly Encoding encoder = Encoding.ASCII; private static readonly Encoding encoder = Encoding.ASCII;
internal HttpWriter(Stream stream, IBufferPool bufferPool, int bufferSize) internal HttpWriter(Stream stream, IBufferPool bufferPool)
{ {
BufferSize = bufferSize;
this.stream = stream; this.stream = stream;
this.bufferPool = bufferPool; this.bufferPool = bufferPool;
} }
internal int BufferSize { get; }
/// <summary> /// <summary>
/// Writes a line async /// Writes a line async
/// </summary> /// </summary>
...@@ -48,9 +45,9 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -48,9 +45,9 @@ namespace Titanium.Web.Proxy.Helpers
{ {
int newLineChars = addNewLine ? newLine.Length : 0; int newLineChars = addNewLine ? newLine.Length : 0;
int charCount = value.Length; int charCount = value.Length;
if (charCount < BufferSize - newLineChars) if (charCount < bufferPool.BufferSize - newLineChars)
{ {
var buffer = bufferPool.GetBuffer(BufferSize); var buffer = bufferPool.GetBuffer();
try try
{ {
int idx = encoder.GetBytes(value, 0, charCount, buffer, 0); int idx = encoder.GetBytes(value, 0, charCount, buffer, 0);
...@@ -246,7 +243,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -246,7 +243,7 @@ namespace Titanium.Web.Proxy.Helpers
private async Task copyBytesFromStream(ICustomStreamReader reader, long count, Action<byte[], int, int> onCopy, private async Task copyBytesFromStream(ICustomStreamReader reader, long count, Action<byte[], int, int> onCopy,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
var buffer = bufferPool.GetBuffer(BufferSize); var buffer = bufferPool.GetBuffer();
try try
{ {
......
using System; using System;
using System.IO; using System.IO;
using System.Net.Sockets;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
...@@ -8,38 +9,32 @@ using Titanium.Web.Proxy.StreamExtended.BufferPool; ...@@ -8,38 +9,32 @@ using Titanium.Web.Proxy.StreamExtended.BufferPool;
namespace Titanium.Web.Proxy.Helpers namespace Titanium.Web.Proxy.Helpers
{ {
internal enum IpVersion
{
Ipv4 = 1,
Ipv6 = 2
}
internal class TcpHelper internal class TcpHelper
{ {
/// <summary> /// <summary>
/// Gets the process id by local port number. /// Gets the process id by local port number.
/// </summary> /// </summary>
/// <returns>Process id.</returns> /// <returns>Process id.</returns>
internal static unsafe int GetProcessIdByLocalPort(IpVersion ipVersion, int localPort) internal static unsafe int GetProcessIdByLocalPort(AddressFamily addressFamily, int localPort)
{ {
var tcpTable = IntPtr.Zero; var tcpTable = IntPtr.Zero;
int tcpTableLength = 0; int tcpTableLength = 0;
int ipVersionValue = ipVersion == IpVersion.Ipv4 ? NativeMethods.AfInet : NativeMethods.AfInet6; int addressFamilyValue = addressFamily == AddressFamily.InterNetwork ? NativeMethods.AfInet : NativeMethods.AfInet6;
const int allPid = (int)NativeMethods.TcpTableType.OwnerPidAll; const int allPid = (int)NativeMethods.TcpTableType.OwnerPidAll;
if (NativeMethods.GetExtendedTcpTable(tcpTable, ref tcpTableLength, false, ipVersionValue, allPid, 0) != 0) if (NativeMethods.GetExtendedTcpTable(tcpTable, ref tcpTableLength, false, addressFamilyValue, allPid, 0) != 0)
{ {
try try
{ {
tcpTable = Marshal.AllocHGlobal(tcpTableLength); tcpTable = Marshal.AllocHGlobal(tcpTableLength);
if (NativeMethods.GetExtendedTcpTable(tcpTable, ref tcpTableLength, true, ipVersionValue, allPid, if (NativeMethods.GetExtendedTcpTable(tcpTable, ref tcpTableLength, true, addressFamilyValue, allPid,
0) == 0) 0) == 0)
{ {
int rowCount = *(int*)tcpTable; int rowCount = *(int*)tcpTable;
uint portInNetworkByteOrder = toNetworkByteOrder((uint)localPort); uint portInNetworkByteOrder = toNetworkByteOrder((uint)localPort);
if (ipVersion == IpVersion.Ipv4) if (addressFamily == AddressFamily.InterNetwork)
{ {
var rowPtr = (NativeMethods.TcpRow*)(tcpTable + 4); var rowPtr = (NativeMethods.TcpRow*)(tcpTable + 4);
...@@ -102,23 +97,21 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -102,23 +97,21 @@ namespace Titanium.Web.Proxy.Helpers
/// <param name="clientStream"></param> /// <param name="clientStream"></param>
/// <param name="serverStream"></param> /// <param name="serverStream"></param>
/// <param name="bufferPool"></param> /// <param name="bufferPool"></param>
/// <param name="bufferSize"></param>
/// <param name="onDataSend"></param> /// <param name="onDataSend"></param>
/// <param name="onDataReceive"></param> /// <param name="onDataReceive"></param>
/// <param name="cancellationTokenSource"></param> /// <param name="cancellationTokenSource"></param>
/// <param name="exceptionFunc"></param> /// <param name="exceptionFunc"></param>
/// <returns></returns> /// <returns></returns>
private static async Task sendRawTap(Stream clientStream, Stream serverStream, private static async Task sendRawTap(Stream clientStream, Stream serverStream, IBufferPool bufferPool,
IBufferPool bufferPool, int bufferSize,
Action<byte[], int, int> onDataSend, Action<byte[], int, int> onDataReceive, Action<byte[], int, int> onDataSend, Action<byte[], int, int> onDataReceive,
CancellationTokenSource cancellationTokenSource, CancellationTokenSource cancellationTokenSource,
ExceptionHandler exceptionFunc) ExceptionHandler exceptionFunc)
{ {
// Now async relay all server=>client & client=>server data // Now async relay all server=>client & client=>server data
var sendRelay = var sendRelay =
clientStream.CopyToAsync(serverStream, onDataSend, bufferPool, bufferSize, cancellationTokenSource.Token); clientStream.CopyToAsync(serverStream, onDataSend, bufferPool, cancellationTokenSource.Token);
var receiveRelay = var receiveRelay =
serverStream.CopyToAsync(clientStream, onDataReceive, bufferPool, bufferSize, cancellationTokenSource.Token); serverStream.CopyToAsync(clientStream, onDataReceive, bufferPool, cancellationTokenSource.Token);
await Task.WhenAny(sendRelay, receiveRelay); await Task.WhenAny(sendRelay, receiveRelay);
cancellationTokenSource.Cancel(); cancellationTokenSource.Cancel();
...@@ -134,20 +127,18 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -134,20 +127,18 @@ namespace Titanium.Web.Proxy.Helpers
/// <param name="clientStream"></param> /// <param name="clientStream"></param>
/// <param name="serverStream"></param> /// <param name="serverStream"></param>
/// <param name="bufferPool"></param> /// <param name="bufferPool"></param>
/// <param name="bufferSize"></param>
/// <param name="onDataSend"></param> /// <param name="onDataSend"></param>
/// <param name="onDataReceive"></param> /// <param name="onDataReceive"></param>
/// <param name="cancellationTokenSource"></param> /// <param name="cancellationTokenSource"></param>
/// <param name="exceptionFunc"></param> /// <param name="exceptionFunc"></param>
/// <returns></returns> /// <returns></returns>
internal static Task SendRaw(Stream clientStream, Stream serverStream, internal static Task SendRaw(Stream clientStream, Stream serverStream, IBufferPool bufferPool,
IBufferPool bufferPool, int bufferSize,
Action<byte[], int, int> onDataSend, Action<byte[], int, int> onDataReceive, Action<byte[], int, int> onDataSend, Action<byte[], int, int> onDataReceive,
CancellationTokenSource cancellationTokenSource, CancellationTokenSource cancellationTokenSource,
ExceptionHandler exceptionFunc) ExceptionHandler exceptionFunc)
{ {
// todo: fix APM mode // todo: fix APM mode
return sendRawTap(clientStream, serverStream, bufferPool, bufferSize, onDataSend, onDataReceive, return sendRawTap(clientStream, serverStream, bufferPool, onDataSend, onDataReceive,
cancellationTokenSource, cancellationTokenSource,
exceptionFunc); exceptionFunc);
} }
......
...@@ -42,14 +42,6 @@ namespace Titanium.Web.Proxy.Models ...@@ -42,14 +42,6 @@ namespace Titanium.Web.Proxy.Models
/// </summary> /// </summary>
public bool DecryptSsl { get; } public bool DecryptSsl { get; }
/// <summary>
/// Is IPv6 enabled?
/// </summary>
public bool IpV6Enabled => Equals(IpAddress, IPAddress.IPv6Any)
|| Equals(IpAddress, IPAddress.IPv6Loopback)
|| Equals(IpAddress, IPAddress.IPv6None);
/// <summary> /// <summary>
/// Generic certificate to use for SSL decryption. /// Generic certificate to use for SSL decryption.
/// </summary> /// </summary>
......
...@@ -19,8 +19,8 @@ namespace Titanium.Web.Proxy.Network ...@@ -19,8 +19,8 @@ namespace Titanium.Web.Proxy.Network
private readonly FileStream fileStreamSent; private readonly FileStream fileStreamSent;
public DebugCustomBufferedStream(Guid connectionId, string type, Stream baseStream, IBufferPool bufferPool, int bufferSize, bool leaveOpen = false) public DebugCustomBufferedStream(Guid connectionId, string type, Stream baseStream, IBufferPool bufferPool, bool leaveOpen = false)
: base(baseStream, bufferPool, bufferSize, leaveOpen) : base(baseStream, bufferPool, leaveOpen)
{ {
Counter = Interlocked.Increment(ref counter); Counter = Interlocked.Increment(ref counter);
fileStreamSent = new FileStream(Path.Combine(basePath, $"{connectionId}_{type}_{Counter}_sent.dat"), FileMode.Create); fileStreamSent = new FileStream(Path.Combine(basePath, $"{connectionId}_{type}_{Counter}_sent.dat"), FileMode.Create);
......
...@@ -60,8 +60,7 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -60,8 +60,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
// If client is localhost get the process id // If client is localhost get the process id
if (NetworkHelper.IsLocalIpAddress(remoteEndPoint.Address)) if (NetworkHelper.IsLocalIpAddress(remoteEndPoint.Address))
{ {
var ipVersion = endPoint.IpV6Enabled ? IpVersion.Ipv6 : IpVersion.Ipv4; processId = TcpHelper.GetProcessIdByLocalPort(endPoint.IpAddress.AddressFamily, remoteEndPoint.Port);
processId = TcpHelper.GetProcessIdByLocalPort(ipVersion, remoteEndPoint.Port);
} }
else else
{ {
......
...@@ -76,8 +76,9 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -76,8 +76,9 @@ namespace Titanium.Web.Proxy.Network.Tcp
/// <summary> /// <summary>
/// Gets the connection cache key. /// Gets the connection cache key.
/// </summary> /// </summary>
/// <param name="server">The server.</param>
/// <param name="session">The session event arguments.</param> /// <param name="session">The session event arguments.</param>
/// <param name="applicationProtocol"></param> /// <param name="applicationProtocol">The application protocol.</param>
/// <returns></returns> /// <returns></returns>
internal async Task<string> GetConnectionCacheKey(ProxyServer server, SessionEventArgsBase session, internal async Task<string> GetConnectionCacheKey(ProxyServer server, SessionEventArgsBase session,
SslApplicationProtocol applicationProtocol) SslApplicationProtocol applicationProtocol)
...@@ -340,11 +341,11 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -340,11 +341,11 @@ namespace Titanium.Web.Proxy.Network.Tcp
await proxyServer.InvokeConnectionCreateEvent(tcpClient, false); await proxyServer.InvokeConnectionCreateEvent(tcpClient, false);
stream = new CustomBufferedStream(tcpClient.GetStream(), proxyServer.BufferPool, proxyServer.BufferSize); stream = new CustomBufferedStream(tcpClient.GetStream(), proxyServer.BufferPool);
if (useUpstreamProxy && (isConnect || isHttps)) if (useUpstreamProxy && (isConnect || isHttps))
{ {
var writer = new HttpRequestWriter(stream, proxyServer.BufferPool, proxyServer.BufferSize); var writer = new HttpRequestWriter(stream, proxyServer.BufferPool);
var connectRequest = new ConnectRequest var connectRequest = new ConnectRequest
{ {
OriginalUrl = $"{remoteHostName}:{remotePort}", OriginalUrl = $"{remoteHostName}:{remotePort}",
...@@ -379,7 +380,7 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -379,7 +380,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
{ {
var sslStream = new SslStream(stream, false, proxyServer.ValidateServerCertificate, var sslStream = new SslStream(stream, false, proxyServer.ValidateServerCertificate,
proxyServer.SelectClientCertificate); proxyServer.SelectClientCertificate);
stream = new CustomBufferedStream(sslStream, proxyServer.BufferPool, proxyServer.BufferSize); stream = new CustomBufferedStream(sslStream, proxyServer.BufferPool);
var options = new SslClientAuthenticationOptions var options = new SslClientAuthenticationOptions
{ {
...@@ -423,7 +424,7 @@ namespace Titanium.Web.Proxy.Network.Tcp ...@@ -423,7 +424,7 @@ namespace Titanium.Web.Proxy.Network.Tcp
IsHttps = isHttps, IsHttps = isHttps,
NegotiatedApplicationProtocol = negotiatedApplicationProtocol, NegotiatedApplicationProtocol = negotiatedApplicationProtocol,
UseUpstreamProxy = useUpstreamProxy, UseUpstreamProxy = useUpstreamProxy,
StreamWriter = new HttpRequestWriter(stream, proxyServer.BufferPool, proxyServer.BufferSize), StreamWriter = new HttpRequestWriter(stream, proxyServer.BufferPool),
Stream = stream, Stream = stream,
Version = httpVersion Version = httpVersion
}; };
......
...@@ -111,6 +111,7 @@ namespace Titanium.Web.Proxy ...@@ -111,6 +111,7 @@ namespace Titanium.Web.Proxy
/// Create an authentication required response. /// Create an authentication required response.
/// </summary> /// </summary>
/// <param name="description">Response description.</param> /// <param name="description">Response description.</param>
/// <param name="continuation">The continuation.</param>
/// <returns></returns> /// <returns></returns>
private Response createAuthentication407Response(string description, string continuation = null) private Response createAuthentication407Response(string description, string continuation = null)
{ {
......
...@@ -95,12 +95,7 @@ namespace Titanium.Web.Proxy ...@@ -95,12 +95,7 @@ namespace Titanium.Web.Proxy
bool userTrustRootCertificate = true, bool machineTrustRootCertificate = false, bool userTrustRootCertificate = true, bool machineTrustRootCertificate = false,
bool trustRootCertificateAsAdmin = false) bool trustRootCertificateAsAdmin = false)
{ {
BufferPool = new DefaultBufferPool();
if (BufferPool == null)
{
BufferPool = new DefaultBufferPool();
}
ProxyEndPoints = new List<ProxyEndPoint>(); ProxyEndPoints = new List<ProxyEndPoint>();
tcpConnectionFactory = new TcpConnectionFactory(this); tcpConnectionFactory = new TcpConnectionFactory(this);
if (RunTime.IsWindows && !RunTime.IsUwpOnWindows) if (RunTime.IsWindows && !RunTime.IsUwpOnWindows)
...@@ -190,12 +185,6 @@ namespace Titanium.Web.Proxy ...@@ -190,12 +185,6 @@ namespace Titanium.Web.Proxy
/// </summary> /// </summary>
public bool NoDelay { get; set; } = true; public bool NoDelay { get; set; } = true;
/// <summary>
/// Buffer size in bytes used throughout this proxy.
/// Default value is 8192 bytes.
/// </summary>
public int BufferSize { get; set; } = 8192;
/// <summary> /// <summary>
/// Seconds client/server connection are to be kept alive when waiting for read/write to complete. /// Seconds client/server connection are to be kept alive when waiting for read/write to complete.
/// This will also determine the pool eviction time when connection pool is enabled. /// This will also determine the pool eviction time when connection pool is enabled.
......
...@@ -9,8 +9,23 @@ namespace Titanium.Web.Proxy.StreamExtended.BufferPool ...@@ -9,8 +9,23 @@ namespace Titanium.Web.Proxy.StreamExtended.BufferPool
/// Works well when all consumers ask for buffers with the same size. /// Works well when all consumers ask for buffers with the same size.
/// If your application would use variable size buffers consider implementing IBufferPool using System.Buffers library from Microsoft. /// If your application would use variable size buffers consider implementing IBufferPool using System.Buffers library from Microsoft.
/// </summary> /// </summary>
public class DefaultBufferPool : IBufferPool internal class DefaultBufferPool : IBufferPool
{ {
/// <summary>
/// Buffer size in bytes used throughout this proxy.
/// Default value is 8192 bytes.
/// </summary>
public int BufferSize { get; set; } = 8192;
/// <summary>
/// Gets a buffer with a default size.
/// </summary>
/// <returns></returns>
public byte[] GetBuffer()
{
return ArrayPool<byte>.Shared.Rent(BufferSize);
}
/// <summary> /// <summary>
/// Gets a buffer. /// Gets a buffer.
/// </summary> /// </summary>
......
...@@ -8,6 +8,10 @@ namespace Titanium.Web.Proxy.StreamExtended.BufferPool ...@@ -8,6 +8,10 @@ namespace Titanium.Web.Proxy.StreamExtended.BufferPool
/// </summary> /// </summary>
public interface IBufferPool : IDisposable public interface IBufferPool : IDisposable
{ {
int BufferSize { get; }
byte[] GetBuffer();
byte[] GetBuffer(int bufferSize); byte[] GetBuffer(int bufferSize);
void ReturnBuffer(byte[] buffer); void ReturnBuffer(byte[] buffer);
......
...@@ -17,8 +17,6 @@ namespace Titanium.Web.Proxy.StreamExtended.Network ...@@ -17,8 +17,6 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
private readonly IBufferPool bufferPool; private readonly IBufferPool bufferPool;
public int BufferSize { get; }
private int bufferLength; private int bufferLength;
private byte[] buffer; private byte[] buffer;
...@@ -31,12 +29,11 @@ namespace Titanium.Web.Proxy.StreamExtended.Network ...@@ -31,12 +29,11 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
public long ReadBytes { get; private set; } public long ReadBytes { get; private set; }
public CopyStream(ICustomStreamReader reader, ICustomStreamWriter writer, IBufferPool bufferPool, int bufferSize) public CopyStream(ICustomStreamReader reader, ICustomStreamWriter writer, IBufferPool bufferPool)
{ {
this.reader = reader; this.reader = reader;
this.writer = writer; this.writer = writer;
BufferSize = bufferSize; buffer = bufferPool.GetBuffer();
buffer = bufferPool.GetBuffer(bufferSize);
this.bufferPool = bufferPool; this.bufferPool = bufferPool;
} }
...@@ -94,7 +91,7 @@ namespace Titanium.Web.Proxy.StreamExtended.Network ...@@ -94,7 +91,7 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
int result = reader.Read(buffer, offset, count); int result = reader.Read(buffer, offset, count);
if (result > 0) if (result > 0)
{ {
if (bufferLength + result > BufferSize) if (bufferLength + result > bufferPool.BufferSize)
{ {
Flush(); Flush();
} }
...@@ -113,7 +110,7 @@ namespace Titanium.Web.Proxy.StreamExtended.Network ...@@ -113,7 +110,7 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
int result = await reader.ReadAsync(buffer, offset, count, cancellationToken); int result = await reader.ReadAsync(buffer, offset, count, cancellationToken);
if (result > 0) if (result > 0)
{ {
if (bufferLength + result > BufferSize) if (bufferLength + result > bufferPool.BufferSize)
{ {
await FlushAsync(cancellationToken); await FlushAsync(cancellationToken);
} }
......
...@@ -18,8 +18,6 @@ namespace Titanium.Web.Proxy.StreamExtended.Network ...@@ -18,8 +18,6 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
Position = startPosition; Position = startPosition;
} }
int ICustomStreamReader.BufferSize => baseStream.BufferSize;
/// <summary> /// <summary>
/// Gets a value indicating whether data is available. /// Gets a value indicating whether data is available.
/// </summary> /// </summary>
...@@ -92,11 +90,12 @@ namespace Titanium.Web.Proxy.StreamExtended.Network ...@@ -92,11 +90,12 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
/// <param name="buffer">The buffer to copy.</param> /// <param name="buffer">The buffer to copy.</param>
/// <param name="offset">The offset where copying.</param> /// <param name="offset">The offset where copying.</param>
/// <param name="index">The index.</param> /// <param name="index">The index.</param>
/// <param name="count">The count.</param>
/// <param name="cancellationToken">The cancellation token.</param> /// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns> /// <returns></returns>
Task<int> ICustomStreamReader.PeekBytesAsync(byte[] buffer, int offset, int index, int size, CancellationToken cancellationToken) Task<int> ICustomStreamReader.PeekBytesAsync(byte[] buffer, int offset, int index, int count, CancellationToken cancellationToken)
{ {
return baseStream.PeekBytesAsync(buffer, offset, index, size, cancellationToken); return baseStream.PeekBytesAsync(buffer, offset, index, count, cancellationToken);
} }
/// <summary> /// <summary>
...@@ -114,7 +113,6 @@ namespace Titanium.Web.Proxy.StreamExtended.Network ...@@ -114,7 +113,6 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
/// Reads a byte from buffer. /// Reads a byte from buffer.
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
/// <exception cref="Exception">Buffer is empty</exception>
byte ICustomStreamReader.ReadByteFromBuffer() byte ICustomStreamReader.ReadByteFromBuffer()
{ {
return ReadByte(); return ReadByte();
......
...@@ -15,7 +15,7 @@ namespace Titanium.Web.Proxy.StreamExtended.Network ...@@ -15,7 +15,7 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
/// of UTF-8 encoded string or raw bytes asynchronously from last read position. /// of UTF-8 encoded string or raw bytes asynchronously from last read position.
/// </summary> /// </summary>
/// <seealso cref="System.IO.Stream" /> /// <seealso cref="System.IO.Stream" />
public class CustomBufferedStream : Stream, ICustomStreamReader internal class CustomBufferedStream : Stream, ICustomStreamReader
{ {
private readonly bool leaveOpen; private readonly bool leaveOpen;
private byte[] streamBuffer; private byte[] streamBuffer;
...@@ -35,8 +35,6 @@ namespace Titanium.Web.Proxy.StreamExtended.Network ...@@ -35,8 +35,6 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
private readonly IBufferPool bufferPool; private readonly IBufferPool bufferPool;
public int BufferSize { get; }
public event EventHandler<DataEventArgs> DataRead; public event EventHandler<DataEventArgs> DataRead;
public event EventHandler<DataEventArgs> DataWrite; public event EventHandler<DataEventArgs> DataWrite;
...@@ -68,14 +66,12 @@ namespace Titanium.Web.Proxy.StreamExtended.Network ...@@ -68,14 +66,12 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
/// </summary> /// </summary>
/// <param name="baseStream">The base stream.</param> /// <param name="baseStream">The base stream.</param>
/// <param name="bufferPool">Bufferpool.</param> /// <param name="bufferPool">Bufferpool.</param>
/// <param name="bufferSize">Size of the buffer.</param>
/// <param name="leaveOpen"><see langword="true" /> to leave the stream open after disposing the <see cref="T:CustomBufferedStream" /> object; otherwise, <see langword="false" />.</param> /// <param name="leaveOpen"><see langword="true" /> to leave the stream open after disposing the <see cref="T:CustomBufferedStream" /> object; otherwise, <see langword="false" />.</param>
public CustomBufferedStream(Stream baseStream, IBufferPool bufferPool, int bufferSize, bool leaveOpen = false) public CustomBufferedStream(Stream baseStream, IBufferPool bufferPool, bool leaveOpen = false)
{ {
BaseStream = baseStream; BaseStream = baseStream;
BufferSize = bufferSize;
this.leaveOpen = leaveOpen; this.leaveOpen = leaveOpen;
streamBuffer = bufferPool.GetBuffer(bufferSize); streamBuffer = bufferPool.GetBuffer();
this.bufferPool = bufferPool; this.bufferPool = bufferPool;
} }
...@@ -278,9 +274,10 @@ namespace Titanium.Web.Proxy.StreamExtended.Network ...@@ -278,9 +274,10 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
/// <param name="buffer">The buffer to copy.</param> /// <param name="buffer">The buffer to copy.</param>
/// <param name="offset">The offset where copying.</param> /// <param name="offset">The offset where copying.</param>
/// <param name="index">The index.</param> /// <param name="index">The index.</param>
/// <param name="count">The count.</param>
/// <param name="cancellationToken">The cancellation token.</param> /// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns> /// <returns></returns>
public async Task<int> PeekBytesAsync(byte[] buffer, int offset, int index, int size, CancellationToken cancellationToken = default) public async Task<int> PeekBytesAsync(byte[] buffer, int offset, int index, int count, CancellationToken cancellationToken = default)
{ {
if (Available <= index) if (Available <= index)
{ {
...@@ -288,19 +285,19 @@ namespace Titanium.Web.Proxy.StreamExtended.Network ...@@ -288,19 +285,19 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
} }
// When index is greater than the buffer size // When index is greater than the buffer size
if (streamBuffer.Length <= (index + size)) if (streamBuffer.Length <= (index + count))
{ {
throw new Exception("Requested Peek index and size exceeds the buffer size. Consider increasing the buffer size."); throw new Exception("Requested Peek index and size exceeds the buffer size. Consider increasing the buffer size.");
} }
if (Available <= (index + size)) if (Available <= (index + count))
{ {
return -1; return -1;
} }
Buffer.BlockCopy(streamBuffer, index, buffer, offset, size); Buffer.BlockCopy(streamBuffer, index, buffer, offset, count);
return size; return count;
} }
/// <summary> /// <summary>
...@@ -359,7 +356,7 @@ namespace Titanium.Web.Proxy.StreamExtended.Network ...@@ -359,7 +356,7 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
/// <param name="value">The byte to write to the stream.</param> /// <param name="value">The byte to write to the stream.</param>
public override void WriteByte(byte value) public override void WriteByte(byte value)
{ {
var buffer = bufferPool.GetBuffer(BufferSize); var buffer = bufferPool.GetBuffer();
try try
{ {
buffer[0] = value; buffer[0] = value;
...@@ -576,7 +573,7 @@ namespace Titanium.Web.Proxy.StreamExtended.Network ...@@ -576,7 +573,7 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
int bufferDataLength = 0; int bufferDataLength = 0;
// try to use buffer from the buffer pool, usually it is enough // try to use buffer from the buffer pool, usually it is enough
var bufferPoolBuffer = bufferPool.GetBuffer(reader.BufferSize); var bufferPoolBuffer = bufferPool.GetBuffer();
var buffer = bufferPoolBuffer; var buffer = bufferPoolBuffer;
try try
......
...@@ -9,8 +9,6 @@ namespace Titanium.Web.Proxy.StreamExtended.Network ...@@ -9,8 +9,6 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
/// </summary> /// </summary>
public interface ICustomStreamReader public interface ICustomStreamReader
{ {
int BufferSize { get; }
int Available { get; } int Available { get; }
bool DataAvailable { get; } bool DataAvailable { get; }
...@@ -43,9 +41,10 @@ namespace Titanium.Web.Proxy.StreamExtended.Network ...@@ -43,9 +41,10 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
/// <param name="buffer">The buffer to copy.</param> /// <param name="buffer">The buffer to copy.</param>
/// <param name="offset">The offset where copying.</param> /// <param name="offset">The offset where copying.</param>
/// <param name="index">The index.</param> /// <param name="index">The index.</param>
/// <param name="count">The count.</param>
/// <param name="cancellationToken">The cancellation token.</param> /// <param name="cancellationToken">The cancellation token.</param>
/// <returns></returns> /// <returns></returns>
Task<int> PeekBytesAsync(byte[] buffer, int offset, int index, int size, CancellationToken cancellationToken = default); Task<int> PeekBytesAsync(byte[] buffer, int offset, int index, int count, CancellationToken cancellationToken = default);
byte ReadByteFromBuffer(); byte ReadByteFromBuffer();
......
...@@ -7,7 +7,6 @@ namespace Titanium.Web.Proxy.StreamExtended.Network ...@@ -7,7 +7,6 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
/// <summary> /// <summary>
/// Mimic a Task but you can set AsyncState /// Mimic a Task but you can set AsyncState
/// </summary> /// </summary>
/// <typeparam name="T"></typeparam>
public class TaskResult : IAsyncResult public class TaskResult : IAsyncResult
{ {
Task Task; Task Task;
...@@ -31,7 +30,7 @@ namespace Titanium.Web.Proxy.StreamExtended.Network ...@@ -31,7 +30,7 @@ namespace Titanium.Web.Proxy.StreamExtended.Network
} }
/// <summary> /// <summary>
/// Mimic a Task<T> but you can set AsyncState /// Mimic a Task&lt;T&gt; but you can set AsyncState
/// </summary> /// </summary>
/// <typeparam name="T"></typeparam> /// <typeparam name="T"></typeparam>
public class TaskResult<T> : IAsyncResult public class TaskResult<T> : IAsyncResult
......
...@@ -10,7 +10,7 @@ namespace Titanium.Web.Proxy.StreamExtended ...@@ -10,7 +10,7 @@ namespace Titanium.Web.Proxy.StreamExtended
/// <summary> /// <summary>
/// Use this class to peek SSL client/server hello information. /// Use this class to peek SSL client/server hello information.
/// </summary> /// </summary>
public class SslTools internal class SslTools
{ {
/// <summary> /// <summary>
/// Is the given stream starts with an SSL client hello? /// Is the given stream starts with an SSL client hello?
......
...@@ -32,8 +32,8 @@ namespace Titanium.Web.Proxy ...@@ -32,8 +32,8 @@ namespace Titanium.Web.Proxy
var cancellationTokenSource = new CancellationTokenSource(); var cancellationTokenSource = new CancellationTokenSource();
var cancellationToken = cancellationTokenSource.Token; var cancellationToken = cancellationTokenSource.Token;
var clientStream = new CustomBufferedStream(clientConnection.GetStream(), BufferPool, BufferSize); var clientStream = new CustomBufferedStream(clientConnection.GetStream(), BufferPool);
var clientStreamWriter = new HttpResponseWriter(clientStream, BufferPool, BufferSize); var clientStreamWriter = new HttpResponseWriter(clientStream, BufferPool);
SslStream sslStream = null; SslStream sslStream = null;
...@@ -78,9 +78,9 @@ namespace Titanium.Web.Proxy ...@@ -78,9 +78,9 @@ 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 CustomBufferedStream(sslStream, BufferPool, BufferSize); clientStream = new CustomBufferedStream(sslStream, BufferPool);
clientStreamWriter = new HttpResponseWriter(clientStream, BufferPool, BufferSize); clientStreamWriter = new HttpResponseWriter(clientStream, BufferPool);
} }
catch (Exception e) catch (Exception e)
{ {
...@@ -109,7 +109,7 @@ namespace Titanium.Web.Proxy ...@@ -109,7 +109,7 @@ namespace Titanium.Web.Proxy
if (available > 0) if (available > 0)
{ {
// send the buffered data // send the buffered data
var data = BufferPool.GetBuffer(BufferSize); var data = BufferPool.GetBuffer();
try try
{ {
// clientStream.Available should be at most BufferSize because it is using the same buffer size // clientStream.Available should be at most BufferSize because it is using the same buffer size
...@@ -124,7 +124,7 @@ namespace Titanium.Web.Proxy ...@@ -124,7 +124,7 @@ namespace Titanium.Web.Proxy
if (!clientStream.IsClosed && !connection.Stream.IsClosed) if (!clientStream.IsClosed && !connection.Stream.IsClosed)
{ {
await TcpHelper.SendRaw(clientStream, connection.Stream, BufferPool, BufferSize, await TcpHelper.SendRaw(clientStream, connection.Stream, BufferPool,
null, null, cancellationTokenSource, ExceptionFunc); null, null, cancellationTokenSource, ExceptionFunc);
} }
} }
......
...@@ -63,10 +63,8 @@ namespace Titanium.Web.Proxy ...@@ -63,10 +63,8 @@ namespace Titanium.Web.Proxy
await invokeBeforeResponse(args); await invokeBeforeResponse(args);
} }
await TcpHelper.SendRaw(clientStream, serverConnection.Stream, BufferPool, BufferSize, await TcpHelper.SendRaw(clientStream, serverConnection.Stream, BufferPool,
(buffer, offset, count) => { args.OnDataSent(buffer, offset, count); }, args.OnDataSent, args.OnDataReceived, cancellationTokenSource, ExceptionFunc);
(buffer, offset, count) => { args.OnDataReceived(buffer, offset, count); },
cancellationTokenSource, ExceptionFunc);
} }
} }
} }
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