fix: Added CwsBaseHandler, refactored CwsDefaultRequestHandler

This commit is contained in:
jdevito
2023-01-18 13:30:27 -06:00
parent 1cbdc5aaef
commit e98aae2d89
6 changed files with 309 additions and 89 deletions

View File

@@ -0,0 +1,149 @@
using System;
using System.Collections.Generic;
using Crestron.SimplSharp.WebScripting;
using Newtonsoft.Json;
namespace PepperDash.Core
{
/// <summary>
/// CWS Base Handler, implements IHttpCwsHandler
/// </summary>
public abstract class CwsBaseHandler : IHttpCwsHandler
{
private readonly Dictionary<string, Action<HttpCwsContext>> _handlers;
/// <summary>
/// Constructor
/// </summary>
protected CwsBaseHandler()
{
_handlers = new Dictionary<string, Action<HttpCwsContext>>
{
{"CONNECT", HandleConnect},
{"DELETE", HandleDelete},
{"GET", HandleGet},
{"HEAD", HandleHead},
{"OPTIONS", HandleOptions},
{"PATCH", HandlePatch},
{"POST", HandlePost},
{"PUT", HandlePut},
{"TRACE", HandleTrace}
};
}
/// <summary>
/// Handles CONNECT method requests
/// </summary>
/// <param name="context"></param>
protected virtual void HandleConnect(HttpCwsContext context)
{
context.Response.StatusCode = 501;
context.Response.StatusDescription = "Not Implemented";
context.Response.End();
}
/// <summary>
/// Handles DELETE method requests
/// </summary>
/// <param name="context"></param>
protected virtual void HandleDelete(HttpCwsContext context)
{
context.Response.StatusCode = 501;
context.Response.StatusDescription = "Not Implemented";
context.Response.End();
}
/// <summary>
/// Handles GET method requests
/// </summary>
/// <param name="context"></param>
protected virtual void HandleGet(HttpCwsContext context)
{
context.Response.StatusCode = 501;
context.Response.StatusDescription = "Not Implemented";
context.Response.End();
}
/// <summary>
/// Handles HEAD method requests
/// </summary>
/// <param name="context"></param>
protected virtual void HandleHead(HttpCwsContext context)
{
context.Response.StatusCode = 501;
context.Response.StatusDescription = "Not Implemented";
context.Response.End();
}
/// <summary>
/// Handles OPTIONS method requests
/// </summary>
/// <param name="context"></param>
protected virtual void HandleOptions(HttpCwsContext context)
{
context.Response.StatusCode = 501;
context.Response.StatusDescription = "Not Implemented";
context.Response.End();
}
/// <summary>
/// Handles PATCH method requests
/// </summary>
/// <param name="context"></param>
protected virtual void HandlePatch(HttpCwsContext context)
{
context.Response.StatusCode = 501;
context.Response.StatusDescription = "Not Implemented";
context.Response.End();
}
/// <summary>
/// Handles POST method requests
/// </summary>
/// <param name="context"></param>
protected virtual void HandlePost(HttpCwsContext context)
{
context.Response.StatusCode = 501;
context.Response.StatusDescription = "Not Implemented";
context.Response.End();
}
/// <summary>
/// Handles PUT method requests
/// </summary>
/// <param name="context"></param>
protected virtual void HandlePut(HttpCwsContext context)
{
context.Response.StatusCode = 501;
context.Response.StatusDescription = "Not Implemented";
context.Response.End();
}
/// <summary>
/// Handles TRACE method requests
/// </summary>
/// <param name="context"></param>
protected virtual void HandleTrace(HttpCwsContext context)
{
context.Response.StatusCode = 501;
context.Response.StatusDescription = "Not Implemented";
context.Response.End();
}
/// <summary>
/// Process request
/// </summary>
/// <param name="context"></param>
public void ProcessRequest(HttpCwsContext context)
{
Action<HttpCwsContext> handler;
if (!_handlers.TryGetValue(context.Request.HttpMethod, out handler))
{
return;
}
handler(context);
}
}
}

View File

