Skip to content

Commit

Permalink
Added example content decoder plugin explaining how to operate on bod…
Browse files Browse the repository at this point in the history
…y data.
  • Loading branch information
slav-at-attachix committed Jul 21, 2021
1 parent 057bb13 commit bf3d5a3
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 40 deletions.
2 changes: 1 addition & 1 deletion Sming/Components/Network/src/Network/Http/HttpResource.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
class HttpServerConnection;

using HttpServerConnectionBodyDelegate =
Delegate<int(HttpServerConnection& connection, HttpRequest&, const char* at, int length)>;
Delegate<int(HttpServerConnection& connection, HttpRequest&, char** at, int* length)>;
using HttpServerConnectionUpgradeDelegate =
Delegate<int(HttpServerConnection& connection, HttpRequest&, char* at, int length)>;
using HttpResourceDelegate =
Expand Down
18 changes: 10 additions & 8 deletions Sming/Components/Network/src/Network/Http/HttpServerConnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,22 +166,24 @@ int HttpServerConnection::onBody(const char* at, size_t length)
return 0;
}

if(bodyParser) {
const size_t consumed = bodyParser(request, at, length);
if(consumed != length) {
char* data = const_cast<char*>(at);
int dataLength = length;
if(resource != nullptr && resource->onBody) {
const int result = resource->onBody(*this, request, &data, &dataLength);
if(result != 0) {
hasContentError = true;
if(closeOnContentError) {
return -1;
return result;
}
}
}

if(resource != nullptr && resource->onBody) {
const int result = resource->onBody(*this, request, at, length);
if(result != 0) {
if(bodyParser) {
const size_t consumed = bodyParser(request, data, dataLength);
if(consumed != length) {
hasContentError = true;
if(closeOnContentError) {
return result;
return -1;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class ResourceBasicAuth : public HttpResourcePlugin
HttpEventedResource::EventCallback(&ResourceBasicAuth::authenticate, this), 1);
}

bool authenticate(HttpServerConnection& connection, const char* at, size_t length)
bool authenticate(HttpServerConnection& connection, char** at, int* length)
{
auto request = connection.getRequest();
auto& headers = request->headers;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class ResourceIpAuth : public HttpResourcePlugin
HttpEventedResource::EventCallback(&ResourceIpAuth::authenticate, this), 1);
}

bool authenticate(HttpServerConnection& connection, const char* at, size_t length)
bool authenticate(HttpServerConnection& connection, char** at, int* length)
{
auto remoteIp = connection.getRemoteIp();
if(remoteIp.compare(ip, netmask)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/****
* Sming Framework Project - Open Source framework for high efficiency native ESP8266 development.
* Created 2015 by Skurydin Alexey
* http://github.com/SmingHub/Sming
* All files of the Sming Core are provided under the LGPL v3 license.
*
*
* @author: 2021 - Slavey Karadzhov <[email protected]>
*
****/

#pragma once

#include "../HttpResourcePlugin.h"
#include <Data/WebHelpers/base64.h>

class DecoderContent : public HttpResourcePlugin
{
bool registerPlugin(HttpEventedResource& resource) override
{
// Check if the provided content is encoded in some way
return resource.addEvent(
HttpEventedResource::EVENT_BODY,
[](HttpServerConnection& connection, char** at, int* length) {
auto request = connection.getRequest();
if(request->headers[HTTP_HEADER_CONTENT_ENCODING] == "test") {
char* data = *at;
for(unsigned i = 0; i < *length; i++) {
data[i]++;
}
}

return true;
},
1);
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ HttpEventedResource::HttpEventedResource(HttpResource* resource)
delegate = resource;

// [ Register the main events with priority 0 ]
addEvent(EventType::EVENT_URL, [this](HttpServerConnection& connection, const char* at = nullptr, int length = 0) {
addEvent(EventType::EVENT_URL, [this](HttpServerConnection& connection, char** at = nullptr,
int* length = nullptr) {
if(delegate->onUrlComplete) {
auto hasError = delegate->onUrlComplete(connection, *connection.getRequest(), *connection.getResponse());
if(hasError) {
Expand All @@ -18,7 +19,7 @@ HttpEventedResource::HttpEventedResource(HttpResource* resource)
});

addEvent(EventType::EVENT_HEADERS,
[this](HttpServerConnection& connection, const char* at = nullptr, int length = 0) {
[this](HttpServerConnection& connection, char** at = nullptr, int* length = nullptr) {
if(delegate->onHeadersComplete) {
auto hasError =
delegate->onHeadersComplete(connection, *connection.getRequest(), *connection.getResponse());
Expand All @@ -30,31 +31,32 @@ HttpEventedResource::HttpEventedResource(HttpResource* resource)
return true;
});

addEvent(EventType::EVENT_UPGRADE, [this](HttpServerConnection& connection, const char* at = nullptr,
int length = 0) {
if(delegate->onUpgrade) {
auto hasError = delegate->onUpgrade(connection, *connection.getRequest(), const_cast<char*>(at), length);
if(hasError) {
return false;
}
}
addEvent(EventType::EVENT_UPGRADE,
[this](HttpServerConnection& connection, char** at = nullptr, int* length = nullptr) {
if(delegate->onUpgrade) {
auto hasError = delegate->onUpgrade(connection, *connection.getRequest(), *at, *length);
if(hasError) {
return false;
}
}

return true;
});
return true;
});

addEvent(EventType::EVENT_BODY, [this](HttpServerConnection& connection, const char* at = nullptr, int length = 0) {
if(delegate->onBody) {
auto hasError = delegate->onBody(connection, *connection.getRequest(), at, length);
if(hasError) {
return false;
}
}
addEvent(EventType::EVENT_BODY,
[this](HttpServerConnection& connection, char** at = nullptr, int* length = nullptr) {
if(delegate->onBody) {
auto hasError = delegate->onBody(connection, *connection.getRequest(), at, length);
if(hasError) {
return false;
}
}

return true;
});
return true;
});

addEvent(EventType::EVENT_COMPLETE,
[this](HttpServerConnection& connection, const char* at = nullptr, int length = 0) {
[this](HttpServerConnection& connection, char** at = nullptr, int* length = nullptr) {
if(delegate->onRequestComplete) {
auto hasError =
delegate->onRequestComplete(connection, *connection.getRequest(), *connection.getResponse());
Expand All @@ -79,7 +81,7 @@ HttpEventedResource::HttpEventedResource(HttpResource* resource)
return runEvent(EventType::EVENT_UPGRADE, connection, nullptr, 0);
};

onBody = [this](HttpServerConnection& connection, HttpRequest& request, const char* at, int length) -> int {
onBody = [this](HttpServerConnection& connection, HttpRequest& request, char** at, int* length) -> int {
return runEvent(EventType::EVENT_BODY, connection, at, length);
};

Expand All @@ -88,7 +90,7 @@ HttpEventedResource::HttpEventedResource(HttpResource* resource)
};
}

int HttpEventedResource::runEvent(EventType type, HttpServerConnection& connection, const char* at, int length)
int HttpEventedResource::runEvent(EventType type, HttpServerConnection& connection, char** at, int* length)
{
auto request = connection.getRequest();
if(request->headers[SKIP_HEADER] == "1") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class HttpEventedResource : public HttpResource
public:
enum EventType { EVENT_URL, EVENT_HEADERS, EVENT_UPGRADE, EVENT_BODY, EVENT_COMPLETE };

using EventCallback = Delegate<bool(HttpServerConnection&, const char*, size_t)>;
using EventCallback = Delegate<bool(HttpServerConnection&, char**, int*)>;
using Events = ObjectMap<EventType, PriorityList<EventCallback>>;

/**
Expand All @@ -39,7 +39,7 @@ class HttpEventedResource : public HttpResource
return Type::EVENTED_RESOURCE;
}

int runEvent(EventType type, HttpServerConnection& connection, const char* at = nullptr, int length = 0);
int runEvent(EventType type, HttpServerConnection& connection, char** at = nullptr, int* length = nullptr);

bool addEvent(EventType type, EventCallback callback, int priority = 0);

Expand Down
10 changes: 7 additions & 3 deletions samples/HttpServer_WebSockets/app/application.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <SmingCore.h>
#include <Network/Http/Websocket/WebsocketResource.h>
#include <Network/Http/Resource/HttpAuth.h>
#include <Network/Http/Resource/Content/DecoderContent.h>
#include "CUserData.h"

// If you want, you can define WiFi settings globally in Eclipse Environment Variables
Expand Down Expand Up @@ -96,10 +97,9 @@ void wsDisconnected(WebsocketConnection& socket)
socket.broadcast(message);
}

int onTest(HttpServerConnection& connection, HttpRequest& request, HttpResponse& response)
void onTest(HttpRequest& request, HttpResponse& response)
{
onIndex(request, response);
return 0;
debug_d("Got content: %s", request.getBody().c_str());
}

void startWebServer()
Expand All @@ -108,6 +108,8 @@ void startWebServer()
server.paths.set("/", onIndex);
server.paths.setDefault(onFile);

server.setBodyParser(MIME_FORM_URL_ENCODED, bodyToStringParser);

// Web Sockets configuration
auto wsResource = new WebsocketResource();
wsResource->setConnectionHandler(wsConnected);
Expand All @@ -122,6 +124,8 @@ void startWebServer()
server.paths.set("/ip", onIndex, new ResourceIpAuth(IpAddress("192.168.13.0"), IpAddress("255.255.255.0")),
pluginBasicAuth);

server.paths.set("/test", onTest, new DecoderContent());

Serial.println(F("\r\n=== WEB SERVER STARTED ==="));
Serial.println(WifiStation.getIP());
Serial.println(F("==============================\r\n"));
Expand Down

0 comments on commit bf3d5a3

Please sign in to comment.