Skip to content

Commit

Permalink
Initial working version of plugins per resource.
Browse files Browse the repository at this point in the history
  • Loading branch information
slav-at-attachix committed Jul 21, 2021
1 parent ab4b901 commit 057bb13
Show file tree
Hide file tree
Showing 11 changed files with 210 additions and 155 deletions.
47 changes: 26 additions & 21 deletions Sming/Components/Network/src/Data/PriorityList.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,33 @@
*
****/


template <typename ObjectType>
class PriorityNode
template <typename ObjectType> class PriorityNode
{
public:
ObjectType data;
int priority;
PriorityNode* next;
};


template <typename ObjectType>
class PriorityNodeList
template <typename ObjectType> class PriorityList
{
public:
~PriorityNodeList()
~PriorityList()
{
auto start = head;
while(start !=nullptr) {
auto temp = start;
start = start->next;
delete temp;
auto current = head;
while(current != nullptr) {
auto next = current->next;
delete current;
current = next;
}
}

/**
* @brief Adds and element and orders it according to its priority. Order is: High to low.
* @param prioty
*
* @retval bool true on success
*/
bool add(ObjectType object, int priority)
{
auto node = new PriorityNode<ObjectType>{};
Expand All @@ -49,29 +51,32 @@ class PriorityNodeList
return true;
}

auto start = head;
if(start->priority < node->priority) {
node->next = start;
auto current = head;
if(current->priority < node->priority) {
node->next = current;
head = node;
return true;
return true;
}

while(start->next != nullptr && start->next->priority > node->priority) {
start = start->next;
while(current->next != nullptr && current->next->priority > node->priority) {
current = current->next;
}

node->next = start->next;
start->next = node;
node->next = current->next;
current->next = node;

return true;
}

/**
* @brief Gets the head of the ordered linked list
* @retval pointer
*/
PriorityNode<ObjectType>* getHead() const
{
return head;
}


private:
PriorityNode<ObjectType>* head = nullptr;
};
8 changes: 2 additions & 6 deletions Sming/Components/Network/src/Network/Http/HttpResource.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,7 @@ using HttpResourceDelegate =
class HttpResource
{
public:

enum Type {
RESOURCE,
EVENTED_RESOURCE
};
enum Type { RESOURCE, EVENTED_RESOURCE };

virtual Type getType()
{
Expand All @@ -57,7 +53,7 @@ class HttpResource
}

public:
HttpResourceDelegate onUrlComplete = nullptr; ///< URL is ready
HttpResourceDelegate onUrlComplete = nullptr; ///< URL is ready. Path and status code are available
HttpServerConnectionBodyDelegate onBody = nullptr; ///< resource wants to process the raw body data
HttpResourceDelegate onHeadersComplete = nullptr; ///< headers are ready
HttpResourceDelegate onRequestComplete = nullptr; ///< request is complete OR upgraded
Expand Down
53 changes: 50 additions & 3 deletions Sming/Components/Network/src/Network/Http/HttpResourceTree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,59 @@ class HttpCompatResource : public HttpResource

/* HttpResourceTree */

void HttpResourceTree::set(String path, const HttpPathDelegate& callback)
void HttpResourceTree::set(const String path, HttpResource* resource, HttpResourcePlugin* plugin)
{
if(resource == nullptr) {
return;
}

HttpResource* oldResource = get(path);
bool replaceResource = true;
if(oldResource == resource) {
replaceResource = false;
}

if(plugin != nullptr) {
if(resource->getType() != HttpResource::EVENTED_RESOURCE) {
resource = new HttpEventedResource(resource);
}

plugin->registerPlugin(*(static_cast<HttpEventedResource*>(resource)));
if(!loadedPlugins.contains(plugin)) {
loadedPlugins.addElement(plugin);
}
}

if(replaceResource) {
set(path, resource);
}
}

void HttpResourceTree::set(const String& path, const HttpResourceDelegate& onRequestComplete,
HttpResourcePlugin* plugin)
{
auto resource = get(path);
if(resource == nullptr) {
debug_i("'%s' registered", path.c_str());
resource = new HttpResource;
resource->onRequestComplete = onRequestComplete;
}

set(path, resource, plugin);
}

void HttpResourceTree::set(String path, const HttpPathDelegate& callback, HttpResourcePlugin* plugin)
{
if(path.length() > 1 && path.endsWith("/")) {
path.remove(path.length() - 1);
}
debug_i("'%s' registered", path.c_str());

set(path, new HttpCompatResource(callback));
HttpResource* resource = get(path);
if(resource == nullptr) {
debug_i("'%s' registered", path.c_str());

resource = new HttpCompatResource(callback);
}

set(path, resource, plugin);
}
47 changes: 25 additions & 22 deletions Sming/Components/Network/src/Network/Http/HttpResourceTree.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "HttpResource.h"
#include "Resource/HttpEventedResource.h"
#include "Resource/HttpResourcePlugin.h"
#include <WVector.h>

using HttpPathDelegate = Delegate<void(HttpRequest& request, HttpResponse& response)>;

Expand All @@ -28,6 +29,13 @@ using HttpPathDelegate = Delegate<void(HttpRequest& request, HttpResponse& respo
class HttpResourceTree : public ObjectMap<String, HttpResource>
{
public:
~HttpResourceTree()
{
for(unsigned i = 0; i < loadedPlugins.count(); i++) {
delete loadedPlugins[i];
}
}

/** @brief Set the default resource handler
* @param resource The default resource handler
*/
Expand Down Expand Up @@ -74,29 +82,13 @@ class HttpResourceTree : public ObjectMap<String, HttpResource>
set(path, resource);
}

void set(const String& path, const HttpResourceDelegate& onRequestComplete, HttpResourcePlugin plugin)
{
HttpResource* resource = get(path);
if(resource == nullptr) {
HttpResource* resource = new HttpResource;
resource->onRequestComplete = onRequestComplete;

auto eventedResource = new HttpEventedResource(resource);
plugin(*eventedResource);
set(path, resource);

return;
}


if(resource->getType() == HttpResource::EVENTED_RESOURCE) {
plugin(*(static_cast<HttpEventedResource*>(resource)));
}
}
void set(const String path, HttpResource* resource, HttpResourcePlugin* plugin);

void set(const String& path, const HttpResourceDelegate& onRequestComplete, HttpResourcePlugin* plugin);

template <class H, class... Tail>
void set(const String& path, const HttpResourceDelegate& onRequestComplete, H plugin, Tail... plugins)
template <class... Tail>
void set(const String& path, const HttpResourceDelegate& onRequestComplete, HttpResourcePlugin* plugin,
Tail... plugins)
{
set(path, onRequestComplete, plugin);
set(path, onRequestComplete, plugins...);
Expand All @@ -106,8 +98,19 @@ class HttpResourceTree : public ObjectMap<String, HttpResource>
* @brief Add a new path resource with a callback
* @param path URL path
* @param callback The callback that will handle this path
* @param plugin - optional resource plugin
* @note Path should start with slash. Trailing slashes will be removed
* @note Any existing handler for this path is replaced
*/
void set(String path, const HttpPathDelegate& callback);
void set(String path, const HttpPathDelegate& callback, HttpResourcePlugin* plugin = nullptr);

template <class... Tail>
void set(const String& path, const HttpPathDelegate& callback, HttpResourcePlugin* plugin, Tail... plugins)
{
set(path, callback, plugin);
set(path, callback, plugins...);
}

private:
Vector<HttpResourcePlugin*> loadedPlugins;
};
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,12 @@ int HttpServerConnection::onPath(const Url& uri)
resource = resourceTree->getDefault();
}

return 0;
int hasError = 0;
if(resource != nullptr && resource->onUrlComplete) {
hasError = resource->onUrlComplete(*this, request, response);
}

return hasError;
}

int HttpServerConnection::onMessageComplete(http_parser* parser)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,23 @@
#include "../HttpResourcePlugin.h"
#include <Data/WebHelpers/base64.h>

class ResourceBasicAuth
class ResourceBasicAuth : public HttpResourcePlugin
{
public:
ResourceBasicAuth(const String& realm, const String& username, const String& password)
: realm(realm), username(username), password(password)
: realm(realm), username(username), password(password)
{
}

bool operator()(HttpEventedResource& resource)
bool registerPlugin(HttpEventedResource& resource) override
{
return resource.addEvent(HttpEventedResource::EVENT_HEADERS, HttpEventedResource::EventCallback(&ResourceBasicAuth::authenticate, this), 1);
return resource.addEvent(HttpEventedResource::EVENT_HEADERS,
HttpEventedResource::EventCallback(&ResourceBasicAuth::authenticate, this), 1);
}

bool authenticate(HttpServerConnection& connection, const char* at, size_t length) const
bool authenticate(HttpServerConnection& connection, const char* at, size_t length)
{
auto request = connection.getRequest();

auto& headers = request->headers;
auto authorization = headers[HTTP_HEADER_AUTHORIZATION];
if(authorization) {
Expand Down Expand Up @@ -66,6 +66,7 @@ class ResourceBasicAuth

return false;
}

private:
String realm;
String username;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,17 @@
#include "../HttpResourcePlugin.h"
#include <Data/WebHelpers/base64.h>

class ResourceIpAuth
class ResourceIpAuth : public HttpResourcePlugin
{
public:
ResourceIpAuth(IpAddress ip, IpAddress netmask) : ip(ip), netmask(netmask)
{
}

bool operator()(HttpEventedResource& resource)
bool registerPlugin(HttpEventedResource& resource) override
{
return resource.addEvent(HttpEventedResource::EVENT_URL, HttpEventedResource::EventCallback(&ResourceIpAuth::authenticate,this), 1);
return resource.addEvent(HttpEventedResource::EVENT_URL,
HttpEventedResource::EventCallback(&ResourceIpAuth::authenticate, this), 1);
}

bool authenticate(HttpServerConnection& connection, const char* at, size_t length)
Expand Down
Loading

0 comments on commit 057bb13

Please sign in to comment.