@@ -0,0 +1,106 @@
using Crestron.SimplSharp.WebScripting;
namespace PepperDash.Core
{
public class CwsDefaultRequestHandler : CwsBaseHandler
{
/// <summary>
/// Handles CONNECT method requests
/// </summary>
/// <param name="context"></param>
protected override void HandleConnect(HttpCwsContext context)
{
context.Response.StatusCode = 501;
context.Response.StatusDescription = "Not Implemented";
context.Response.End();
}
/// <summary>
/// Handles DELETE method requests
/// </summary>
/// <param name="context"></param>
protected override void HandleDelete(HttpCwsContext context)
{
context.Response.StatusCode = 501;
context.Response.StatusDescription = "Not Implemented";
context.Response.End();
}
/// <summary>
/// Handles GET method requests
/// </summary>
/// <param name="context"></param>
protected override void HandleGet(HttpCwsContext context)
{
context.Response.StatusCode = 501;
context.Response.StatusDescription = "Not Implemented";
context.Response.End();
}
/// <summary>
/// Handles HEAD method requests
/// </summary>
/// <param name="context"></param>
protected override void HandleHead(HttpCwsContext context)
{
context.Response.StatusCode = 501;
context.Response.StatusDescription = "Not Implemented";
context.Response.End();
}
/// <summary>
/// Handles OPTIONS method requests
/// </summary>
/// <param name="context"></param>
protected override void HandleOptions(HttpCwsContext context)
{
context.Response.StatusCode = 501;
context.Response.StatusDescription = "Not Implemented";
context.Response.End();
}
/// <summary>
/// Handles PATCH method requests
/// </summary>
/// <param name="context"></param>
protected override void HandlePatch(HttpCwsContext context)
{
context.Response.StatusCode = 501;
context.Response.StatusDescription = "Not Implemented";
context.Response.End();
}
/// <summary>
/// Handles POST method requests
/// </summary>
/// <param name="context"></param>
protected override void HandlePost(HttpCwsContext context)
{
context.Response.StatusCode = 501;
context.Response.StatusDescription = "Not Implemented";
context.Response.End();
}
/// <summary>
/// Handles PUT method requests
/// </summary>
/// <param name="context"></param>
protected override void HandlePut(HttpCwsContext context)
{
context.Response.StatusCode = 501;
context.Response.StatusDescription = "Not Implemented";
context.Response.End();
}
/// <summary>
/// Handles TRACE method requests
/// </summary>
/// <param name="context"></param>
protected override void HandleTrace(HttpCwsContext context)
{
context.Response.StatusCode = 501;
context.Response.StatusDescription = "Not Implemented";
context.Response.End();
}
}
}

View File

