Unverified Commit f9a74d7b authored by honfika's avatar honfika Committed by GitHub

Merge pull request #691 from justcoding121/master

less exceptions
parents b81baeca 4febcb05
...@@ -26,7 +26,7 @@ namespace Titanium.Web.Proxy.Examples.Basic ...@@ -26,7 +26,7 @@ namespace Titanium.Web.Proxy.Examples.Basic
{ {
proxyServer = new ProxyServer(); proxyServer = new ProxyServer();
proxyServer.EnableHttp2 = true; //proxyServer.EnableHttp2 = true;
// generate root certificate without storing it in file system // generate root certificate without storing it in file system
//proxyServer.CertificateManager.CreateRootCertificate(false); //proxyServer.CertificateManager.CreateRootCertificate(false);
......
...@@ -141,6 +141,8 @@ namespace Titanium.Web.Proxy ...@@ -141,6 +141,8 @@ namespace Titanium.Web.Proxy
bool http2Supported = false; bool http2Supported = false;
if (EnableHttp2)
{
var alpn = clientHelloInfo.GetAlpn(); var alpn = clientHelloInfo.GetAlpn();
if (alpn != null && alpn.Contains(SslApplicationProtocol.Http2)) if (alpn != null && alpn.Contains(SslApplicationProtocol.Http2))
{ {
...@@ -163,6 +165,7 @@ namespace Titanium.Web.Proxy ...@@ -163,6 +165,7 @@ namespace Titanium.Web.Proxy
// ignore // ignore
} }
} }
}
if (EnableTcpServerConnectionPrefetch) if (EnableTcpServerConnectionPrefetch)
{ {
...@@ -274,7 +277,7 @@ namespace Titanium.Web.Proxy ...@@ -274,7 +277,7 @@ namespace Titanium.Web.Proxy
// If we detected that client tunnel CONNECTs without SSL by checking for empty client hello then // If we detected that client tunnel CONNECTs without SSL by checking for empty client hello then
// this connection should not be HTTPS. // this connection should not be HTTPS.
var connection = await tcpConnectionFactory.GetServerConnection(this, connectArgs, var connection = await tcpConnectionFactory.GetServerConnection(this, connectArgs,
true, SslExtensions.Http2ProtocolAsList, true, null,
true, cancellationToken); true, cancellationToken);
try try
......
...@@ -33,7 +33,8 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -33,7 +33,8 @@ namespace Titanium.Web.Proxy.Helpers
private bool disposed; private bool disposed;
private bool closed; private bool closedWrite;
private bool closedRead;
private readonly IBufferPool bufferPool; private readonly IBufferPool bufferPool;
...@@ -43,7 +44,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -43,7 +44,7 @@ namespace Titanium.Web.Proxy.Helpers
private Stream baseStream { get; } private Stream baseStream { get; }
public bool IsClosed => closed; public bool IsClosed => closedRead;
static HttpStream() static HttpStream()
{ {
...@@ -88,9 +89,23 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -88,9 +89,23 @@ namespace Titanium.Web.Proxy.Helpers
/// When overridden in a derived class, clears all buffers for this stream and causes any buffered data to be written to the underlying device. /// When overridden in a derived class, clears all buffers for this stream and causes any buffered data to be written to the underlying device.
/// </summary> /// </summary>
public override void Flush() public override void Flush()
{
if (closedWrite)
{
return;
}
try
{ {
baseStream.Flush(); baseStream.Flush();
} }
catch
{
closedWrite = true;
if (!swallowException)
throw;
}
}
/// <summary> /// <summary>
/// When overridden in a derived class, sets the position within the current stream. /// When overridden in a derived class, sets the position within the current stream.
...@@ -153,8 +168,23 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -153,8 +168,23 @@ namespace Titanium.Web.Proxy.Helpers
public override void Write(byte[] buffer, int offset, int count) public override void Write(byte[] buffer, int offset, int count)
{ {
OnDataWrite(buffer, offset, count); OnDataWrite(buffer, offset, count);
if (closedWrite)
{
return;
}
try
{
baseStream.Write(buffer, offset, count); baseStream.Write(buffer, offset, count);
} }
catch
{
closedWrite = true;
if (!swallowException)
throw;
}
}
/// <summary> /// <summary>
/// Asynchronously reads the bytes from the current stream and writes them to another stream, using a specified buffer size and cancellation token. /// Asynchronously reads the bytes from the current stream and writes them to another stream, using a specified buffer size and cancellation token.
...@@ -184,9 +214,23 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -184,9 +214,23 @@ namespace Titanium.Web.Proxy.Helpers
/// <returns> /// <returns>
/// A task that represents the asynchronous flush operation. /// A task that represents the asynchronous flush operation.
/// </returns> /// </returns>
public override Task FlushAsync(CancellationToken cancellationToken) public override async Task FlushAsync(CancellationToken cancellationToken)
{
if (closedWrite)
{ {
return baseStream.FlushAsync(cancellationToken); return;
}
try
{
await baseStream.FlushAsync(cancellationToken);
}
catch
{
closedWrite = true;
if (!swallowException)
throw;
}
} }
/// <summary> /// <summary>
...@@ -393,8 +437,23 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -393,8 +437,23 @@ namespace Titanium.Web.Proxy.Helpers
public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{ {
OnDataWrite(buffer, offset, count); OnDataWrite(buffer, offset, count);
if (closedWrite)
{
return;
}
try
{
await baseStream.WriteAsync(buffer, offset, count, cancellationToken); await baseStream.WriteAsync(buffer, offset, count, cancellationToken);
} }
catch
{
closedWrite = true;
if (!swallowException)
throw;
}
}
/// <summary> /// <summary>
/// Writes a byte to the current position in the stream and advances the position within the stream by one byte. /// Writes a byte to the current position in the stream and advances the position within the stream by one byte.
...@@ -402,6 +461,11 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -402,6 +461,11 @@ namespace Titanium.Web.Proxy.Helpers
/// <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)
{ {
if (closedWrite)
{
return;
}
var buffer = bufferPool.GetBuffer(); var buffer = bufferPool.GetBuffer();
try try
{ {
...@@ -409,6 +473,12 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -409,6 +473,12 @@ namespace Titanium.Web.Proxy.Helpers
OnDataWrite(buffer, 0, 1); OnDataWrite(buffer, 0, 1);
baseStream.Write(buffer, 0, 1); baseStream.Write(buffer, 0, 1);
} }
catch
{
closedWrite = true;
if (!swallowException)
throw;
}
finally finally
{ {
bufferPool.ReturnBuffer(buffer); bufferPool.ReturnBuffer(buffer);
...@@ -434,7 +504,8 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -434,7 +504,8 @@ namespace Titanium.Web.Proxy.Helpers
if (!disposed) if (!disposed)
{ {
disposed = true; disposed = true;
closed = true; closedRead = true;
closedWrite = true;
if (!leaveOpen) if (!leaveOpen)
{ {
baseStream.Dispose(); baseStream.Dispose();
...@@ -511,7 +582,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -511,7 +582,7 @@ namespace Titanium.Web.Proxy.Helpers
/// </summary> /// </summary>
public bool FillBuffer() public bool FillBuffer()
{ {
if (closed) if (closedRead)
{ {
throw new Exception("Stream is already closed"); throw new Exception("Stream is already closed");
} }
...@@ -536,11 +607,17 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -536,11 +607,17 @@ namespace Titanium.Web.Proxy.Helpers
bufferLength += readBytes; bufferLength += readBytes;
} }
} }
catch
{
if (!swallowException)
throw;
}
finally finally
{ {
if (!result) if (!result)
{ {
closed = true; closedRead = true;
closedWrite = true;
} }
} }
...@@ -555,7 +632,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -555,7 +632,7 @@ namespace Titanium.Web.Proxy.Helpers
/// <returns></returns> /// <returns></returns>
public async ValueTask<bool> FillBufferAsync(CancellationToken cancellationToken = default) public async ValueTask<bool> FillBufferAsync(CancellationToken cancellationToken = default)
{ {
if (closed) if (closedRead)
{ {
throw new Exception("Stream is already closed"); throw new Exception("Stream is already closed");
} }
...@@ -595,7 +672,8 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -595,7 +672,8 @@ namespace Titanium.Web.Proxy.Helpers
{ {
if (!result) if (!result)
{ {
closed = true; closedRead = true;
closedWrite = true;
} }
} }
...@@ -766,6 +844,11 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -766,6 +844,11 @@ namespace Titanium.Web.Proxy.Helpers
private async ValueTask writeAsyncInternal(string value, bool addNewLine, CancellationToken cancellationToken) private async ValueTask writeAsyncInternal(string value, bool addNewLine, CancellationToken cancellationToken)
{ {
if (closedWrite)
{
return;
}
int newLineChars = addNewLine ? newLine.Length : 0; int newLineChars = addNewLine ? newLine.Length : 0;
int charCount = value.Length; int charCount = value.Length;
if (charCount < bufferPool.BufferSize - newLineChars) if (charCount < bufferPool.BufferSize - newLineChars)
...@@ -782,6 +865,12 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -782,6 +865,12 @@ namespace Titanium.Web.Proxy.Helpers
await baseStream.WriteAsync(buffer, 0, idx, cancellationToken); await baseStream.WriteAsync(buffer, 0, idx, cancellationToken);
} }
catch
{
closedWrite = true;
if (!swallowException)
throw;
}
finally finally
{ {
bufferPool.ReturnBuffer(buffer); bufferPool.ReturnBuffer(buffer);
...@@ -797,8 +886,17 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -797,8 +886,17 @@ namespace Titanium.Web.Proxy.Helpers
idx += newLineChars; idx += newLineChars;
} }
try
{
await baseStream.WriteAsync(buffer, 0, idx, cancellationToken); await baseStream.WriteAsync(buffer, 0, idx, cancellationToken);
} }
catch
{
closedWrite = true;
if (!swallowException)
throw;
}
}
} }
public ValueTask WriteLineAsync(string value, CancellationToken cancellationToken = default) public ValueTask WriteLineAsync(string value, CancellationToken cancellationToken = default)
...@@ -825,6 +923,13 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -825,6 +923,13 @@ namespace Titanium.Web.Proxy.Helpers
/// <param name="flush">Should we flush after write?</param> /// <param name="flush">Should we flush after write?</param>
/// <param name="cancellationToken">The cancellation token.</param> /// <param name="cancellationToken">The cancellation token.</param>
internal async ValueTask WriteAsync(byte[] data, bool flush = false, CancellationToken cancellationToken = default) internal async ValueTask WriteAsync(byte[] data, bool flush = false, CancellationToken cancellationToken = default)
{
if (closedWrite)
{
return;
}
try
{ {
await baseStream.WriteAsync(data, 0, data.Length, cancellationToken); await baseStream.WriteAsync(data, 0, data.Length, cancellationToken);
if (flush) if (flush)
...@@ -832,9 +937,23 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -832,9 +937,23 @@ namespace Titanium.Web.Proxy.Helpers
await baseStream.FlushAsync(cancellationToken); await baseStream.FlushAsync(cancellationToken);
} }
} }
catch
{
closedWrite = true;
if (!swallowException)
throw;
}
}
internal async Task WriteAsync(byte[] data, int offset, int count, bool flush, internal async Task WriteAsync(byte[] data, int offset, int count, bool flush,
CancellationToken cancellationToken = default) CancellationToken cancellationToken = default)
{
if (closedWrite)
{
return;
}
try
{ {
await baseStream.WriteAsync(data, offset, count, cancellationToken); await baseStream.WriteAsync(data, offset, count, cancellationToken);
if (flush) if (flush)
...@@ -842,6 +961,13 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -842,6 +961,13 @@ namespace Titanium.Web.Proxy.Helpers
await baseStream.FlushAsync(cancellationToken); await baseStream.FlushAsync(cancellationToken);
} }
} }
catch
{
closedWrite = true;
if (!swallowException)
throw;
}
}
/// <summary> /// <summary>
/// Writes the byte array body to the stream; optionally chunked /// Writes the byte array body to the stream; optionally chunked
...@@ -1056,9 +1182,23 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -1056,9 +1182,23 @@ namespace Titanium.Web.Proxy.Helpers
/// <param name="buffer">The buffer to write data from.</param> /// <param name="buffer">The buffer to write data from.</param>
/// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="P:System.Threading.CancellationToken.None" />.</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> /// <returns>A task that represents the asynchronous write operation.</returns>
public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = default) public override async ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = default)
{
if (closedWrite)
{ {
return baseStream.WriteAsync(buffer, cancellationToken); return;
}
try
{
await baseStream.WriteAsync(buffer, cancellationToken);
}
catch
{
closedWrite = true;
if (!swallowException)
throw;
}
} }
#else #else
/// <summary> /// <summary>
...@@ -1067,11 +1207,19 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -1067,11 +1207,19 @@ namespace Titanium.Web.Proxy.Helpers
/// <param name="buffer">The buffer to write data from.</param> /// <param name="buffer">The buffer to write data from.</param>
/// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="P:System.Threading.CancellationToken.None" />.</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> /// <returns>A task that represents the asynchronous write operation.</returns>
public Task WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken) public async Task WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken)
{ {
var buf = ArrayPool<byte>.Shared.Rent(buffer.Length); var buf = ArrayPool<byte>.Shared.Rent(buffer.Length);
buffer.CopyTo(buf); buffer.CopyTo(buf);
return baseStream.WriteAsync(buf, 0, buf.Length, cancellationToken); try
{
await baseStream.WriteAsync(buf, 0, buf.Length, cancellationToken);
}
catch
{
if (!swallowException)
throw;
}
} }
#endif #endif
} }
......
...@@ -2,25 +2,24 @@ ...@@ -2,25 +2,24 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using Titanium.Web.Proxy.StreamExtended.Network; using Titanium.Web.Proxy.StreamExtended.Network;
internal class NullWriter : IHttpStreamWriter namespace Titanium.Web.Proxy.Helpers
{ {
internal class NullWriter : IHttpStreamWriter
{
public static NullWriter Instance { get; } = new NullWriter(); public static NullWriter Instance { get; } = new NullWriter();
public void Write(byte[] buffer, int offset, int count) public void Write(byte[] buffer, int offset, int count)
{ {
} }
#if NET45
public async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
}
#else
public Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) public Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{ {
#if NET45
return Net45Compatibility.CompletedTask;
#else
return Task.CompletedTask; return Task.CompletedTask;
}
#endif #endif
}
public ValueTask WriteLineAsync(CancellationToken cancellationToken = default) public ValueTask WriteLineAsync(CancellationToken cancellationToken = default)
{ {
...@@ -31,4 +30,5 @@ internal class NullWriter : IHttpStreamWriter ...@@ -31,4 +30,5 @@ internal class NullWriter : IHttpStreamWriter
{ {
throw new System.NotImplementedException(); throw new System.NotImplementedException();
} }
}
} }
...@@ -10,6 +10,8 @@ namespace Titanium.Web.Proxy ...@@ -10,6 +10,8 @@ namespace Titanium.Web.Proxy
class Net45Compatibility class Net45Compatibility
{ {
public static byte[] EmptyArray = new byte[0]; public static byte[] EmptyArray = new byte[0];
public static Task CompletedTask = new Task(() => { });
} }
} }
#endif #endif
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