Commit a991c2bc authored by Honfika's avatar Honfika

simplify custom stream

parent 7023f63b
......@@ -205,4 +205,4 @@ FakesAssemblies/
*.opt
# Docfx
docs/manifest.json
\ No newline at end of file
docs/manifest.json
......@@ -51,8 +51,8 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="StreamExtended, Version=1.0.147.0, Culture=neutral, PublicKeyToken=bbfa0f1d54f50043, processorArchitecture=MSIL">
<HintPath>..\..\packages\StreamExtended.1.0.147-beta\lib\net45\StreamExtended.dll</HintPath>
<Reference Include="StreamExtended, Version=1.0.160.0, Culture=neutral, PublicKeyToken=bbfa0f1d54f50043, processorArchitecture=MSIL">
<HintPath>..\..\packages\StreamExtended.1.0.160-beta\lib\net45\StreamExtended.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
......
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="StreamExtended" version="1.0.147-beta" targetFramework="net45" />
<package id="StreamExtended" version="1.0.160-beta" targetFramework="net45" />
</packages>
\ No newline at end of file
using System;
namespace Titanium.Web.Proxy.EventArguments
{
/// <summary>
/// Wraps the data sent/received by a proxy server instance.
/// </summary>
public class DataEventArgs : EventArgs
{
internal DataEventArgs(byte[] buffer, int offset, int count)
{
Buffer = buffer;
Offset = offset;
Count = count;
}
/// <summary>
/// The buffer with data.
/// </summary>
public byte[] Buffer { get; }
/// <summary>
/// Offset in buffer from which valid data begins.
/// </summary>
public int Offset { get; }
/// <summary>
/// Length from offset in buffer with valid data.
/// </summary>
public int Count { get; }
}
}
......@@ -9,18 +9,16 @@ namespace Titanium.Web.Proxy.EventArguments
{
internal class LimitedStream : Stream
{
private readonly CustomBinaryReader baseReader;
private readonly CustomBufferedStream baseStream;
private readonly ICustomStreamReader baseStream;
private readonly bool isChunked;
private long bytesRemaining;
private bool readChunkTrail;
internal LimitedStream(CustomBufferedStream baseStream, CustomBinaryReader baseReader, bool isChunked,
internal LimitedStream(ICustomStreamReader baseStream, bool isChunked,
long contentLength)
{
this.baseStream = baseStream;
this.baseReader = baseReader;
this.isChunked = isChunked;
bytesRemaining = isChunked
? 0
......@@ -48,12 +46,12 @@ namespace Titanium.Web.Proxy.EventArguments
if (readChunkTrail)
{
// read the chunk trail of the previous chunk
string s = baseReader.ReadLineAsync().Result;
string s = baseStream.ReadLineAsync().Result;
}
readChunkTrail = true;
string chunkHead = baseReader.ReadLineAsync().Result;
string chunkHead = baseStream.ReadLineAsync().Result;
int idx = chunkHead.IndexOf(";", StringComparison.Ordinal);
if (idx >= 0)
{
......@@ -68,7 +66,7 @@ namespace Titanium.Web.Proxy.EventArguments
bytesRemaining = -1;
//chunk trail
baseReader.ReadLineAsync().Wait();
baseStream.ReadLineAsync().Wait();
}
}
......@@ -127,7 +125,7 @@ namespace Titanium.Web.Proxy.EventArguments
{
if (bytesRemaining != -1)
{
var buffer = BufferPool.GetBuffer(baseReader.Buffer.Length);
var buffer = BufferPool.GetBuffer(baseStream.BufferSize);
try
{
int res = await ReadAsync(buffer, 0, buffer.Length);
......
......@@ -68,16 +68,11 @@ namespace Titanium.Web.Proxy.EventArguments
/// </summary>
public event EventHandler<MultipartRequestPartSentEventArgs> MultipartRequestPartSent;
private CustomBufferedStream GetStream(bool isRequest)
private ICustomStreamReader GetStreamReader(bool isRequest)
{
return isRequest ? ProxyClient.ClientStream : WebSession.ServerConnection.Stream;
}
private CustomBinaryReader GetStreamReader(bool isRequest)
{
return isRequest ? ProxyClient.ClientStreamReader : WebSession.ServerConnection.StreamReader;
}
private HttpWriter GetStreamWriter(bool isRequest)
{
return isRequest ? (HttpWriter)ProxyClient.ClientStreamWriter : WebSession.ServerConnection.StreamWriter;
......@@ -207,11 +202,10 @@ namespace Titanium.Web.Proxy.EventArguments
string boundary = HttpHelper.GetBoundaryFromContentType(request.ContentType);
using (var copyStream = new CopyStream(reader, writer, BufferSize))
using (var copyStreamReader = new CustomBinaryReader(copyStream, BufferSize))
{
while (contentLength > copyStream.ReadBytes)
{
long read = await ReadUntilBoundaryAsync(copyStreamReader, contentLength, boundary, cancellationToken);
long read = await ReadUntilBoundaryAsync(copyStream, contentLength, boundary, cancellationToken);
if (read == 0)
{
break;
......@@ -220,7 +214,7 @@ namespace Titanium.Web.Proxy.EventArguments
if (contentLength > copyStream.ReadBytes)
{
var headers = new HeaderCollection();
await HeaderParser.ReadHeaders(copyStreamReader, headers, cancellationToken);
await HeaderParser.ReadHeaders(copyStream, headers, cancellationToken);
OnMultipartRequestPartSent(boundary, headers);
}
}
......@@ -241,8 +235,7 @@ namespace Titanium.Web.Proxy.EventArguments
private async Task CopyBodyAsync(bool isRequest, HttpWriter writer, TransformationMode transformation, Action<byte[], int, int> onCopy, CancellationToken cancellationToken)
{
var stream = GetStream(isRequest);
var reader = GetStreamReader(isRequest);
var stream = GetStreamReader(isRequest);
var requestResponse = isRequest ? (RequestResponseBase)WebSession.Request : WebSession.Response;
......@@ -250,7 +243,7 @@ namespace Titanium.Web.Proxy.EventArguments
long contentLength = requestResponse.ContentLength;
if (transformation == TransformationMode.None)
{
await writer.CopyBodyAsync(reader, isChunked, contentLength, onCopy, cancellationToken);
await writer.CopyBodyAsync(stream, isChunked, contentLength, onCopy, cancellationToken);
return;
}
......@@ -259,7 +252,7 @@ namespace Titanium.Web.Proxy.EventArguments
string contentEncoding = requestResponse.ContentEncoding;
Stream s = limitedStream = new LimitedStream(stream, reader, isChunked, contentLength);
Stream s = limitedStream = new LimitedStream(stream, isChunked, contentLength);
if (transformation == TransformationMode.Uncompress && contentEncoding != null)
{
......@@ -269,13 +262,10 @@ namespace Titanium.Web.Proxy.EventArguments
try
{
var bufStream = new CustomBufferedStream(s, BufferSize, true);
reader = new CustomBinaryReader(bufStream, BufferSize);
await writer.CopyBodyAsync(reader, false, -1, onCopy, cancellationToken);
await writer.CopyBodyAsync(bufStream, false, -1, onCopy, cancellationToken);
}
finally
{
reader?.Dispose();
decompressStream?.Dispose();
await limitedStream.Finish();
......@@ -287,7 +277,7 @@ namespace Titanium.Web.Proxy.EventArguments
/// Read a line from the byte stream
/// </summary>
/// <returns></returns>
private async Task<long> ReadUntilBoundaryAsync(CustomBinaryReader reader, long totalBytesToRead, string boundary, CancellationToken cancellationToken)
private async Task<long> ReadUntilBoundaryAsync(ICustomStreamReader reader, long totalBytesToRead, string boundary, CancellationToken cancellationToken)
{
int bufferDataLength = 0;
......
using System;
using System.Net;
using System.Threading;
using StreamExtended.Network;
using Titanium.Web.Proxy.Helpers;
using Titanium.Web.Proxy.Http;
using Titanium.Web.Proxy.Models;
......@@ -50,7 +51,7 @@ namespace Titanium.Web.Proxy.EventArguments
{
if (RunTime.IsWindows)
{
var remoteEndPoint = (IPEndPoint)ProxyClient.TcpClient.Client.RemoteEndPoint;
var remoteEndPoint = ClientEndPoint;
//If client is localhost get the process id
if (NetworkHelper.IsLocalIpAddress(remoteEndPoint.Address))
......
......@@ -34,7 +34,6 @@ namespace Titanium.Web.Proxy
var clientStream = new CustomBufferedStream(tcpClient.GetStream(), BufferSize);
var clientStreamReader = new CustomBinaryReader(clientStream, BufferSize);
var clientStreamWriter = new HttpResponseWriter(clientStream, BufferSize);
try
......@@ -46,7 +45,7 @@ namespace Titanium.Web.Proxy
if (await HttpHelper.IsConnectMethod(clientStream) == 1)
{
//read the first line HTTP command
string httpCmd = await clientStreamReader.ReadLineAsync(cancellationToken);
string httpCmd = await clientStream.ReadLineAsync(cancellationToken);
if (string.IsNullOrEmpty(httpCmd))
{
return;
......@@ -64,7 +63,7 @@ namespace Titanium.Web.Proxy
HttpVersion = version
};
await HeaderParser.ReadHeaders(clientStreamReader, connectRequest.Headers, cancellationToken);
await HeaderParser.ReadHeaders(clientStream, connectRequest.Headers, cancellationToken);
connectArgs = new TunnelConnectSessionEventArgs(BufferSize, endPoint, connectRequest,
cancellationTokenSource, ExceptionFunc);
......@@ -159,7 +158,7 @@ namespace Titanium.Web.Proxy
options.ApplicationProtocols = clientHelloInfo.GetAlpn();
if (options.ApplicationProtocols == null || options.ApplicationProtocols.Count == 0)
{
options.ApplicationProtocols = SslExtensions.Http11ProtocolAsList;
options.ApplicationProtocols = Titanium.Web.Proxy.Extensions.SslExtensions.Http11ProtocolAsList;
}
}
......@@ -172,8 +171,6 @@ namespace Titanium.Web.Proxy
//HTTPS server created - we can now decrypt the client's traffic
clientStream = new CustomBufferedStream(sslStream, BufferSize);
clientStreamReader.Dispose();
clientStreamReader = new CustomBinaryReader(clientStream, BufferSize);
clientStreamWriter = new HttpResponseWriter(clientStream, BufferSize);
}
catch (Exception e)
......@@ -240,23 +237,23 @@ namespace Titanium.Web.Proxy
if (connectArgs != null && await HttpHelper.IsPriMethod(clientStream) == 1)
{
// todo
string httpCmd = await clientStreamReader.ReadLineAsync(cancellationToken);
string httpCmd = await clientStream.ReadLineAsync(cancellationToken);
if (httpCmd == "PRI * HTTP/2.0")
{
// HTTP/2 Connection Preface
string line = await clientStreamReader.ReadLineAsync(cancellationToken);
string line = await clientStream.ReadLineAsync(cancellationToken);
if (line != string.Empty)
{
throw new Exception($"HTTP/2 Protocol violation. Empty string expected, '{line}' received");
}
line = await clientStreamReader.ReadLineAsync(cancellationToken);
line = await clientStream.ReadLineAsync(cancellationToken);
if (line != "SM")
{
throw new Exception($"HTTP/2 Protocol violation. 'SM' expected, '{line}' received");
}
line = await clientStreamReader.ReadLineAsync(cancellationToken);
line = await clientStream.ReadLineAsync(cancellationToken);
if (line != string.Empty)
{
throw new Exception($"HTTP/2 Protocol violation. Empty string expected, '{line}' received");
......@@ -279,7 +276,7 @@ namespace Titanium.Web.Proxy
}
//Now create the request
await HandleHttpSessionRequest(endPoint, tcpClient, clientStream, clientStreamReader,
await HandleHttpSessionRequest(endPoint, tcpClient, clientStream,
clientStreamWriter, cancellationTokenSource, connectHostname,
connectArgs?.WebSession.ConnectRequest);
}
......@@ -301,7 +298,6 @@ namespace Titanium.Web.Proxy
}
finally
{
clientStreamReader.Dispose();
clientStream.Dispose();
if (!cancellationTokenSource.IsCancellationRequested)
{
......
......@@ -11,17 +11,20 @@ using Titanium.Web.Proxy.Shared;
namespace Titanium.Web.Proxy.Helpers
{
internal class HttpWriter : CustomBinaryWriter
internal class HttpWriter : ICustomStreamWriter
{
private readonly Stream stream;
private static readonly byte[] newLine = ProxyConstants.NewLine;
private static readonly Encoder encoder = Encoding.ASCII.GetEncoder();
private readonly char[] charBuffer;
internal HttpWriter(Stream stream, int bufferSize) : base(stream)
internal HttpWriter(Stream stream, int bufferSize)
{
BufferSize = bufferSize;
this.stream = stream;
// ASCII encoder max byte count is char count + 1
charBuffer = new char[BufferSize - 1];
......@@ -62,7 +65,7 @@ namespace Titanium.Web.Proxy.Helpers
idx += newLineChars;
}
return WriteAsync(buffer, 0, idx, cancellationToken);
return stream.WriteAsync(buffer, 0, idx, cancellationToken);
}
finally
{
......@@ -82,7 +85,7 @@ namespace Titanium.Web.Proxy.Helpers
idx += newLineChars;
}
return WriteAsync(buffer, 0, idx, cancellationToken);
return stream.WriteAsync(buffer, 0, idx, cancellationToken);
}
}
......@@ -109,26 +112,26 @@ namespace Titanium.Web.Proxy.Helpers
await WriteLineAsync(cancellationToken);
if (flush)
{
await FlushAsync(cancellationToken);
await stream.FlushAsync(cancellationToken);
}
}
internal async Task WriteAsync(byte[] data, bool flush = false, CancellationToken cancellationToken = default)
{
await WriteAsync(data, 0, data.Length, cancellationToken);
await stream.WriteAsync(data, 0, data.Length, cancellationToken);
if (flush)
{
await FlushAsync(cancellationToken);
await stream.FlushAsync(cancellationToken);
}
}
internal async Task WriteAsync(byte[] data, int offset, int count, bool flush,
CancellationToken cancellationToken = default)
{
await WriteAsync(data, offset, count, cancellationToken);
await stream.WriteAsync(data, offset, count, cancellationToken);
if (flush)
{
await FlushAsync(cancellationToken);
await stream.FlushAsync(cancellationToken);
}
}
......@@ -159,7 +162,7 @@ namespace Titanium.Web.Proxy.Helpers
/// <param name="onCopy"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
internal Task CopyBodyAsync(CustomBinaryReader streamReader, bool isChunked, long contentLength,
internal Task CopyBodyAsync(ICustomStreamReader streamReader, bool isChunked, long contentLength,
Action<byte[], int, int> onCopy, CancellationToken cancellationToken)
{
//For chunked request we need to read data as they arrive, until we reach a chunk end symbol
......@@ -204,7 +207,7 @@ namespace Titanium.Web.Proxy.Helpers
/// <param name="onCopy"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
private async Task CopyBodyChunkedAsync(CustomBinaryReader reader, Action<byte[], int, int> onCopy,
private async Task CopyBodyChunkedAsync(ICustomStreamReader reader, Action<byte[], int, int> onCopy,
CancellationToken cancellationToken)
{
while (true)
......@@ -245,31 +248,39 @@ namespace Titanium.Web.Proxy.Helpers
/// <param name="onCopy"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
private async Task CopyBytesFromStream(CustomBinaryReader reader, long count, Action<byte[], int, int> onCopy,
private async Task CopyBytesFromStream(ICustomStreamReader reader, long count, Action<byte[], int, int> onCopy,
CancellationToken cancellationToken)
{
var buffer = reader.Buffer;
long remainingBytes = count;
var buffer = BufferPool.GetBuffer(BufferSize);
while (remainingBytes > 0)
try
{
int bytesToRead = buffer.Length;
if (remainingBytes < bytesToRead)
{
bytesToRead = (int)remainingBytes;
}
long remainingBytes = count;
int bytesRead = await reader.ReadBytesAsync(buffer, bytesToRead, cancellationToken);
if (bytesRead == 0)
while (remainingBytes > 0)
{
break;
}
int bytesToRead = buffer.Length;
if (remainingBytes < bytesToRead)
{
bytesToRead = (int)remainingBytes;
}
remainingBytes -= bytesRead;
int bytesRead = await reader.ReadAsync(buffer, 0, bytesToRead, cancellationToken);
if (bytesRead == 0)
{
break;
}
await WriteAsync(buffer, 0, bytesRead, cancellationToken);
remainingBytes -= bytesRead;
onCopy?.Invoke(buffer, 0, bytesRead);
await stream.WriteAsync(buffer, 0, bytesRead, cancellationToken);
onCopy?.Invoke(buffer, 0, bytesRead);
}
}
finally
{
BufferPool.ReturnBuffer(buffer);
}
}
......@@ -291,5 +302,33 @@ namespace Titanium.Web.Proxy.Helpers
await WriteBodyAsync(body, requestResponse.IsChunked, cancellationToken);
}
}
/// <summary>When overridden in a derived class, writes a sequence of bytes to the current stream and advances the current position within this stream by the number of bytes written.</summary>
/// <param name="buffer">An array of bytes. This method copies count bytes from buffer to the current stream.</param>
/// <param name="offset">The zero-based byte offset in buffer at which to begin copying bytes to the current stream.</param>
/// <param name="count">The number of bytes to be written to the current stream.</param>
/// <exception cref="T:System.ArgumentException">The sum of offset and count is greater than the buffer length.</exception>
/// <exception cref="T:System.ArgumentNullException">buffer is null.</exception>
/// <exception cref="T:System.ArgumentOutOfRangeException">offset or count is negative.</exception>
/// <exception cref="T:System.IO.IOException">An I/O error occured, such as the specified file cannot be found.</exception>
/// <exception cref="T:System.NotSupportedException">The stream does not support writing.</exception>
/// <exception cref="T:System.ObjectDisposedException"><see cref="M:System.IO.Stream.Write(System.Byte[],System.Int32,System.Int32)"></see> was called after the stream was closed.</exception>
public void Write(byte[] buffer, int offset, int count)
{
stream.Write(buffer, offset, count);
}
/// <summary>
/// Asynchronously writes a sequence of bytes to the current stream, advances the current position within this stream by the number of bytes written, and monitors cancellation requests.
/// </summary>
/// <param name="buffer">The buffer to write data from.</param>
/// <param name="offset">The zero-based byte offset in <paramref name="buffer" /> from which to begin copying bytes to the stream.</param>
/// <param name="count">The maximum number of bytes to write.</param>
/// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="P:System.Threading.CancellationToken.None" />.</param>
/// <returns>A task that represents the asynchronous write operation.</returns>
public Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
return stream.WriteAsync(buffer, offset, count, cancellationToken);
}
}
}
......@@ -8,7 +8,7 @@ namespace Titanium.Web.Proxy.Http
{
internal static class HeaderParser
{
internal static async Task ReadHeaders(CustomBinaryReader reader, HeaderCollection headerCollection,
internal static async Task ReadHeaders(ICustomStreamReader reader, HeaderCollection headerCollection,
CancellationToken cancellationToken)
{
string tmpLine;
......
......@@ -121,7 +121,7 @@ namespace Titanium.Web.Proxy.Http
{
if (Request.ExpectContinue)
{
string httpStatus = await ServerConnection.StreamReader.ReadLineAsync(cancellationToken);
string httpStatus = await ServerConnection.Stream.ReadLineAsync(cancellationToken);
Response.ParseResponseLine(httpStatus, out _, out int responseStatusCode,
out string responseStatusDescription);
......@@ -131,13 +131,13 @@ namespace Titanium.Web.Proxy.Http
&& responseStatusDescription.EqualsIgnoreCase("continue"))
{
Request.Is100Continue = true;
await ServerConnection.StreamReader.ReadLineAsync(cancellationToken);
await ServerConnection.Stream.ReadLineAsync(cancellationToken);
}
else if (responseStatusCode == (int)HttpStatusCode.ExpectationFailed
&& responseStatusDescription.EqualsIgnoreCase("expectation failed"))
{
Request.ExpectationFailed = true;
await ServerConnection.StreamReader.ReadLineAsync(cancellationToken);
await ServerConnection.Stream.ReadLineAsync(cancellationToken);
}
}
}
......@@ -155,7 +155,7 @@ namespace Titanium.Web.Proxy.Http
return;
}
string httpStatus = await ServerConnection.StreamReader.ReadLineAsync(cancellationToken);
string httpStatus = await ServerConnection.Stream.ReadLineAsync(cancellationToken);
if (httpStatus == null)
{
throw new IOException();
......@@ -163,7 +163,7 @@ namespace Titanium.Web.Proxy.Http
if (httpStatus == string.Empty)
{
httpStatus = await ServerConnection.StreamReader.ReadLineAsync(cancellationToken);
httpStatus = await ServerConnection.Stream.ReadLineAsync(cancellationToken);
}
Response.ParseResponseLine(httpStatus, out var version, out int statusCode, out string statusDescription);
......@@ -179,7 +179,7 @@ namespace Titanium.Web.Proxy.Http
//Read the next line after 100-continue
Response.Is100Continue = true;
Response.StatusCode = 0;
await ServerConnection.StreamReader.ReadLineAsync(cancellationToken);
await ServerConnection.Stream.ReadLineAsync(cancellationToken);
//now receive response
await ReceiveResponse(cancellationToken);
......@@ -192,7 +192,7 @@ namespace Titanium.Web.Proxy.Http
//read next line after expectation failed response
Response.ExpectationFailed = true;
Response.StatusCode = 0;
await ServerConnection.StreamReader.ReadLineAsync(cancellationToken);
await ServerConnection.Stream.ReadLineAsync(cancellationToken);
//now receive response
await ReceiveResponse(cancellationToken);
......@@ -200,7 +200,7 @@ namespace Titanium.Web.Proxy.Http
}
//Read the response headers in to unique and non-unique header collections
await HeaderParser.ReadHeaders(ServerConnection.StreamReader, Response.Headers, cancellationToken);
await HeaderParser.ReadHeaders(ServerConnection.Stream, Response.Headers, cancellationToken);
}
/// <summary>
......
......@@ -24,12 +24,12 @@ namespace Titanium.Web.Proxy.Network
public int Counter { get; }
protected override void OnDataSent(byte[] buffer, int offset, int count)
protected override void OnDataWrite(byte[] buffer, int offset, int count)
{
fileStreamSent.Write(buffer, offset, count);
}
protected override void OnDataReceived(byte[] buffer, int offset, int count)
protected override void OnDataRead(byte[] buffer, int offset, int count)
{
fileStreamReceived.Write(buffer, offset, count);
}
......
......@@ -19,11 +19,6 @@ namespace Titanium.Web.Proxy.Network
/// </summary>
internal CustomBufferedStream ClientStream { get; set; }
/// <summary>
/// Used to read line by line from client
/// </summary>
internal CustomBinaryReader ClientStreamReader { get; set; }
/// <summary>
/// Used to write line by line to client
/// </summary>
......
......@@ -46,11 +46,6 @@ namespace Titanium.Web.Proxy.Network.Tcp
internal TcpClient TcpClient { private get; set; }
/// <summary>
/// Used to read lines from server
/// </summary>
internal CustomBinaryReader StreamReader { get; set; }
/// <summary>
/// Used to write lines to server
/// </summary>
......@@ -71,8 +66,6 @@ namespace Titanium.Web.Proxy.Network.Tcp
/// </summary>
public void Dispose()
{
StreamReader?.Dispose();
Stream?.Dispose();
TcpClient.CloseSocket();
......
......@@ -93,20 +93,17 @@ namespace Titanium.Web.Proxy.Network.Tcp
await writer.WriteRequestAsync(connectRequest, cancellationToken: cancellationToken);
using (var reader = new CustomBinaryReader(stream, proxyServer.BufferSize))
{
string httpStatus = await reader.ReadLineAsync(cancellationToken);
Response.ParseResponseLine(httpStatus, out _, out int statusCode, out string statusDescription);
string httpStatus = await stream.ReadLineAsync(cancellationToken);
if (statusCode != 200 && !statusDescription.EqualsIgnoreCase("OK")
&& !statusDescription.EqualsIgnoreCase("Connection Established"))
{
throw new Exception("Upstream proxy failed to create a secure tunnel");
}
Response.ParseResponseLine(httpStatus, out _, out int statusCode, out string statusDescription);
await reader.ReadAndIgnoreAllLinesAsync(cancellationToken);
if (statusCode != 200 && !statusDescription.EqualsIgnoreCase("OK")
&& !statusDescription.EqualsIgnoreCase("Connection Established"))
{
throw new Exception("Upstream proxy failed to create a secure tunnel");
}
await stream.ReadAndIgnoreAllLinesAsync(cancellationToken);
}
if (decryptSsl)
......@@ -152,7 +149,6 @@ namespace Titanium.Web.Proxy.Network.Tcp
IsHttp2Supported = http2Supported,
UseUpstreamProxy = useUpstreamProxy,
TcpClient = client,
StreamReader = new CustomBinaryReader(stream, proxyServer.BufferSize),
StreamWriter = new HttpRequestWriter(stream, proxyServer.BufferSize),
Stream = stream,
Version = httpVersion
......
......@@ -34,7 +34,6 @@ namespace Titanium.Web.Proxy
/// <param name="endPoint">The proxy endpoint.</param>
/// <param name="client">The client.</param>
/// <param name="clientStream">The client stream.</param>
/// <param name="clientStreamReader">The client stream reader.</param>
/// <param name="clientStreamWriter">The client stream writer.</param>
/// <param name="cancellationTokenSource">The cancellation token source for this async task.</param>
/// <param name="httpsConnectHostname">
......@@ -45,8 +44,7 @@ namespace Titanium.Web.Proxy
/// <param name="isTransparentEndPoint">Is this a request from transparent endpoint?</param>
/// <returns></returns>
private async Task HandleHttpSessionRequest(ProxyEndPoint endPoint, TcpClient client,
CustomBufferedStream clientStream, CustomBinaryReader clientStreamReader,
HttpResponseWriter clientStreamWriter,
CustomBufferedStream clientStream, HttpResponseWriter clientStreamWriter,
CancellationTokenSource cancellationTokenSource, string httpsConnectHostname, ConnectRequest connectRequest,
bool isTransparentEndPoint = false)
{
......@@ -60,7 +58,7 @@ namespace Titanium.Web.Proxy
while (true)
{
// read the request line
string httpCmd = await clientStreamReader.ReadLineAsync(cancellationToken);
string httpCmd = await clientStream.ReadLineAsync(cancellationToken);
if (string.IsNullOrEmpty(httpCmd))
{
......@@ -81,7 +79,7 @@ namespace Titanium.Web.Proxy
out var version);
//Read the request headers in to unique and non-unique header collections
await HeaderParser.ReadHeaders(clientStreamReader, args.WebSession.Request.Headers,
await HeaderParser.ReadHeaders(clientStream, args.WebSession.Request.Headers,
cancellationToken);
Uri httpRemoteUri;
......@@ -124,7 +122,6 @@ namespace Titanium.Web.Proxy
request.Method = httpMethod;
request.HttpVersion = version;
args.ProxyClient.ClientStream = clientStream;
args.ProxyClient.ClientStreamReader = clientStreamReader;
args.ProxyClient.ClientStreamWriter = clientStreamWriter;
//proxy authorization check
......@@ -198,7 +195,7 @@ namespace Titanium.Web.Proxy
await connection.StreamWriter.WriteLineAsync(httpCmd, cancellationToken);
await connection.StreamWriter.WriteHeadersAsync(request.Headers,
cancellationToken: cancellationToken);
string httpStatus = await connection.StreamReader.ReadLineAsync(cancellationToken);
string httpStatus = await connection.Stream.ReadLineAsync(cancellationToken);
Response.ParseResponseLine(httpStatus, out var responseVersion,
out int responseStatusCode,
......@@ -207,7 +204,7 @@ namespace Titanium.Web.Proxy
response.StatusCode = responseStatusCode;
response.StatusDescription = responseStatusDescription;
await HeaderParser.ReadHeaders(connection.StreamReader, response.Headers,
await HeaderParser.ReadHeaders(connection.Stream, response.Headers,
cancellationToken);
if (!args.IsTransparent)
......
......@@ -37,8 +37,8 @@
<Reference Include="BouncyCastle.Crypto, Version=1.8.2.0, Culture=neutral, PublicKeyToken=0e99375e54769942, processorArchitecture=MSIL">
<HintPath>..\packages\Portable.BouncyCastle.1.8.2\lib\net40\BouncyCastle.Crypto.dll</HintPath>
</Reference>
<Reference Include="StreamExtended, Version=1.0.147.0, Culture=neutral, PublicKeyToken=bbfa0f1d54f50043, processorArchitecture=MSIL">
<HintPath>..\packages\StreamExtended.1.0.147-beta\lib\net45\StreamExtended.dll</HintPath>
<Reference Include="StreamExtended, Version=1.0.160.0, Culture=neutral, PublicKeyToken=bbfa0f1d54f50043, processorArchitecture=MSIL">
<HintPath>..\packages\StreamExtended.1.0.160-beta\lib\net45\StreamExtended.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
......
......@@ -13,7 +13,7 @@
<ItemGroup>
<PackageReference Include="Portable.BouncyCastle" Version="1.8.2" />
<PackageReference Include="StreamExtended" Version="1.0.147-beta" />
<PackageReference Include="StreamExtended" Version="1.0.160-beta" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
......
......@@ -14,7 +14,7 @@
<copyright>Copyright &#x00A9; Titanium. All rights reserved.</copyright>
<tags></tags>
<dependencies>
<dependency id="StreamExtended" version="1.0.147-beta" />
<dependency id="StreamExtended" version="1.0.160-beta" />
<dependency id="Portable.BouncyCastle" version="1.8.2" />
</dependencies>
</metadata>
......
......@@ -30,7 +30,6 @@ namespace Titanium.Web.Proxy
var clientStream = new CustomBufferedStream(tcpClient.GetStream(), BufferSize);
var clientStreamReader = new CustomBinaryReader(clientStream, BufferSize);
var clientStreamWriter = new HttpResponseWriter(clientStream, BufferSize);
try
......@@ -73,8 +72,6 @@ namespace Titanium.Web.Proxy
//HTTPS server created - we can now decrypt the client's traffic
clientStream = new CustomBufferedStream(sslStream, BufferSize);
clientStreamReader.Dispose();
clientStreamReader = new CustomBinaryReader(clientStream, BufferSize);
clientStreamWriter = new HttpResponseWriter(clientStream, BufferSize);
}
catch (Exception e)
......@@ -126,12 +123,11 @@ namespace Titanium.Web.Proxy
//HTTPS server created - we can now decrypt the client's traffic
//Now create the request
await HandleHttpSessionRequest(endPoint, tcpClient, clientStream, clientStreamReader,
clientStreamWriter, cancellationTokenSource, isHttps ? httpsHostName : null, null, true);
await HandleHttpSessionRequest(endPoint, tcpClient, clientStream, clientStreamWriter,
cancellationTokenSource, isHttps ? httpsHostName : null, null, true);
}
finally
{
clientStreamReader.Dispose();
clientStream.Dispose();
if (!cancellationTokenSource.IsCancellationRequested)
{
......
......@@ -2,5 +2,5 @@
<packages>
<package id="Portable.BouncyCastle" version="1.8.2" targetFramework="net45" />
<package id="StreamExtended" version="1.0.147-beta" targetFramework="net45" />
<package id="StreamExtended" version="1.0.160-beta" targetFramework="net45" />
</packages>
\ No newline at end of file
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