@@ -44,7 +44,6 @@ namespace PepperDash.Core
public GenericCwsBase(string key, string basePath) public GenericCwsBase(string key, string basePath)
: base(key) : base(key)
{ {
BasePath = string.IsNullOrEmpty(basePath) ? DefaultBasePath : basePath; BasePath = string.IsNullOrEmpty(basePath) ? DefaultBasePath : basePath;
} }
@@ -57,7 +56,6 @@ namespace PepperDash.Core
public GenericCwsBase(string key, string name, string basePath) public GenericCwsBase(string key, string name, string basePath)
: base(key, name) : base(key, name)
{ {
BasePath = string.IsNullOrEmpty(basePath) ? DefaultBasePath : basePath; BasePath = string.IsNullOrEmpty(basePath) ? DefaultBasePath : basePath;
} }
@@ -67,8 +65,7 @@ namespace PepperDash.Core
/// <param name="programEventType"></param> /// <param name="programEventType"></param>
void CrestronEnvironment_ProgramStatusEventHandler(eProgramStatusEventType programEventType) void CrestronEnvironment_ProgramStatusEventHandler(eProgramStatusEventType programEventType)
{ {
if (programEventType != eProgramStatusEventType.Stopping) if (programEventType != eProgramStatusEventType.Stopping) return;
return;
Debug.Console(DebugInfo, this, "Program stopping. Disabling Server"); Debug.Console(DebugInfo, this, "Program stopping. Disabling Server");
@@ -82,13 +79,15 @@ namespace PepperDash.Core
void CrestronEnvironment_EthernetEventHandler(EthernetEventArgs ethernetEventArgs) void CrestronEnvironment_EthernetEventHandler(EthernetEventArgs ethernetEventArgs)
{ {
// Re-enable the server if the link comes back up and the status should be connected // Re-enable the server if the link comes back up and the status should be connected
if (ethernetEventArgs.EthernetEventType == eEthernetEventType.LinkUp if (ethernetEventArgs.EthernetEventType == eEthernetEventType.LinkUp && IsRegistered)
&& IsRegistered)
{ {
Debug.Console(DebugInfo, this, "Ethernet link up. Starting server"); Debug.Console(DebugInfo, this, "Ethernet link up. Server is alreedy registered.");
return;
Start();
} }
Debug.Console(DebugInfo, this, "Ethernet link up. Starting server");
Start();
} }
/// <summary> /// <summary>
@@ -97,7 +96,37 @@ namespace PepperDash.Core
public void Initialize(string key, string basePath) public void Initialize(string key, string basePath)
{ {
Key = key; Key = key;
BasePath = string.IsNullOrEmpty(basePath) ? DefaultBasePath : basePath; BasePath = string.IsNullOrEmpty(basePath) ? DefaultBasePath : basePath;
}
/// <summary>
/// Adds a route to CWS
/// </summary>
public void AddRoute(HttpCwsRoute route)
{
if (route == null)
{
Debug.Console(DebugInfo, this, "Failed to add route, route parameter is null");
return;
}
_server.Routes.Add(route);
}
/// <summary>
/// Removes a route from CWS
/// </summary>
/// <param name="route"></param>
public void RemoveRoute(HttpCwsRoute route)
{
if (route == null)
{
Debug.Console(DebugInfo, this, "Failed to remote route, orute parameter is null");
return;
}
_server.Routes.Remove(route);
} }
/// <summary> /// <summary>
@@ -119,7 +148,7 @@ namespace PepperDash.Core
_server = new HttpCwsServer(BasePath) _server = new HttpCwsServer(BasePath)
{ {
HttpRequestHandler = new RequestHandlerUnknown() HttpRequestHandler = new CwsDefaultRequestHandler()
}; };
IsRegistered = _server.Register(); IsRegistered = _server.Register();
@@ -148,29 +177,26 @@ namespace PepperDash.Core
if (_server == null) if (_server == null)
{ {
Debug.Console(DebugInfo, this, "Servier has already been stopped"); Debug.Console(DebugInfo, this, "Server has already been stopped");
return; return;
} }
if (_server.Unregister()) IsRegistered = _server.Unregister() == false;
{ _server.Dispose();
IsRegistered = false; _server = null;
}
Dispose(true);
} }
catch (Exception ex) catch (Exception ex)
{ {
Debug.Console(DebugInfo, this, "ServerStop Exception Message: {0}", ex.Message); Debug.Console(DebugInfo, this, "Server Stop Exception Message: {0}", ex.Message);
Debug.Console(DebugVerbose, this, "ServerStop Exception StackTrace: {0}", ex.StackTrace); Debug.Console(DebugVerbose, this, "Server Stop Exception StackTrace: {0}", ex.StackTrace);
if (ex.InnerException != null) if (ex.InnerException != null)
Debug.Console(DebugVerbose, this, "ServerStop Exception InnerException: {0}", ex.InnerException); Debug.Console(DebugVerbose, this, "Server Stop Exception InnerException: {0}", ex.InnerException);
} }
finally finally
{ {
_serverLock.Leave(); _serverLock.Leave();
} }
} }
/// <summary> /// <summary>
/// Received request handler /// Received request handler
@@ -184,7 +210,6 @@ namespace PepperDash.Core
{ {
try try
{ {
// TODO [ ] Add logic for received requests
Debug.Console(DebugInfo, this, @"RecieveRequestEventHandler Debug.Console(DebugInfo, this, @"RecieveRequestEventHandler
Method: {0} Method: {0}
Path: {1} Path: {1}
@@ -206,7 +231,6 @@ UserHostName: {9}",
args.Context.Request.UserAgent, args.Context.Request.UserAgent,
args.Context.Request.UserHostAddress, args.Context.Request.UserHostAddress,
args.Context.Request.UserHostName); args.Context.Request.UserHostName);
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -215,52 +239,6 @@ UserHostName: {9}",
if (ex.InnerException != null) if (ex.InnerException != null)
Debug.Console(DebugVerbose, this, "ReceivedRequestEventHandler Exception InnerException: {0}", ex.InnerException); Debug.Console(DebugVerbose, this, "ReceivedRequestEventHandler Exception InnerException: {0}", ex.InnerException);
} }
} }
/// <summary>
/// Tracks if CWS is disposed
/// </summary>
public bool Disposed
{
get
{
return (_server == null);
}
}
/// <summary>
/// Disposes CWS instance
/// </summary>
public void Dispose()
{
Dispose(true);
CrestronEnvironment.GC.SuppressFinalize(this);
}
/// <summary>
/// Disposes CWS instance
/// </summary>
/// <param name="disposing"></param>
protected void Dispose(bool disposing)
{
if (Disposed)
{
Debug.Console(DebugInfo, this, "Server has already been disposed");
return;
}
if (!disposing) return;
if (_server != null)
{
_server.Dispose();
_server = null;
}
}
~GenericCwsBase()
{
Dispose(true);
}
} }
} }

