mirror of
https://github.com/AlexMacocian/MTSC.git
synced 2026-07-15 14:59:33 +00:00
Configurable return 500 on exception in http handlers.
Configurable websocket hearbeat. Nit fixes.
This commit is contained in:
@@ -43,8 +43,12 @@ namespace MTSC.UnitTests
|
||||
.AddHandler(new WebsocketRoutingHandler()
|
||||
.AddRoute<EchoWebsocketModule>("echo")
|
||||
.AddRoute<EchoWebsocketModule2>("echo2")
|
||||
.AddRoute<RoutingModules.HelloWorldModule>("hello-world"))
|
||||
.AddRoute<RoutingModules.HelloWorldModule>("hello-world")
|
||||
.WithHeartbeatEnabled(true)
|
||||
.WithHeartbeatFrequency(TimeSpan.FromMilliseconds(100)))
|
||||
.AddHandler(new HttpRoutingHandler()
|
||||
.WithReturn500OnException(true)
|
||||
.AddRoute<ExceptionThrowingModule>(HttpMessage.HttpMethods.Get, "throw")
|
||||
.AddRoute<Http200Module>(HttpMessage.HttpMethods.Get, "")
|
||||
.AddRoute<TestQueryModule>(HttpMessage.HttpMethods.Get, "query")
|
||||
.AddRoute<EchoModule>(HttpMessage.HttpMethods.Post, "echo")
|
||||
@@ -60,6 +64,16 @@ namespace MTSC.UnitTests
|
||||
.WithSslAuthenticationTimeout(TimeSpan.FromMilliseconds(100));
|
||||
Server.RunAsync();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task ServerReturns500OnError()
|
||||
{
|
||||
HttpClient httpClient = new HttpClient();
|
||||
httpClient.BaseAddress = new Uri("http://localhost:800");
|
||||
var response = await httpClient.GetAsync("throw");
|
||||
Assert.AreEqual(response.StatusCode, HttpStatusCode.InternalServerError);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task ServerParsesRequestAndResponse()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
using MTSC.Common.Http;
|
||||
using MTSC.Common.Http.RoutingModules;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MTSC.UnitTests.RoutingModules
|
||||
{
|
||||
public class ExceptionThrowingModule : HttpRouteBase
|
||||
{
|
||||
public override Task<HttpResponse> HandleRequest(HttpRequest request)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,13 +8,32 @@ namespace MTSC.Common.Http.RoutingModules
|
||||
{
|
||||
public abstract class HttpRouteBase : ISetHttpContext
|
||||
{
|
||||
private static HttpResponse InternalServerError500 { get; } =
|
||||
new HttpResponse
|
||||
{
|
||||
StatusCode = HttpMessage.StatusCodes.InternalServerError,
|
||||
BodyString = "An exception ocurred while processing the request"
|
||||
};
|
||||
|
||||
public ClientData ClientData { get; private set; }
|
||||
public HttpRoutingHandler HttpRoutingHandler { get; private set; }
|
||||
public Server Server { get; private set; }
|
||||
|
||||
public async Task<HttpResponse> CallHandleRequest(HttpRequest request)
|
||||
{
|
||||
return await this.HandleRequest(request);
|
||||
try
|
||||
{
|
||||
return await this.HandleRequest(request);
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (this.HttpRoutingHandler.Return500OnException is true)
|
||||
{
|
||||
return InternalServerError500;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
public abstract Task<HttpResponse> HandleRequest(HttpRequest request);
|
||||
|
||||
|
||||
@@ -8,23 +8,22 @@ namespace MTSC.Common
|
||||
{
|
||||
public class TimeoutSuppressedStream : Stream
|
||||
{
|
||||
NetworkStream innerStream;
|
||||
private readonly NetworkStream innerStream;
|
||||
|
||||
public TimeoutSuppressedStream(TcpClient tcpClient)
|
||||
{
|
||||
innerStream = tcpClient.GetStream();
|
||||
this.innerStream = tcpClient.GetStream();
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
try
|
||||
{
|
||||
return innerStream.Read(buffer, offset, count);
|
||||
return this.innerStream.Read(buffer, offset, count);
|
||||
}
|
||||
catch (IOException lException)
|
||||
{
|
||||
SocketException lInnerException = lException.InnerException as SocketException;
|
||||
if (lInnerException != null && lInnerException.SocketErrorCode == SocketError.TimedOut)
|
||||
if (lException.InnerException is SocketException lInnerException && lInnerException.SocketErrorCode == SocketError.TimedOut)
|
||||
{
|
||||
// Normally, a simple TimeOut on the read will cause SslStream to flip its lid
|
||||
// However, if we suppress the IOException and just return 0 bytes read, this is ok.
|
||||
@@ -37,38 +36,38 @@ namespace MTSC.Common
|
||||
}
|
||||
|
||||
|
||||
public override bool CanRead => innerStream.CanRead;
|
||||
public override bool CanSeek => innerStream.CanSeek;
|
||||
public override bool CanTimeout => innerStream.CanTimeout;
|
||||
public override bool CanWrite => innerStream.CanWrite;
|
||||
public virtual bool DataAvailable => innerStream.DataAvailable;
|
||||
public override long Length => innerStream.Length;
|
||||
public override IAsyncResult BeginRead(byte[] buffer, int offset, int size, AsyncCallback callback, object state) => innerStream.BeginRead(buffer, offset, size, callback, state);
|
||||
public override IAsyncResult BeginWrite(byte[] buffer, int offset, int size, AsyncCallback callback, object state) => innerStream.BeginWrite(buffer, offset, size, callback, state);
|
||||
public override int EndRead(IAsyncResult asyncResult) => innerStream.EndRead(asyncResult);
|
||||
public override void EndWrite(IAsyncResult asyncResult) => innerStream.EndWrite(asyncResult);
|
||||
public override void Flush() => innerStream.Flush();
|
||||
public override Task FlushAsync(CancellationToken cancellationToken) => innerStream.FlushAsync(cancellationToken);
|
||||
public override long Seek(long offset, SeekOrigin origin) => innerStream.Seek(offset, origin);
|
||||
public override void SetLength(long value) => innerStream.SetLength(value);
|
||||
public override void Write(byte[] buffer, int offset, int count) => innerStream.Write(buffer, offset, count);
|
||||
public override bool CanRead => this.innerStream.CanRead;
|
||||
public override bool CanSeek => this.innerStream.CanSeek;
|
||||
public override bool CanTimeout => this.innerStream.CanTimeout;
|
||||
public override bool CanWrite => this.innerStream.CanWrite;
|
||||
public virtual bool DataAvailable => this.innerStream.DataAvailable;
|
||||
public override long Length => this.innerStream.Length;
|
||||
public override IAsyncResult BeginRead(byte[] buffer, int offset, int size, AsyncCallback callback, object state) => this.innerStream.BeginRead(buffer, offset, size, callback, state);
|
||||
public override IAsyncResult BeginWrite(byte[] buffer, int offset, int size, AsyncCallback callback, object state) => this.innerStream.BeginWrite(buffer, offset, size, callback, state);
|
||||
public override int EndRead(IAsyncResult asyncResult) => this.innerStream.EndRead(asyncResult);
|
||||
public override void EndWrite(IAsyncResult asyncResult) => this.innerStream.EndWrite(asyncResult);
|
||||
public override void Flush() => this.innerStream.Flush();
|
||||
public override Task FlushAsync(CancellationToken cancellationToken) => this.innerStream.FlushAsync(cancellationToken);
|
||||
public override long Seek(long offset, SeekOrigin origin) => this.innerStream.Seek(offset, origin);
|
||||
public override void SetLength(long value) => this.innerStream.SetLength(value);
|
||||
public override void Write(byte[] buffer, int offset, int count) => this.innerStream.Write(buffer, offset, count);
|
||||
|
||||
public override long Position
|
||||
{
|
||||
get { return innerStream.Position; }
|
||||
set { innerStream.Position = value; }
|
||||
get { return this.innerStream.Position; }
|
||||
set { this.innerStream.Position = value; }
|
||||
}
|
||||
|
||||
public override int ReadTimeout
|
||||
{
|
||||
get { return innerStream.ReadTimeout; }
|
||||
set { innerStream.ReadTimeout = value; }
|
||||
get { return this.innerStream.ReadTimeout; }
|
||||
set { this.innerStream.ReadTimeout = value; }
|
||||
}
|
||||
|
||||
public override int WriteTimeout
|
||||
{
|
||||
get { return innerStream.WriteTimeout; }
|
||||
set { innerStream.WriteTimeout = value; }
|
||||
get { return this.innerStream.WriteTimeout; }
|
||||
set { this.innerStream.WriteTimeout = value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -5,13 +5,13 @@
|
||||
<TargetFrameworks>netcoreapp2.1;net48;netstandard2.0;netcoreapp3.1;net5.0</TargetFrameworks>
|
||||
<ApplicationIcon />
|
||||
<StartupObject />
|
||||
<Version>3.2.3</Version>
|
||||
<Version>3.3</Version>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Authors>Alexandru-Victor Macocian</Authors>
|
||||
<Product>MTSC</Product>
|
||||
<Description>Modular TCP Server and Client</Description>
|
||||
<AssemblyVersion>0.3.2.3</AssemblyVersion>
|
||||
<FileVersion>0.3.2.3</FileVersion>
|
||||
<AssemblyVersion>3.3.0.0</AssemblyVersion>
|
||||
<FileVersion>3.3.0.0</FileVersion>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<PackageProjectUrl>https://github.com/AlexMacocian/MTSC</PackageProjectUrl>
|
||||
|
||||
@@ -14,14 +14,13 @@ namespace MTSC.ServerSide.Handlers
|
||||
/// </summary>
|
||||
public sealed class HttpHandler : IHandler
|
||||
{
|
||||
private static readonly string urlEncodedHeader = "application/x-www-form-urlencoded";
|
||||
private static readonly string multipartHeader = "multipart/form-data";
|
||||
#region Fields
|
||||
private List<IHttpLogger> httpLoggers = new List<IHttpLogger>();
|
||||
private List<IHttpModule> httpModules = new List<IHttpModule>();
|
||||
private ConcurrentQueue<Tuple<ClientData, HttpResponse>> messageOutQueue = new ConcurrentQueue<Tuple<ClientData, HttpResponse>>();
|
||||
private readonly List<IHttpLogger> httpLoggers = new();
|
||||
private readonly List<IHttpModule> httpModules = new();
|
||||
private readonly ConcurrentQueue<Tuple<ClientData, HttpResponse>> messageOutQueue = new();
|
||||
#endregion
|
||||
#region Public Properties
|
||||
public bool Return500OnException { get; set; } = true;
|
||||
public TimeSpan FragmentsExpirationTime { get; set; } = TimeSpan.FromSeconds(15);
|
||||
public double MaximumRequestSize { get; set; } = 15000;
|
||||
#endregion
|
||||
@@ -42,6 +41,11 @@ namespace MTSC.ServerSide.Handlers
|
||||
this.MaximumRequestSize = size;
|
||||
return this;
|
||||
}
|
||||
public HttpHandler WithReturn500OnException(bool return500OnException)
|
||||
{
|
||||
this.Return500OnException = return500OnException;
|
||||
return this;
|
||||
}
|
||||
/// <summary>
|
||||
/// The amount of time fragments are kept in the buffer before being discarded.
|
||||
/// </summary>
|
||||
@@ -180,7 +184,7 @@ namespace MTSC.ServerSide.Handlers
|
||||
client.Resources.RemoveResource<FragmentedMessage>();
|
||||
}
|
||||
|
||||
HttpResponse response = new HttpResponse();
|
||||
HttpResponse response = new();
|
||||
if (request.Headers.ContainsHeader(HttpMessage.GeneralHeaders.Connection) &&
|
||||
request.Headers[HttpMessage.GeneralHeaders.Connection].ToLower() == "close")
|
||||
{
|
||||
@@ -194,13 +198,27 @@ namespace MTSC.ServerSide.Handlers
|
||||
foreach (var httpLogger in this.httpLoggers) httpLogger.LogRequest(server, this, client, request);
|
||||
foreach (IHttpModule module in httpModules)
|
||||
{
|
||||
if (module.HandleRequest(server, this, client, request, ref response))
|
||||
try
|
||||
{
|
||||
break;
|
||||
if (module.HandleRequest(server, this, client, request, ref response))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (this.Return500OnException)
|
||||
{
|
||||
response.StatusCode = StatusCodes.InternalServerError;
|
||||
response.BodyString = "An exception ocurred while processing the request";
|
||||
break;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
foreach (var httpLogger in this.httpLoggers) httpLogger.LogResponse(server, this, client, response);
|
||||
QueueResponse(client, response);
|
||||
this.QueueResponse(client, response);
|
||||
return true;
|
||||
}
|
||||
/// <summary>
|
||||
|
||||
@@ -12,14 +12,13 @@ namespace MTSC.ServerSide.Handlers
|
||||
{
|
||||
private static readonly Func<Server, HttpRequest, ClientData, RouteEnablerResponse> alwaysEnabled = (server, request, client) => RouteEnablerResponse.Accept;
|
||||
private readonly ConcurrentQueue<Tuple<ClientData, HttpResponse>> messageOutQueue = new ConcurrentQueue<Tuple<ClientData, HttpResponse>>();
|
||||
private readonly List<IHttpLogger> httpLoggers = new List<IHttpLogger>();
|
||||
private readonly List<IHttpLogger> httpLoggers = new();
|
||||
private readonly Dictionary<HttpMethods, Dictionary<string, (Type,
|
||||
Func<Server, HttpRequest, ClientData, RouteEnablerResponse>)>> moduleDictionary =
|
||||
new Dictionary<HttpMethods, Dictionary<string, (Type,
|
||||
Func<Server, HttpRequest, ClientData, RouteEnablerResponse>)>>();
|
||||
Func<Server, HttpRequest, ClientData, RouteEnablerResponse>)>> moduleDictionary = new();
|
||||
|
||||
public TimeSpan FragmentsExpirationTime { get; set; } = TimeSpan.FromSeconds(15);
|
||||
public double MaximumRequestSize { get; set; } = double.MaxValue;
|
||||
public bool Return500OnException { get; set; } = true;
|
||||
|
||||
public HttpRoutingHandler()
|
||||
{
|
||||
@@ -30,6 +29,11 @@ namespace MTSC.ServerSide.Handlers
|
||||
}
|
||||
}
|
||||
|
||||
public HttpRoutingHandler WithReturn500OnException(bool return500OnException)
|
||||
{
|
||||
this.Return500OnException = return500OnException;
|
||||
return this;
|
||||
}
|
||||
public HttpRoutingHandler AddHttpLogger(IHttpLogger logger)
|
||||
{
|
||||
this.httpLoggers.Add(logger);
|
||||
|
||||
@@ -28,11 +28,28 @@ namespace MTSC.ServerSide.Handlers
|
||||
Closed
|
||||
}
|
||||
#region Fields
|
||||
private byte[] emptyData = new byte[0];
|
||||
private DateTime ellapsedTime = DateTime.Now;
|
||||
private DateTime previousHeartbeatProc = DateTime.Now;
|
||||
private readonly Dictionary<string, (Type, Func<Server, HttpRequest, ClientData, RouteEnablerResponse>)> moduleDictionary =
|
||||
new Dictionary<string, (Type, Func<Server, HttpRequest, ClientData, RouteEnablerResponse>)>();
|
||||
private readonly ConcurrentQueue<Tuple<ClientData, WebsocketMessage>> messageQueue = new ConcurrentQueue<Tuple<ClientData, WebsocketMessage>>();
|
||||
#endregion
|
||||
#region Properties
|
||||
public bool HeartbeatEnabled { get; set; }
|
||||
public TimeSpan HeartbeatFrequency { get; set; }
|
||||
#endregion
|
||||
#region Public Methods
|
||||
public WebsocketRoutingHandler WithHeartbeatFrequency(TimeSpan heartbeatFrequency)
|
||||
{
|
||||
this.HeartbeatFrequency = heartbeatFrequency;
|
||||
return this;
|
||||
}
|
||||
public WebsocketRoutingHandler WithHeartbeatEnabled(bool heartbeatEnabled)
|
||||
{
|
||||
this.HeartbeatEnabled = heartbeatEnabled;
|
||||
return this;
|
||||
}
|
||||
public WebsocketRoutingHandler AddRoute<T>(string uri)
|
||||
where T : WebsocketRouteBase
|
||||
{
|
||||
@@ -212,6 +229,11 @@ namespace MTSC.ServerSide.Handlers
|
||||
this.QueueMessage(client, new byte[0] ,WebsocketMessage.Opcodes.Pong);
|
||||
return true;
|
||||
}
|
||||
else if (receivedMessage.Opcode == WebsocketMessage.Opcodes.Pong)
|
||||
{
|
||||
// According to https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers, ignore unrequested pings.
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
@@ -244,11 +266,18 @@ namespace MTSC.ServerSide.Handlers
|
||||
|
||||
void IHandler.Tick(Server server)
|
||||
{
|
||||
this.ellapsedTime = DateTime.Now;
|
||||
foreach(var client in server.Clients)
|
||||
{
|
||||
if (client.Resources.TryGetResource<WebsocketRouteBase>(out var route))
|
||||
{
|
||||
route.Tick();
|
||||
if (this.HeartbeatEnabled is true &&
|
||||
(this.ellapsedTime - this.previousHeartbeatProc) > this.HeartbeatFrequency)
|
||||
{
|
||||
this.previousHeartbeatProc = DateTime.Now;
|
||||
this.QueueMessage(client, emptyData, WebsocketMessage.Opcodes.Ping);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+30
-86
@@ -28,14 +28,14 @@ namespace MTSC.ServerSide
|
||||
private bool running;
|
||||
private X509Certificate2 certificate;
|
||||
private TcpListener listener;
|
||||
private readonly ProducerConsumerQueue<ClientData> addQueue = new ProducerConsumerQueue<ClientData>();
|
||||
private readonly List<ClientData> clients = new List<ClientData>();
|
||||
private readonly List<ClientData> toRemove = new List<ClientData>();
|
||||
private readonly List<IHandler> handlers = new List<IHandler>();
|
||||
private readonly List<ILogger> loggers = new List<ILogger>();
|
||||
private readonly List<IExceptionHandler> exceptionHandlers = new List<IExceptionHandler>();
|
||||
private readonly List<IServerUsageMonitor> serverUsageMonitors = new List<IServerUsageMonitor>();
|
||||
private readonly ProducerConsumerQueue<(ClientData, byte[])> messageOutQueue = new ProducerConsumerQueue<(ClientData, byte[])>();
|
||||
private readonly ProducerConsumerQueue<ClientData> addQueue = new();
|
||||
private readonly List<ClientData> clients = new();
|
||||
private readonly List<ClientData> toRemove = new();
|
||||
private readonly List<IHandler> handlers = new();
|
||||
private readonly List<ILogger> loggers = new();
|
||||
private readonly List<IExceptionHandler> exceptionHandlers = new();
|
||||
private readonly List<IServerUsageMonitor> serverUsageMonitors = new();
|
||||
private readonly ProducerConsumerQueue<(ClientData, byte[])> messageOutQueue = new();
|
||||
private readonly IServiceManager serviceManager = new ServiceManager();
|
||||
#endregion
|
||||
#region Private Properties
|
||||
@@ -540,13 +540,7 @@ namespace MTSC.ServerSide
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
foreach (IExceptionHandler exceptionHandler in this.exceptionHandlers)
|
||||
{
|
||||
if (exceptionHandler.HandleException(e))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.HandleException(e);
|
||||
}
|
||||
/*
|
||||
* Check and gather messages from clients and place them in their queues.
|
||||
@@ -567,13 +561,7 @@ namespace MTSC.ServerSide
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
foreach (IExceptionHandler exceptionHandler in this.exceptionHandlers)
|
||||
{
|
||||
if (exceptionHandler.HandleException(e))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.HandleException(e);
|
||||
}
|
||||
/*
|
||||
* Add all accepted clients to the list
|
||||
@@ -626,13 +614,7 @@ namespace MTSC.ServerSide
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
foreach (IExceptionHandler exceptionHandler in this.exceptionHandlers)
|
||||
{
|
||||
if (exceptionHandler.HandleException(e))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.HandleException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -700,13 +682,7 @@ namespace MTSC.ServerSide
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
foreach (IExceptionHandler exceptionHandler in this.exceptionHandlers)
|
||||
{
|
||||
if (exceptionHandler.HandleException(e))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.HandleException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -732,13 +708,7 @@ namespace MTSC.ServerSide
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
foreach (IExceptionHandler exceptionHandler in this.exceptionHandlers)
|
||||
{
|
||||
if (exceptionHandler.HandleException(e))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.HandleException(e);
|
||||
}
|
||||
this.clients.Remove(client);
|
||||
}
|
||||
@@ -752,13 +722,7 @@ namespace MTSC.ServerSide
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
foreach (IExceptionHandler exceptionHandler in this.exceptionHandlers)
|
||||
{
|
||||
if (exceptionHandler.HandleException(e))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.HandleException(e);
|
||||
}
|
||||
}
|
||||
private void CheckAndGatherMessages()
|
||||
@@ -819,13 +783,7 @@ namespace MTSC.ServerSide
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
foreach (IExceptionHandler exceptionHandler in this.exceptionHandlers)
|
||||
{
|
||||
if (exceptionHandler.HandleException(e))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.HandleException(e);
|
||||
}
|
||||
try
|
||||
{
|
||||
@@ -833,13 +791,7 @@ namespace MTSC.ServerSide
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
foreach (IExceptionHandler exceptionHandler in this.exceptionHandlers)
|
||||
{
|
||||
if (exceptionHandler.HandleException(e))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.HandleException(e);
|
||||
}
|
||||
}
|
||||
private void HandleClientMessage(ClientData client, Message message)
|
||||
@@ -855,13 +807,7 @@ namespace MTSC.ServerSide
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
foreach (IExceptionHandler exceptionHandler in this.exceptionHandlers)
|
||||
{
|
||||
if (exceptionHandler.HandleException(e))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.HandleException(e);
|
||||
}
|
||||
}
|
||||
foreach (IHandler handler in this.handlers)
|
||||
@@ -875,13 +821,7 @@ namespace MTSC.ServerSide
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
foreach (IExceptionHandler exceptionHandler in this.exceptionHandlers)
|
||||
{
|
||||
if (exceptionHandler.HandleException(e))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.HandleException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -891,7 +831,7 @@ namespace MTSC.ServerSide
|
||||
{
|
||||
if (this.certificate != null)
|
||||
{
|
||||
SslStream sslStream = new SslStream(client.SafeNetworkStream,
|
||||
SslStream sslStream = new(client.SafeNetworkStream,
|
||||
false,
|
||||
this.RemoteCertificateValidationCallback,
|
||||
this.LocalCertificateSelectionCallback,
|
||||
@@ -917,16 +857,20 @@ namespace MTSC.ServerSide
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
foreach (IExceptionHandler exceptionHandler in this.exceptionHandlers)
|
||||
{
|
||||
if (exceptionHandler.HandleException(e))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.HandleException(e);
|
||||
client.Dispose();
|
||||
}
|
||||
}
|
||||
private void HandleException(Exception exception)
|
||||
{
|
||||
foreach (IExceptionHandler exceptionHandler in this.exceptionHandlers)
|
||||
{
|
||||
if (exceptionHandler.HandleException(exception))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user