Skip to content

Commit

Permalink
Save flash: Move WebApi json parsing to separate method to prevent a …
Browse files Browse the repository at this point in the history
…lot of redundant code
  • Loading branch information
tbnobody committed Apr 1, 2024
1 parent 58efd9e commit 8add226
Show file tree
Hide file tree
Showing 13 changed files with 82 additions and 420 deletions.
3 changes: 3 additions & 0 deletions include/WebApi.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "WebApi_webapp.h"
#include "WebApi_ws_console.h"
#include "WebApi_ws_live.h"
#include <AsyncJson.h>
#include <ESPAsyncWebServer.h>
#include <TaskSchedulerDeclarations.h>

Expand All @@ -37,6 +38,8 @@ class WebApiClass {

static void writeConfig(JsonVariant& retMsg, const WebApiError code = WebApiError::GenericSuccess, const String& message = "Settings saved!");

static bool parseRequestData(AsyncWebServerRequest* request, AsyncJsonResponse* response, DynamicJsonDocument& json_document, size_t max_document_size = 1024);

private:
AsyncWebServer _server;

Expand Down
34 changes: 34 additions & 0 deletions src/WebApi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,38 @@ void WebApiClass::writeConfig(JsonVariant& retMsg, const WebApiError code, const
}
}

bool WebApiClass::parseRequestData(AsyncWebServerRequest* request, AsyncJsonResponse* response, DynamicJsonDocument& json_document, size_t max_document_size)
{
auto& retMsg = response->getRoot();
retMsg["type"] = "warning";

if (!request->hasParam("data", true)) {
retMsg["message"] = "No values found!";
retMsg["code"] = WebApiError::GenericNoValueFound;
response->setLength();
request->send(response);
return false;
}

const String json = request->getParam("data", true)->value();
if (json.length() > max_document_size) {
retMsg["message"] = "Data too large!";
retMsg["code"] = WebApiError::GenericDataTooLarge;
response->setLength();
request->send(response);
return false;
}

const DeserializationError error = deserializeJson(json_document, json);
if (error) {
retMsg["message"] = "Failed to parse data!";
retMsg["code"] = WebApiError::GenericParseError;
response->setLength();
request->send(response);
return false;
}

return true;
}

WebApiClass WebApi;
31 changes: 3 additions & 28 deletions src/WebApi_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,38 +53,13 @@ void WebApiConfigClass::onConfigDelete(AsyncWebServerRequest* request)
}

AsyncJsonResponse* response = new AsyncJsonResponse();
auto& retMsg = response->getRoot();
retMsg["type"] = "warning";

if (!request->hasParam("data", true)) {
retMsg["message"] = "No values found!";
retMsg["code"] = WebApiError::GenericNoValueFound;
response->setLength();
request->send(response);
return;
}

const String json = request->getParam("data", true)->value();

if (json.length() > 1024) {
retMsg["message"] = "Data too large!";
retMsg["code"] = WebApiError::GenericDataTooLarge;
response->setLength();
request->send(response);
return;
}

DynamicJsonDocument root(1024);
const DeserializationError error = deserializeJson(root, json);

