Skip to content
This repository has been archived by the owner on May 17, 2024. It is now read-only.

Commit

Permalink
Merge pull request #31 from justcoding121/master
Browse files Browse the repository at this point in the history
Bufferpool beta
  • Loading branch information
justcoding121 authored May 10, 2018
2 parents 5bbefe5 + 6166e35 commit 169f3bc
Show file tree
Hide file tree
Showing 18 changed files with 706 additions and 162 deletions.
16 changes: 9 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ Supports
### Server Name Indication

```csharp
var yourClientStream = new CustomBufferedStream(clientStream, 4096)
var clientSslHelloInfo = await SslTools.PeekClientHello(yourClientStream);
var bufferPool = new DefaultBufferPool();
var yourClientStream = new CustomBufferedStream(clientStream, bufferPool, 4096)
var clientSslHelloInfo = await SslTools.PeekClientHello(yourClientStream, bufferPool);

//will be null if no client hello was received (not a SSL connection)
if (clientSslHelloInfo != null)
Expand All @@ -44,9 +45,9 @@ if (clientSslHelloInfo != null)

### Peek Client SSL Hello
```csharp

var yourClientStream = new CustomBufferedStream(clientStream, 4096)
var clientSslHelloInfo = await SslTools.PeekClientHello(yourClientStream);
var bufferPool = new DefaultBufferPool();
var yourClientStream = new CustomBufferedStream(clientStream, bufferPool, 4096)
var clientSslHelloInfo = await SslTools.PeekClientHello(yourClientStream, bufferPool);

//will be null if no client hello was received (not a SSL connection)
if(clientSslHelloInfo!=null)
Expand All @@ -59,8 +60,9 @@ if(clientSslHelloInfo!=null)