View File

@@ -1,16 +0,0 @@
using Crestron.SimplSharp.WebScripting;
namespace PepperDash.Core
{
public class RequestHandlerUnknown : IHttpCwsHandler
{
public void ProcessRequest(HttpCwsContext context)
{
// TODO [ ] Modify unknown request handler
context.Response.StatusCode = 418;
context.Response.StatusDescription = "I'm a teapot";
context.Response.ContentType = "application/json";
context.Response.Write(string.Format("{0} {1}", context.Request.HttpMethod, context.Request.RawUrl), true);
}
}
}

View File

@@ -7,7 +7,7 @@
<ProjectGuid>{87E29B4C-569B-4368-A4ED-984AC1440C96}</ProjectGuid> <ProjectGuid>{87E29B4C-569B-4368-A4ED-984AC1440C96}</ProjectGuid>
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>PepperDash_Core</RootNamespace> <RootNamespace>PepperDash.Core</RootNamespace>
<AssemblyName>PepperDash_Core</AssemblyName> <AssemblyName>PepperDash_Core</AssemblyName>
<ProjectTypeGuids>{0B4745B0-194B-4BB6-8E21-E9057CA92500};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> <ProjectTypeGuids>{0B4745B0-194B-4BB6-8E21-E9057CA92500};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<PlatformFamilyName>WindowsCE</PlatformFamilyName> <PlatformFamilyName>WindowsCE</PlatformFamilyName>
@@ -93,8 +93,9 @@
<Compile Include="Comm\TcpServerConfigObject.cs" /> <Compile Include="Comm\TcpServerConfigObject.cs" />
<Compile Include="Config\PortalConfigReader.cs" /> <Compile Include="Config\PortalConfigReader.cs" />
<Compile Include="CoreInterfaces.cs" /> <Compile Include="CoreInterfaces.cs" />
<Compile Include="CrestronWebServer\CwsBaseHandler.cs" />
<Compile Include="CrestronWebServer\GenericCwsBase.cs" /> <Compile Include="CrestronWebServer\GenericCwsBase.cs" />
<Compile Include="CrestronWebServer\RequestHandlerUnknown.cs" /> <Compile Include="CrestronWebServer\CwsDefaultRequestHandler.cs" />
<Compile Include="EventArgs.cs" /> <Compile Include="EventArgs.cs" />
<Compile Include="GenericRESTfulCommunications\Constants.cs" /> <Compile Include="GenericRESTfulCommunications\Constants.cs" />
<Compile Include="GenericRESTfulCommunications\GenericRESTfulClient.cs" /> <Compile Include="GenericRESTfulCommunications\GenericRESTfulClient.cs" />

View File

@@ -0,0 +1,2 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=CrestronWebServer/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>