if (error) {
retMsg["message"] = "Failed to parse data!";
retMsg["code"] = WebApiError::GenericDataTooLarge;
response->setLength();
request->send(response);
if (!WebApi.parseRequestData(request, response, root)) {
return;
}

auto& retMsg = response->getRoot();

if (!(root.containsKey("delete"))) {
retMsg["message"] = "Values are missing!";
retMsg["code"] = WebApiError::GenericValueMissing;
Expand Down
31 changes: 3 additions & 28 deletions src/WebApi_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,38 +97,13 @@ void WebApiDeviceClass::onDeviceAdminPost(AsyncWebServerRequest* request)
}

AsyncJsonResponse* response = new AsyncJsonResponse(false, MQTT_JSON_DOC_SIZE);
auto& retMsg = response->getRoot();
retMsg["type"] = "warning";

if (!request->hasParam("data", true)) {
retMsg["message"] = "No values found!";
retMsg["code"] = WebApiError::GenericNoValueFound;
response->setLength();
request->send(response);
return;
}

const String json = request->getParam("data", true)->value();

if (json.length() > MQTT_JSON_DOC_SIZE) {
retMsg["message"] = "Data too large!";
retMsg["code"] = WebApiError::GenericDataTooLarge;
response->setLength();
request->send(response);
return;
}

DynamicJsonDocument root(MQTT_JSON_DOC_SIZE);
const DeserializationError error = deserializeJson(root, json);

if (error) {
retMsg["message"] = "Failed to parse data!";
retMsg["code"] = WebApiError::GenericParseError;
response->setLength();
request->send(response);
if (!WebApi.parseRequestData(request, response, root, MQTT_JSON_DOC_SIZE)) {
return;
}

auto& retMsg = response->getRoot();

if (!(root.containsKey("curPin")
|| root.containsKey("display"))) {
retMsg["message"] = "Values are missing!";
Expand Down
31 changes: 3 additions & 28 deletions src/WebApi_dtu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,38 +84,13 @@ void WebApiDtuClass::onDtuAdminPost(AsyncWebServerRequest* request)
}

AsyncJsonResponse* response = new AsyncJsonResponse();
auto& retMsg = response->getRoot();
retMsg["type"] = "warning";

if (!request->hasParam("data", true)) {
retMsg["message"] = "No values found!";
retMsg["code"] = WebApiError::GenericNoValueFound;
response->setLength();
request->send(response);
return;
}

const String json = request->getParam("data", true)->value();

if (json.length() > 1024) {
retMsg["message"] = "Data too large!";
retMsg["code"] = WebApiError::GenericDataTooLarge;
response->setLength();
request->send(response);
return;
}

DynamicJsonDocument root(1024);
const DeserializationError error = deserializeJson(root, json);

if (error) {
retMsg["message"] = "Failed to parse data!";
retMsg["code"] = WebApiError::GenericParseError;
response->setLength();
request->send(response);
if (!WebApi.parseRequestData(request, response, root)) {
return;
}

auto& retMsg = response->getRoot();

if (!(root.containsKey("serial")
&& root.containsKey("pollinterval")
&& root.containsKey("nrf_palevel")
Expand Down
124 changes: 12 additions & 112 deletions src/WebApi_inverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,38 +88,13 @@ void WebApiInverterClass::onInverterAdd(AsyncWebServerRequest* request)
}

AsyncJsonResponse* response = new AsyncJsonResponse();
auto& retMsg = response->getRoot();
retMsg["type"] = "warning";

if (!request->hasParam("data", true)) {
retMsg["message"] = "No values found!";
retMsg["code"] = WebApiError::GenericNoValueFound;
response->setLength();
request->send(response);
return;
}

const String json = request->getParam("data", true)->value();

if (json.length() > 1024) {
retMsg["message"] = "Data too large!";
retMsg["code"] = WebApiError::GenericDataTooLarge;
response->setLength();
request->send(response);
return;
}

DynamicJsonDocument root(1024);
const DeserializationError error = deserializeJson(root, json);

if (error) {
retMsg["message"] = "Failed to parse data!";
retMsg["code"] = WebApiError::GenericParseError;
response->setLength();
request->send(response);
if (!WebApi.parseRequestData(request, response, root)) {
return;
}

auto& retMsg = response->getRoot();

if (!(root.containsKey("serial")
&& root.containsKey("name"))) {
retMsg["message"] = "Values are missing!";
Expand Down Expand Up @@ -188,38 +163,13 @@ void WebApiInverterClass::onInverterEdit(AsyncWebServerRequest* request)
}

AsyncJsonResponse* response = new AsyncJsonResponse();
auto& retMsg = response->getRoot();
retMsg["type"] = "warning";

if (!request->hasParam("data", true)) {
retMsg["message"] = "No values found!";
retMsg["code"] = WebApiError::GenericNoValueFound;
response->setLength();
request->send(response);
return;
}

const String json = request->getParam("data", true)->value();

if (json.length() > 1024) {
retMsg["message"] = "Data too large!";
retMsg["code"] = WebApiError::GenericDataTooLarge;
response->setLength();
request->send(response);
return;
}

DynamicJsonDocument root(1024);
const DeserializationError error = deserializeJson(root, json);

if (error) {
retMsg["message"] = "Failed to parse data!";
retMsg["code"] = WebApiError::GenericParseError;
response->setLength();
request->send(response);
if (!WebApi.parseRequestData(request, response, root)) {
return;
}

auto& retMsg = response->getRoot();

if (!(root.containsKey("id") && root.containsKey("serial") && root.containsKey("name") && root.containsKey("channel"))) {
retMsg["message"] = "Values are missing!";
retMsg["code"] = WebApiError::GenericValueMissing;
Expand Down Expand Up @@ -333,38 +283,13 @@ void WebApiInverterClass::onInverterDelete(AsyncWebServerRequest* request)
}

AsyncJsonResponse* response = new AsyncJsonResponse();
auto& retMsg = response->getRoot();
retMsg["type"] = "warning";

if (!request->hasParam("data", true)) {
retMsg["message"] = "No values found!";
retMsg["code"] = WebApiError::GenericNoValueFound;
response->setLength();
request->send(response);
return;
}

const String json = request->getParam("data", true)->value();

if (json.length() > 1024) {
retMsg["message"] = "Data too large!";
retMsg["code"] = WebApiError::GenericDataTooLarge;
response->setLength();
request->send(response);
return;
}

DynamicJsonDocument root(1024);
const DeserializationError error = deserializeJson(root, json);

if (error) {
retMsg["message"] = "Failed to parse data!";
retMsg["code"] = WebApiError::GenericParseError;
response->setLength();
request->send(response);
if (!WebApi.parseRequestData(request, response, root)) {
return;
}

auto& retMsg = response->getRoot();

if (!(root.containsKey("id"))) {
retMsg["message"] = "Values are missing!";
retMsg["code"] = WebApiError::GenericValueMissing;
Expand Down Expand Up @@ -403,38 +328,13 @@ void WebApiInverterClass::onInverterOrder(AsyncWebServerRequest* request)
}

AsyncJsonResponse* response = new AsyncJsonResponse();
auto& retMsg = response->getRoot();
retMsg["type"] = "warning";

if (!request->hasParam("data", true)) {
retMsg["message"] = "No values found!";
retMsg["code"] = WebApiError::GenericNoValueFound;
response->setLength();
request->send(response);
return;
}

const String json = request->getParam("data", true)->value();

if (json.length() > 1024) {
retMsg["message"] = "Data too large!";
retMsg["code"] = WebApiError::GenericDataTooLarge;
response->setLength();
request->send(response);
return;
}

DynamicJsonDocument root(1024);
const DeserializationError error = deserializeJson(root, json);

if (error) {
retMsg["message"] = "Failed to parse data!";
retMsg["code"] = WebApiError::GenericParseError;
response->setLength();
request->send(response);
if (!WebApi.parseRequestData(request, response, root)) {
return;
}

auto& retMsg = response->getRoot();

if (!(root.containsKey("order"))) {
retMsg["message"] = "Values are missing!";
retMsg["code"] = WebApiError::GenericValueMissing;
Expand Down
31 changes: 3 additions & 28 deletions src/WebApi_limit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,38 +58,13 @@ void WebApiLimitClass::onLimitPost(AsyncWebServerRequest* request)
}

AsyncJsonResponse* response = new AsyncJsonResponse();
auto& retMsg = response->getRoot();
retMsg["type"] = "warning";

if (!request->hasParam("data", true)) {
retMsg["message"] = "No values found!";
retMsg["code"] = WebApiError::GenericNoValueFound;
response->setLength();
request->send(response);
return;
}

const String json = request->getParam("data", true)->value();

if (json.length() > 1024) {
retMsg["message"] = "Data too large!";
retMsg["code"] = WebApiError::GenericDataTooLarge;
response->setLength();
request->send(response);
return;
}

DynamicJsonDocument root(1024);
const DeserializationError error = deserializeJson(root, json);

if (error) {
retMsg["message"] = "Failed to parse data!";
retMsg["code"] = WebApiError::GenericParseError;
response->setLength();
request->send(response);
if (!WebApi.parseRequestData(request, response, root)) {
return;
}

auto& retMsg = response->getRoot();

if (!(root.containsKey("serial")
&& root.containsKey("limit_value")
&& root.containsKey("limit_type"))) {
Expand Down
Loading

0 comments on commit 8add226

Please sign in to comment.