### Peek Server SSL Hello
```csharp
var yourServerStream = new CustomBufferedStream(serverStream, 4096)
var serverSslHelloInfo = await SslTools.PeekServerHello(yourServerStream);
var bufferPool = new DefaultBufferPool();
var yourServerStream = new CustomBufferedStream(serverStream, bufferPool, 4096)
var serverSslHelloInfo = await SslTools.PeekServerHello(yourServerStream, bufferPool);

//will be null if no server hello was received (not a SSL connection)
if(serverSslHelloInfo!=null)
Expand Down
27 changes: 21 additions & 6 deletions StreamExtended/Helpers/BufferPool.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,33 @@
using System.Collections.Concurrent;

namespace StreamExtended.Helpers
namespace StreamExtended
{
//TODO remote static
public static class BufferPool
/// <summary>
/// Use this interface to implement custom buffer pool.
/// To use the default buffer pool implementation use DefaultBufferPool class.
/// </summary>
public interface IBufferPool
{
private static readonly ConcurrentStack<byte[]> buffers = new ConcurrentStack<byte[]>();
byte[] GetBuffer(int bufferSize);
void ReturnBuffer(byte[] buffer);
}


/// <summary>
/// A concrete IBufferPool implementation using concurrent stack.
/// Works well for fixed buffer sizes, where if size does change then it would be global for all applications using this pool.
/// If your application would use variable size buffers consider implementing IBufferPool using System.Buffers from Microsoft.
/// </summary>
public class DefaultBufferPool : IBufferPool
{
private readonly ConcurrentStack<byte[]> buffers = new ConcurrentStack<byte[]>();

/// <summary>
/// Gets a buffer.
/// </summary>
/// <param name="bufferSize">Size of the buffer.</param>
/// <returns></returns>
public static byte[] GetBuffer(int bufferSize)
public byte[] GetBuffer(int bufferSize)
{
if (!buffers.TryPop(out var buffer) || buffer.Length != bufferSize)
{
Expand All @@ -26,7 +41,7 @@ public static byte[] GetBuffer(int bufferSize)
/// Returns the buffer.
/// </summary>
/// <param name="buffer">The buffer.</param>
public static void ReturnBuffer(byte[] buffer)
public void ReturnBuffer(byte[] buffer)
{
if (buffer != null)
{
Expand Down
5 changes: 3 additions & 2 deletions StreamExtended/Network/ClientHelloAlpnAdderStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ namespace StreamExtended.Network
public class ClientHelloAlpnAdderStream : Stream
{
private readonly CustomBufferedStream stream;
private readonly IBufferPool bufferPool;

private bool called;

public ClientHelloAlpnAdderStream(CustomBufferedStream stream)
public ClientHelloAlpnAdderStream(CustomBufferedStream stream, IBufferPool bufferPool)
{
this.stream = stream;
}
Expand Down Expand Up @@ -49,7 +50,7 @@ public override void Write(byte[] buffer, int offset, int count)

//this can be non async, because reads from a memory stream
var cts = new CancellationTokenSource();
var clientHello = SslTools.PeekClientHello(new CustomBufferedStream(ms, (int)ms.Length), cts.Token).Result;
var clientHello = SslTools.PeekClientHello(new CustomBufferedStream(ms, bufferPool, (int)ms.Length), bufferPool, cts.Token).Result;
if (clientHello != null)
{
// 0x00 0x10: ALPN identifier
Expand Down
11 changes: 6 additions & 5 deletions StreamExtended/Network/CopyStream.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using StreamExtended.Helpers;

namespace StreamExtended.Network
{
Expand All @@ -11,6 +10,8 @@ public class CopyStream : ICustomStreamReader, IDisposable

private readonly ICustomStreamWriter writer;

private readonly IBufferPool bufferPool;

public int BufferSize { get; }

private int bufferLength;
Expand All @@ -25,12 +26,12 @@ public class CopyStream : ICustomStreamReader, IDisposable

public long ReadBytes { get; private set; }

public CopyStream(ICustomStreamReader reader, ICustomStreamWriter writer, int bufferSize)
public CopyStream(ICustomStreamReader reader, ICustomStreamWriter writer, IBufferPool bufferPool, int bufferSize)
{
this.reader = reader;
this.writer = writer;
BufferSize = bufferSize;
buffer = BufferPool.GetBuffer(bufferSize);
buffer = bufferPool.GetBuffer(bufferSize);
}

public async Task<bool> FillBufferAsync(CancellationToken cancellationToken = default(CancellationToken))
Expand Down Expand Up @@ -117,7 +118,7 @@ public int Read(byte[] buffer, int offset, int count)

public Task<string> ReadLineAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return CustomBufferedStream.ReadLineInternalAsync(this, cancellationToken);
return CustomBufferedStream.ReadLineInternalAsync(this, bufferPool, cancellationToken);
}

public void Dispose()
Expand All @@ -127,7 +128,7 @@ public void Dispose()
disposed = true;
var buf = buffer;
buffer = null;
BufferPool.ReturnBuffer(buf);
bufferPool.ReturnBuffer(buf);
}
}
}
Expand Down
6 changes: 4 additions & 2 deletions StreamExtended/Network/CustomBufferedPeekStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ namespace StreamExtended.Network
{
public class CustomBufferedPeekStream : ICustomStreamReader
{
private readonly IBufferPool bufferPool;
private readonly ICustomStreamReader baseStream;

internal int Position { get; private set; }

internal CustomBufferedPeekStream(ICustomStreamReader baseStream, int startPosition = 0)
internal CustomBufferedPeekStream(ICustomStreamReader baseStream, IBufferPool bufferPool, int startPosition = 0)
{
this.bufferPool = bufferPool;
this.baseStream = baseStream;
Position = startPosition;
}
Expand Down Expand Up @@ -130,7 +132,7 @@ Task<int> ICustomStreamReader.ReadAsync(byte[] buffer, int offset, int count, Ca
/// <returns></returns>
Task<string> ICustomStreamReader.ReadLineAsync(CancellationToken cancellationToken)
{
return CustomBufferedStream.ReadLineInternalAsync(this, cancellationToken);
return CustomBufferedStream.ReadLineInternalAsync(this, bufferPool, cancellationToken);
}

}
Expand Down
26 changes: 14 additions & 12 deletions StreamExtended/Network/CustomBufferedStream.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using StreamExtended.Helpers;
using System;
using System.Collections.Generic;
using System;
using System.Diagnostics;
using System.IO;
using System.Text;
Expand Down Expand Up @@ -31,6 +29,8 @@ public class CustomBufferedStream : Stream, ICustomStreamReader

private bool closed;

private readonly IBufferPool bufferPool;

public int BufferSize { get; }

public event EventHandler<DataEventArgs> DataRead;
Expand All @@ -41,14 +41,16 @@ public class CustomBufferedStream : Stream, ICustomStreamReader
/// Initializes a new instance of the <see cref="CustomBufferedStream"/> class.
/// </summary>
/// <param name="baseStream">The base stream.</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>
public CustomBufferedStream(Stream baseStream, int bufferSize, bool leaveOpen = false)
public CustomBufferedStream(Stream baseStream, IBufferPool bufferPool, int bufferSize, bool leaveOpen = false)
{
this.baseStream = baseStream;
BufferSize = bufferSize;
this.leaveOpen = leaveOpen;
streamBuffer = BufferPool.GetBuffer(bufferSize);
streamBuffer = bufferPool.GetBuffer(bufferSize);
this.bufferPool = bufferPool;
}

/// <summary>
Expand Down Expand Up @@ -291,7 +293,7 @@ public byte ReadByteFromBuffer()
/// <param name="value">The byte to write to the stream.</param>
public override void WriteByte(byte value)
{
var buffer = BufferPool.GetBuffer(BufferSize);
var buffer = bufferPool.GetBuffer(BufferSize);
try
{
buffer[0] = value;
Expand All @@ -300,7 +302,7 @@ public override void WriteByte(byte value)
}
finally
{
BufferPool.ReturnBuffer(buffer);
bufferPool.ReturnBuffer(buffer);
}
}

Expand Down Expand Up @@ -331,7 +333,7 @@ protected override void Dispose(bool disposing)

var buffer = streamBuffer;
streamBuffer = null;
BufferPool.ReturnBuffer(buffer);
bufferPool.ReturnBuffer(buffer);
}
}

Expand Down Expand Up @@ -493,21 +495,21 @@ public bool FillBuffer()
/// <returns></returns>
public Task<string> ReadLineAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return ReadLineInternalAsync(this, cancellationToken);
return ReadLineInternalAsync(this, bufferPool, cancellationToken);
}

/// <summary>
/// Read a line from the byte stream
/// </summary>
/// <returns></returns>
internal static async Task<string> ReadLineInternalAsync(ICustomStreamReader reader, CancellationToken cancellationToken = default(CancellationToken))
internal static async Task<string> ReadLineInternalAsync(ICustomStreamReader reader, IBufferPool bufferPool, CancellationToken cancellationToken = default(CancellationToken))
{
byte lastChar = default(byte);

int bufferDataLength = 0;

// try to use buffer from the buffer pool, usually it is enough
var bufferPoolBuffer = BufferPool.GetBuffer(reader.BufferSize);
var bufferPoolBuffer = bufferPool.GetBuffer(reader.BufferSize);
var buffer = bufferPoolBuffer;

try
Expand Down Expand Up @@ -541,7 +543,7 @@ public bool FillBuffer()
}
finally
{
BufferPool.ReturnBuffer(bufferPoolBuffer);
bufferPool.ReturnBuffer(bufferPoolBuffer);
}

if (bufferDataLength == 0)
Expand Down
6 changes: 4 additions & 2 deletions StreamExtended/Network/ServerHelloAlpnAdderStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ namespace StreamExtended.Network
{
public class ServerHelloAlpnAdderStream : Stream
{
private readonly IBufferPool bufferPool;
private readonly CustomBufferedStream stream;

private bool called;

public ServerHelloAlpnAdderStream(CustomBufferedStream stream)
public ServerHelloAlpnAdderStream(CustomBufferedStream stream, IBufferPool bufferPool)
{
this.bufferPool = bufferPool;
this.stream = stream;
}

Expand Down Expand Up @@ -49,7 +51,7 @@ public override void Write(byte[] buffer, int offset, int count)

//this can be non async, because reads from a memory stream
var cts = new CancellationTokenSource();
var serverHello = SslTools.PeekServerHello(new CustomBufferedStream(ms, (int)ms.Length), cts.Token).Result;
var serverHello = SslTools.PeekServerHello(new CustomBufferedStream(ms, bufferPool, (int)ms.Length), bufferPool, cts.Token).Result;
if (serverHello != null)
{
// 0x00 0x10: ALPN identifier
Expand Down
Loading

0 comments on commit 169f3bc

Please sign in to comment.