Compare commits
2 commits
242982ff0b
...
57293135a2
Author | SHA1 | Date | |
---|---|---|---|
|
57293135a2 | ||
|
a0db75bfdd |
4 changed files with 40 additions and 17 deletions
|
@ -60,6 +60,11 @@ public sealed class HttpServer
|
|||
/// </summary>
|
||||
public TimeSpan Timeout = TimeSpan.FromSeconds(20);
|
||||
|
||||
/// <summary>
|
||||
/// The maximum time a websocket may be inactive before it is presumed dead and closed.
|
||||
/// </summary>
|
||||
public TimeSpan TimeoutWS = TimeSpan.FromSeconds(60);
|
||||
|
||||
readonly Dictionary<IPAddress, int> IPCounts = new Dictionary<IPAddress, int>();
|
||||
|
||||
readonly SemaphoreSlim IPCountsLock = new SemaphoreSlim(1, 1);
|
||||
|
@ -165,6 +170,9 @@ public sealed class HttpServer
|
|||
|
||||
if (response is SwitchingProtocols swp)
|
||||
{
|
||||
httpStream.Timeout = TimeoutWS;
|
||||
httpStream.KeepAlive();
|
||||
|
||||
//Create and run websocket
|
||||
WebsocketRemote ws = new WebsocketRemote(req, clientInfo, httpStream, swp.Fields.WebSocketProtocol);
|
||||
CloseStatus closeStatus = await swp.Callback(ws);
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
using System.Buffers;
|
||||
using System.Collections.Specialized;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
|
||||
namespace Uwaa.HTTP;
|
||||
|
||||
|
@ -28,19 +26,27 @@ class HttpStream : IDisposable
|
|||
/// </summary>
|
||||
public TimeSpan Timeout;
|
||||
|
||||
internal readonly CancellationTokenSource CancelSrc = new CancellationTokenSource();
|
||||
|
||||
public HttpStream(Stream stream, TimeSpan timeout) : base()
|
||||
{
|
||||
Stream = stream;
|
||||
Timeout = timeout;
|
||||
Buffer = new BufferedStream(stream);
|
||||
Decoder = Encoding.ASCII.GetDecoder();
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets the timeout timer.
|
||||
/// </summary>
|
||||
public void KeepAlive()
|
||||
{
|
||||
CancelSrc.CancelAfter(Timeout);
|
||||
}
|
||||
|
||||
public async ValueTask<string> ReadLine()
|
||||
{
|
||||
CancellationTokenSource cancelSrc = new CancellationTokenSource();
|
||||
cancelSrc.CancelAfter(Timeout);
|
||||
CancelSrc.CancelAfter(Timeout);
|
||||
|
||||
const int maxChars = 4096;
|
||||
byte[] dataBuffer = ArrayPool<byte>.Shared.Rent(1);
|
||||
|
@ -50,7 +56,7 @@ class HttpStream : IDisposable
|
|||
int charBufferIndex = 0;
|
||||
while (true)
|
||||
{
|
||||
if (await Buffer.ReadAsync(dataBuffer.AsMemory(0, 1), cancelSrc.Token) == 0)
|
||||
if (await Stream.ReadAsync(dataBuffer.AsMemory(0, 1), CancelSrc.Token) == 0)
|
||||
if (charBufferIndex == 0)
|
||||
throw new SocketException((int)SocketError.ConnectionReset);
|
||||
else
|
||||
|
@ -87,15 +93,14 @@ class HttpStream : IDisposable
|
|||
|
||||
public async ValueTask<int> Read(Memory<byte> buffer)
|
||||
{
|
||||
CancellationTokenSource cancelSrc = new CancellationTokenSource();
|
||||
cancelSrc.CancelAfter(Timeout);
|
||||
CancelSrc.CancelAfter(Timeout);
|
||||
|
||||
try
|
||||
{
|
||||
int index = 0;
|
||||
while (index < buffer.Length)
|
||||
{
|
||||
int count = await Buffer.ReadAsync(buffer[index..], cancelSrc.Token);
|
||||
int count = await Stream.ReadAsync(buffer[index..], CancelSrc.Token);
|
||||
if (count == 0)
|
||||
break;
|
||||
|
||||
|
@ -134,11 +139,10 @@ class HttpStream : IDisposable
|
|||
|
||||
public ValueTask Write(ReadOnlyMemory<byte> bytes)
|
||||
{
|
||||
CancellationTokenSource cancelSrc = new CancellationTokenSource();
|
||||
cancelSrc.CancelAfter(Timeout);
|
||||
CancelSrc.CancelAfter(Timeout);
|
||||
try
|
||||
{
|
||||
return Buffer.WriteAsync(bytes, cancelSrc.Token);
|
||||
return Buffer.WriteAsync(bytes, CancelSrc.Token);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
|
@ -151,12 +155,11 @@ class HttpStream : IDisposable
|
|||
|
||||
public async Task Flush()
|
||||
{
|
||||
CancellationTokenSource cancelSrc = new CancellationTokenSource();
|
||||
cancelSrc.CancelAfter(Timeout);
|
||||
CancelSrc.CancelAfter(Timeout);
|
||||
try
|
||||
{
|
||||
await Buffer.FlushAsync(cancelSrc.Token);
|
||||
await Stream.FlushAsync(cancelSrc.Token);
|
||||
await Buffer.FlushAsync(CancelSrc.Token);
|
||||
await Stream.FlushAsync(CancelSrc.Token);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
|
|
|
@ -12,5 +12,8 @@ public enum CloseStatus : ushort
|
|||
PolicyViolation = 1008,
|
||||
MessageTooBig = 1009,
|
||||
MandatoryExtension = 1010,
|
||||
InternalServerError = 1011
|
||||
InternalServerError = 1011,
|
||||
ServiceRestart = 1012,
|
||||
TryAgainLater = 1013,
|
||||
BadGateway = 1014,
|
||||
}
|
|
@ -14,6 +14,15 @@ public class Websocket
|
|||
/// </summary>
|
||||
public readonly string? SubProtocol;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum time the websocket may be inactive before it is presumed dead and closed.
|
||||
/// </summary>
|
||||
public TimeSpan Timeout
|
||||
{
|
||||
get => Stream.Timeout;
|
||||
set => Stream.Timeout = value;
|
||||
}
|
||||
|
||||
internal readonly HttpStream Stream;
|
||||
|
||||
readonly List<byte> finalPayload = new List<byte>();
|
||||
|
|
Loading…
Reference in a new issue