Commit 2e6635d9 authored by justcoding121's avatar justcoding121 Committed by justcoding121

Merge pull request #255 from honfika/develop

Buffered stream improvements, allow to remove the machine root certificate as administrator
parents 087d374a b5c96465
...@@ -13,7 +13,6 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -13,7 +13,6 @@ namespace Titanium.Web.Proxy.Helpers
internal class CustomBinaryReader : IDisposable internal class CustomBinaryReader : IDisposable
{ {
private readonly CustomBufferedStream stream; private readonly CustomBufferedStream stream;
private readonly int bufferSize;
private readonly Encoding encoding; private readonly Encoding encoding;
private volatile bool disposed; private volatile bool disposed;
...@@ -24,7 +23,6 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -24,7 +23,6 @@ namespace Titanium.Web.Proxy.Helpers
{ {
this.stream = stream; this.stream = stream;
Buffer = BufferPool.GetBuffer(bufferSize); Buffer = BufferPool.GetBuffer(bufferSize);
this.bufferSize = bufferSize;
//default to UTF-8 //default to UTF-8
encoding = Encoding.UTF8; encoding = Encoding.UTF8;
......
...@@ -14,10 +14,14 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -14,10 +14,14 @@ namespace Titanium.Web.Proxy.Helpers
/// <seealso cref="System.IO.Stream" /> /// <seealso cref="System.IO.Stream" />
internal class CustomBufferedStream : Stream internal class CustomBufferedStream : Stream
{ {
private static readonly AsyncCallback readCallback = ReadCallback;
private readonly Stream baseStream; private readonly Stream baseStream;
private byte[] streamBuffer; private byte[] streamBuffer;
private readonly byte[] oneByteBuffer = new byte[1];
private int bufferLength; private int bufferLength;
private int bufferPos; private int bufferPos;
...@@ -100,6 +104,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -100,6 +104,7 @@ namespace Titanium.Web.Proxy.Helpers
/// <param name="count">The number of bytes to be written to the current stream.</param> /// <param name="count">The number of bytes to be written to the current stream.</param>
public override void Write(byte[] buffer, int offset, int count) public override void Write(byte[] buffer, int offset, int count)
{ {
OnDataSent(buffer, offset, count);
baseStream.Write(buffer, offset, count); baseStream.Write(buffer, offset, count);
} }
...@@ -123,10 +128,19 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -123,10 +128,19 @@ namespace Titanium.Web.Proxy.Helpers
Buffer.BlockCopy(streamBuffer, bufferPos, buffer, offset, available); Buffer.BlockCopy(streamBuffer, bufferPos, buffer, offset, available);
bufferPos += available; bufferPos += available;
bufferLength -= available; bufferLength -= available;
return new ReadAsyncResult(available); return new ReadAsyncResult(buffer, offset, available, state, callback);
} }
return baseStream.BeginRead(buffer, offset, count, callback, state); var result = new ReadAsyncResult(buffer, offset, 0, state, callback);
result.BaseResult = baseStream.BeginRead(buffer, offset, count, readCallback, result);
return result;
}
private static void ReadCallback(IAsyncResult ar)
{
var readResult = (ReadAsyncResult)ar.AsyncState;
readResult.BaseResult = ar;
readResult.Callback(readResult);
} }
/// <summary> /// <summary>
...@@ -143,6 +157,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -143,6 +157,7 @@ namespace Titanium.Web.Proxy.Helpers
[DebuggerStepThrough] [DebuggerStepThrough]
public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
{ {
OnDataSent(buffer, offset, count);
return baseStream.BeginWrite(buffer, offset, count, callback, state); return baseStream.BeginWrite(buffer, offset, count, callback, state);
} }
...@@ -163,7 +178,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -163,7 +178,7 @@ namespace Titanium.Web.Proxy.Helpers
bufferLength = 0; bufferLength = 0;
} }
await baseStream.CopyToAsync(destination, bufferSize, cancellationToken); await base.CopyToAsync(destination, bufferSize, cancellationToken);
} }
/// <summary> /// <summary>
...@@ -188,12 +203,11 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -188,12 +203,11 @@ namespace Titanium.Web.Proxy.Helpers
[DebuggerStepThrough] [DebuggerStepThrough]
public override int EndRead(IAsyncResult asyncResult) public override int EndRead(IAsyncResult asyncResult)
{ {
if (asyncResult is ReadAsyncResult) var readResult = (ReadAsyncResult)asyncResult;
{ int result = readResult.BaseResult == null ? readResult.ReadBytes : baseStream.EndRead(readResult.BaseResult);
return ((ReadAsyncResult)asyncResult).ReadBytes;
}
return baseStream.EndRead(asyncResult); OnDataReceived(readResult.Buffer, readResult.Offset, result);
return result;
} }
/// <summary> /// <summary>
...@@ -313,6 +327,7 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -313,6 +327,7 @@ namespace Titanium.Web.Proxy.Helpers
[DebuggerStepThrough] [DebuggerStepThrough]
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{ {
OnDataSent(buffer, offset, count);
return baseStream.WriteAsync(buffer, offset, count, cancellationToken); return baseStream.WriteAsync(buffer, offset, count, cancellationToken);
} }
...@@ -322,7 +337,17 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -322,7 +337,17 @@ 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)
{ {
baseStream.WriteByte(value); oneByteBuffer[0] = value;
OnDataSent(oneByteBuffer, 0, 1);
baseStream.Write(oneByteBuffer, 0, 1);
}
private void OnDataSent(byte[] buffer, int offset, int count)
{
}
private void OnDataReceived(byte[] buffer, int offset, int count)
{
} }
/// <summary> /// <summary>
...@@ -397,6 +422,11 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -397,6 +422,11 @@ namespace Titanium.Web.Proxy.Helpers
{ {
bufferLength = baseStream.Read(streamBuffer, 0, streamBuffer.Length); bufferLength = baseStream.Read(streamBuffer, 0, streamBuffer.Length);
bufferPos = 0; bufferPos = 0;
if (bufferLength > 0)
{
OnDataReceived(streamBuffer, 0, bufferLength);
}
return bufferLength > 0; return bufferLength > 0;
} }
...@@ -418,24 +448,41 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -418,24 +448,41 @@ namespace Titanium.Web.Proxy.Helpers
{ {
bufferLength = await baseStream.ReadAsync(streamBuffer, 0, streamBuffer.Length, cancellationToken); bufferLength = await baseStream.ReadAsync(streamBuffer, 0, streamBuffer.Length, cancellationToken);
bufferPos = 0; bufferPos = 0;
if (bufferLength > 0)
{
OnDataReceived(streamBuffer, 0, bufferLength);
}
return bufferLength > 0; return bufferLength > 0;
} }
private class ReadAsyncResult : IAsyncResult private class ReadAsyncResult : IAsyncResult
{ {
public byte[] Buffer { get; }
public int Offset { get; }
public IAsyncResult BaseResult { get; set; }
public int ReadBytes { get; } public int ReadBytes { get; }
public bool IsCompleted => true; public object AsyncState { get; }
public AsyncCallback Callback { get; }
public WaitHandle AsyncWaitHandle => null; public bool IsCompleted => CompletedSynchronously || BaseResult.IsCompleted;
public object AsyncState => null; public WaitHandle AsyncWaitHandle => BaseResult?.AsyncWaitHandle;
public bool CompletedSynchronously => true; public bool CompletedSynchronously => BaseResult == null || BaseResult.CompletedSynchronously;
public ReadAsyncResult(int readBytes) public ReadAsyncResult(byte[] buffer, int offset, int readBytes, object state, AsyncCallback callback)
{ {
Buffer = buffer;
Offset = offset;
ReadBytes = readBytes; ReadBytes = readBytes;
AsyncState = state;
Callback = callback;
} }
} }
} }
......
...@@ -276,6 +276,46 @@ namespace Titanium.Web.Proxy.Network ...@@ -276,6 +276,46 @@ namespace Titanium.Web.Proxy.Network
RemoveTrustedRootCertificates(StoreLocation.LocalMachine); RemoveTrustedRootCertificates(StoreLocation.LocalMachine);
} }
/// <summary>
/// Removes the trusted certificates from the local machine's certificate store.
/// Needs elevated permission. Works only on Windows.
/// </summary>
/// <returns></returns>
public bool RemoveTrustedRootCertificatesAsAdministrator()
{
if (RunTime.IsRunningOnMono)
{
return false;
}
var info = new ProcessStartInfo
{
FileName = "certutil.exe",
Arguments = "-delstore Root \"" + RootCertificateName + "\"",
CreateNoWindow = true,
UseShellExecute = true,
Verb = "runas",
ErrorDialog = false,
};
try
{
var process = Process.Start(info);
if (process == null)
{
return false;
}
process.WaitForExit();
}
catch
{
return false;
}
return true;
}
/// <summary> /// <summary>
/// Determines whether the root certificate is trusted. /// Determines whether the root certificate is trusted.
/// </summary> /// </summary>
......
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