diff --git a/Tubio/Framework.cpp b/Tubio/Framework.cpp
index 9657f11..c0914a3 100644
--- a/Tubio/Framework.cpp
+++ b/Tubio/Framework.cpp
@@ -1,6 +1,7 @@
#include "Framework.h"
using namespace Logging;
+using namespace Rest;
Framework::Framework()
{
@@ -13,7 +14,7 @@ Framework::Framework()
PostInit();
- isRunning = true;
+ XGControl::keepServerRunning = true;
Run();
return;
@@ -32,7 +33,7 @@ Framework::~Framework()
void Framework::Run()
{
- while (isRunning)
+ while (XGControl::keepServerRunning)
{
restInterface->Update();
}
@@ -48,6 +49,7 @@ void Framework::Run()
void Framework::PreInit()
{
LogHistory::PreInit();
+ RestQueryHandler::PreInit();
return;
}
@@ -70,6 +72,7 @@ void Framework::OnExit()
void Framework::PostExit()
{
LogHistory::PostExit();
+ RestQueryHandler::PostExit();
return;
}
diff --git a/Tubio/Framework.h b/Tubio/Framework.h
index a61a584..f8da4db 100644
--- a/Tubio/Framework.h
+++ b/Tubio/Framework.h
@@ -2,6 +2,7 @@
#include "Logger.h"
#include "LogHistory.h"
#include "RestInterface.h"
+#include "XGControl.h"
class Framework
{
@@ -9,18 +10,17 @@ public:
Framework();
~Framework();
- void Run();
-
private:
+ void Run();
void PostInit();
void OnExit();
void PreInit();
void PostExit();
- RestInterface* restInterface;
+ Rest::RestInterface* restInterface;
- Log* log;
+ Logging::Logger* log;
bool isRunning = true;
};
diff --git a/Tubio/JasonPP.cpp b/Tubio/JasonPP.cpp
index 12d435c..d224362 100644
--- a/Tubio/JasonPP.cpp
+++ b/Tubio/JasonPP.cpp
@@ -948,6 +948,7 @@ void JsonArray::Parse(const std::string jsonCode)
bool areWeInString = false;
bool areWeInCode = false;
bool isCharEscaped = false;
+ bool areWeBetweenCommaAndValue = false; // Has the parser found a comma, but is still looking for the next value?
for (std::size_t i = 0; i < minifiedCode.length(); i++)
{
@@ -957,13 +958,25 @@ void JsonArray::Parse(const std::string jsonCode)
{
start = i;
areWeInCode = true;
+ areWeBetweenCommaAndValue = true;
}
else if ((!areWeInString) && (areWeInCode) && (arrayBracketLevel == 1) && (curlyBracketLevel == 0) && ((c == ',') || (i == minifiedCode.length() - 1)))
{
+ if (c != ',') areWeBetweenCommaAndValue = false;
end = i;
areWeInCode = false;
- dataJsonSnippets.push_back(minifiedCode.substr(start, end - start));
+
+ std::string codeSnippet = minifiedCode.substr(start, end - start);
+ if (codeSnippet.length() > 0) // A json data snippet can't be of size 0!
+ {
+ dataJsonSnippets.push_back(codeSnippet);
+ }
+ else
+ {
+ // JsonElement too short to be valid.
+ throw JsonParsingGeneralException(std::string("Fucked up a comma around position ") + Jstring((long long int)start));
+ }
}
if ((!areWeInString) && (c == ']') && (arrayBracketLevel == 1) && (i != minifiedCode.length() - 1)) throw JsonParsingExpectedEOFException(minifiedCode.substr(i, minifiedCode.length() - i));
@@ -984,6 +997,7 @@ void JsonArray::Parse(const std::string jsonCode)
// Someone fucked up his json code
if (arrayBracketLevel != 0) throw JsonParsingMissingBracketsException();
if (curlyBracketLevel != 0) throw JsonParsingMissingBracketsException();
+ if (areWeBetweenCommaAndValue) throw JsonParsingGeneralException("Unexpected EOF. Don't put a comma after the last value of a json array!");
if (areWeInString) throw JsonParsingMissingQuotesException();
}
@@ -1090,7 +1104,7 @@ std::string StringHelpers::Replace(const std::string str, const std::string find
return ss.str();
}
-std::string StringHelpers::Escape(std::string str)
+std::string StringHelpers::Escape(const std::string str)
{
std::stringstream ss;
@@ -1120,7 +1134,6 @@ std::string StringHelpers::Escape(std::string str)
ss << "\\\\";
break;
default:
-
if (str[i] < 0) ss << EscapeUTF8(str[i]);
else ss << str[i];
}
@@ -1671,6 +1684,11 @@ double JsonData::GetFloatPrecision() const
return customFloatPrecision;
}
+bool JsonData::IsOfNumericType() const
+{
+ return (dataType == JSON_DATA_TYPE::INT) || (dataType == JSON_DATA_TYPE::FLOAT);
+}
+
bool JsonData::GetBoolData() const
{
JSON_DATA_TYPE typeToGet = JSON_DATA_TYPE::BOOL;
@@ -2963,22 +2981,43 @@ void JsonBlock::Parse(const std::string jsonCode)
bool areWeInString = false;
bool areWeInCode = false;
bool isCharEscaped = false;
+ bool areWeBetweenCommaAndLabel = false; // Has the parser found a comma, but is still looking for the next label?
for (std::size_t i = 0; i < minifiedCode.length(); i++)
{
const char c = minifiedCode[i];
- if ((!areWeInString) && (c == '\"') && (arrayBracketLevel == 0) && (curlyBracketLevel == 1) && (!areWeInCode))
+ if ((!areWeInString) && (arrayBracketLevel == 0) && (curlyBracketLevel == 1) && (!areWeInCode))
{
- start = i;
- areWeInCode = true;
+ if (c == '\"')
+ {
+ start = i;
+ areWeInCode = true;
+ areWeBetweenCommaAndLabel = false;
+ }
+ else if (c == ',')
+ {
+ // Did not find a label between two commas!
+ throw JsonParsingGeneralException(std::string("Fucked up a comma around position ") + Jstring((long long int)i));
+ }
}
else if ((areWeInCode) && (arrayBracketLevel == 0) && (curlyBracketLevel == 1) && (!areWeInString) && ((c == ',') || (c == '}')))
{
end = i;
areWeInCode = false;
- elementCodeSnippets.push_back(minifiedCode.substr(start, end - start));
+ if (c == ',') areWeBetweenCommaAndLabel = true;
+
+ std::string codeSnippet = minifiedCode.substr(start, end - start);
+ if (codeSnippet.length() >= 4) // Minimum length for valid JsonElement code. "":0
+ {
+ elementCodeSnippets.push_back(codeSnippet);
+ }
+ else
+ {
+ // JsonElement too short to be valid.
+ throw JsonParsingGeneralException(std::string("Fucked up a comma around position ") + Jstring((long long int)start));
+ }
}
// Our } at level 1 is not the last char? It should be! EXPECTED_END_OF_FILE_EXCEPTION :)
@@ -2987,7 +3026,7 @@ void JsonBlock::Parse(const std::string jsonCode)
if ((c == '\"') && (!areWeInString)) areWeInString = true;
else if ((c == '\"') && (!isCharEscaped) && (areWeInString)) areWeInString = false;
- // No need to check for char escaping since we are already checking if we are in a string or not. Chars are ever escaped outside of strings
+ // No need to check for char escaping since we are already checking if we are in a string or not. Chars are never escaped outside of strings
if ((c == '[') && (!areWeInString)) arrayBracketLevel++;
else if ((c == ']') && (!areWeInString)) arrayBracketLevel--;
else if ((c == '{') && (!areWeInString)) curlyBracketLevel++;
@@ -3001,6 +3040,7 @@ void JsonBlock::Parse(const std::string jsonCode)
if (arrayBracketLevel != 0) throw JsonParsingMissingBracketsException();
if (curlyBracketLevel != 0) throw JsonParsingMissingBracketsException();
if (areWeInString) throw JsonParsingMissingQuotesException();
+ if (areWeBetweenCommaAndLabel) throw JsonParsingGeneralException("Unexpected EOF. Don't put a comma after the last value of a json block!");
if ((elementCodeSnippets.size() == 0) && (minifiedCode.length() > 2)) throw JsonParsingGeneralException("Found no members in json block, but code is too long for no members");
}
diff --git a/Tubio/JasonPP.hpp b/Tubio/JasonPP.hpp
index 9d3c5b6..5c3fcdd 100644
--- a/Tubio/JasonPP.hpp
+++ b/Tubio/JasonPP.hpp
@@ -1053,7 +1053,7 @@ namespace JasonPP
///
/// The original string to work in
/// The string with escaped characters
- static std::string Escape(std::string str);
+ static std::string Escape(const std::string str);
///
/// Will unescape json strings
@@ -1241,6 +1241,12 @@ namespace JasonPP
/// The json data type of this object
JSON_DATA_TYPE GetDataType() const { return dataType; };
+ ///
+ /// Returns whether or not this JsonData is either of type FLOAT or INT
+ ///
+ /// Whether or not this JsonData is either of type FLOAT or INT
+ bool IsOfNumericType() const;
+
///
/// Returns the bool value of this element, exception if of wrong type
///
@@ -2136,7 +2142,7 @@ namespace JasonPP
};
}
-#define JASONPP_VERSION (1.01)
+#define JASONPP_VERSION (1.02)
namespace JasonPP
{
diff --git a/Tubio/LogHistory.cpp b/Tubio/LogHistory.cpp
index c8ef1d9..2083f45 100644
--- a/Tubio/LogHistory.cpp
+++ b/Tubio/LogHistory.cpp
@@ -23,9 +23,9 @@ void LogHistory::PostExit()
return;
}
-void LogHistory::AddLogToHistory(LogEntry* _newEntry)
+void LogHistory::AddLogToHistory(LogEntry* newEntry)
{
- history->push_back(_newEntry);
+ history->push_back(newEntry);
return;
}
diff --git a/Tubio/LogHistory.h b/Tubio/LogHistory.h
index 33ac04c..66bc7d8 100644
--- a/Tubio/LogHistory.h
+++ b/Tubio/LogHistory.h
@@ -26,7 +26,7 @@ namespace Logging
static std::vector* GetLogHistory() { return history; }
private:
- static void AddLogToHistory(LogEntry* _newEntry);
+ static void AddLogToHistory(LogEntry* newEntry);
static std::vector* history;
diff --git a/Tubio/Logger.cpp b/Tubio/Logger.cpp
index 943e58d..5713018 100644
--- a/Tubio/Logger.cpp
+++ b/Tubio/Logger.cpp
@@ -2,15 +2,15 @@
using namespace Logging;
-Logger::Logger(std::string _identifier)
+Logger::Logger(std::string identifier)
{
isInitialized = true;
std::stringstream ss;
- rawIdentifier = _identifier;
+ rawIdentifier = identifier;
ss << "[" << rawIdentifier << "]";
- identifier = ss.str();
+ this->identifier = ss.str();
return;
}
@@ -25,12 +25,12 @@ void Logger::Clear()
return;
}
-void Logger::Set(std::string _str)
+void Logger::Set(std::string str)
{
if (!IsInitializedSanityCheck()) return;
Clear();
- cout << _str;
+ cout << str;
return;
}
@@ -44,7 +44,7 @@ std::string Logger::Flush()
tm currTm;
localtime_s(&currTm, &currTime);
char timeBuf[256];
- strftime(timeBuf, 100, "%d.%m.%Y - %T", currTm);
+ strftime(timeBuf, 100, "%d.%m.%Y - %T", &currTm);
std::stringstream bufOut;
bufOut << "<" << timeBuf << "> " << identifier << TypeToPrefix(type) << ": " << cout.str();
@@ -56,25 +56,25 @@ std::string Logger::Flush()
newEntry->type = type;
LogHistory::AddLogToHistory(newEntry);
- std::cout << TypeToColor(type) << bufOut.str() << "\033[0m" << std::endl;
+ std::cout << bufOut.str() << std::endl;
Clear();
return "";
}
-std::string Logger::Type(LOG_TYPE _type)
+std::string Logger::Type(LOG_TYPE type)
{
if (!IsInitializedSanityCheck()) return "";
- type = _type;
+ this->type = type;
return "";
}
-std::string Logger::TypeToPrefix(LOG_TYPE _type)
+std::string Logger::TypeToPrefix(LOG_TYPE type)
{
- switch (_type)
+ switch (type)
{
case LOG_TYPE::LOG:
return "";
@@ -94,7 +94,7 @@ std::string Logger::TypeToPrefix(LOG_TYPE _type)
std::string Logger::TypeToColor(LOG_TYPE _type)
{
- switch (_type)
+ /*switch (_type)
{
case LOG_TYPE::LOG:
return "\033[0m";
@@ -109,7 +109,8 @@ std::string Logger::TypeToColor(LOG_TYPE _type)
return "\033[0m";
}
- return "\033[0m";
+ return "\033[0m";*/
+ return "";
}
bool Logger::IsInitializedSanityCheck()
@@ -117,7 +118,8 @@ bool Logger::IsInitializedSanityCheck()
if (!isInitialized)
{
Logger log("Logger"); //A Log object cannot always have a Log-member because of its recursive nature. Only create them when needed!
- log.cout << log.Err() << "Attempted to use logger object without being initialized!" << log.Flush();
+ log.cout << log.Err() << "Attempted to use logger object without being initialized!";
+ log.Flush();
return false;
}
diff --git a/Tubio/Logger.h b/Tubio/Logger.h
index e851e33..47794df 100644
--- a/Tubio/Logger.h
+++ b/Tubio/Logger.h
@@ -7,43 +7,43 @@
namespace Logging
{
- class Log
+ class Logger
{
public:
public:
//Creates a Logger object. Pass an identifier such as MySQL
- Log(std::string _identifier);
+ Logger(std::string identifier);
//Clears the buffered string and resets the log type to default
void Clear();
//Sets the buffered string
- void Set(std::string _str);
+ void Set(std::string str);
//Prints the buffered string to the console and clears it
std::string Flush();
//Sets a custom log type
- std::string Type(LOG_TYPE _type);
+ std::string Type(LOG_TYPE type);
//Sets the log type to warning
- std::string Warn() { return Type(WARN); }
+ std::string Warn() { return Type(LOG_TYPE::WARN); }
//Sets the log type to error
- std::string Err() { return Type(ERR); }
+ std::string Err() { return Type(LOG_TYPE::ERR); }
std::stringstream cout;
private:
- std::string TypeToPrefix(LOG_TYPE _type);
- std::string TypeToColor(LOG_TYPE _type);
+ std::string TypeToPrefix(LOG_TYPE type);
+ std::string TypeToColor(LOG_TYPE type);
bool IsInitializedSanityCheck();
std::string identifier;
std::string rawIdentifier;
- LOG_TYPE type = LOG;
+ LOG_TYPE type = LOG_TYPE::LOG;
bool isInitialized = false;
};
diff --git a/Tubio/RestInterface.cpp b/Tubio/RestInterface.cpp
index 0b30f2b..dbfad08 100644
--- a/Tubio/RestInterface.cpp
+++ b/Tubio/RestInterface.cpp
@@ -1,6 +1,8 @@
#include "RestInterface.h"
using namespace Logging;
+using namespace Rest;
+using namespace JasonPP;
RestInterface::RestInterface()
{
@@ -28,7 +30,6 @@ void RestInterface::PostInit()
{
isBootedSuccessfully = InitWebServer();
-
return;
}
@@ -64,45 +65,42 @@ void RestInterface::Update()
return;
}
-void RestInterface::ServeStringToConnection(struct mg_connection* _c, std::string _str)
+void RestInterface::ServeStringToConnection(struct mg_connection* c, std::string str, int httpStatusCode)
{
- mg_send_head(_c, 200, _str.length(), "content-type: application/json\nAccess-Control-Allow-Origin: *");
- mg_printf(_c, _str.c_str());
+ mg_send_head(c, httpStatusCode, str.length(), "content-type: application/json\nAccess-Control-Allow-Origin: *");
+ mg_printf(c, str.c_str());
return;
}
-
-void RestInterface::EventHandler(mg_connection* _pNc, int _ev, void* _p)
+void RestInterface::EventHandler(mg_connection* pNc, int ev, void* p)
{
- switch (_ev)
+ switch (ev)
{
case MG_EV_HTTP_REQUEST:
- /*
- StringParser sp(_pNc->recv_mbuf.buf);
+ http_message* hpm = (http_message*)p;
+ std::string requestBodyRaw = FixUnterminatedString(hpm->body.p, hpm->body.len);
- sp.Skip("GET /");
- std::string rawRequest = sp.ExtSeek(" HTTP/");
- std::string jsonQuery = StringTools::UrlDecode(rawRequest);
+ if (IsJsonValid(requestBodyRaw))
+ {
+ Json requestBody;
+ requestBody.Parse(requestBodyRaw);
+
+ JsonBlock responseBody;
+ HTTP_STATUS_CODE returnCode;
+ RestQueryHandler::ProcessQuery(requestBody, responseBody, returnCode);
- std::string queryResult = RestAPIQueryHandler::ProcessQuery(jsonQuery);
+ Json response(responseBody);
+ ServeStringToConnection(pNc, response.Render(), returnCode);
+ }
+ else
+ {
+ Json errorJson = RestResponseTemplates::GetByCode(HTTP_STATUS_CODE::BAD_REQUEST, "Received json is fucked up");
+ ServeStringToConnection(pNc, errorJson.Render(), HTTP_STATUS_CODE::BAD_REQUEST);
+ }
-
- ServeStringToConnection(_pNc, queryResult);
- */
-
- //std::cout << _pNc->recv_mbuf.buf << std::endl;
-
- http_message* hpm = (http_message*)_p;
-
- char buf[500];
- mg_get_http_var(&hpm->body, "data", buf, 500);
- std::cout << buf << std::endl;
-
- ServeStringToConnection(_pNc, _pNc->recv_mbuf.buf);
-
break;
}
@@ -115,3 +113,15 @@ void RestInterface::OnExit()
return;
}
+
+
+std::string RestInterface::FixUnterminatedString(const char* cstr, const std::size_t len)
+{
+ std::stringstream ss;
+ for (std::size_t i = 0; i < len; i++)
+ {
+ ss << *(cstr + i);
+ }
+
+ return ss.str();
+}
diff --git a/Tubio/RestInterface.h b/Tubio/RestInterface.h
index ed4f489..6da03f8 100644
--- a/Tubio/RestInterface.h
+++ b/Tubio/RestInterface.h
@@ -4,34 +4,37 @@
#include
#include "mongoose.h"
#include "Logger.h"
+#include "RestResponseTemplates.h"
+#include "RestQueryHandler.h"
#define WEBAPI_SERVER_POLLRATE 100
#define WEBAPI_SERVER_PORT "6969"
-class RestInterface
+namespace Rest
{
-public:
- RestInterface();
- ~RestInterface();
+ class RestInterface
+ {
+ public:
+ RestInterface();
+ ~RestInterface();
- void PostInit();
- void Update();
- void OnExit();
+ void PostInit();
+ void Update();
+ void OnExit();
-private:
- bool InitWebServer();
+ private:
+ bool InitWebServer();
- static void EventHandler(struct mg_connection* _pNc, int _ev, void* _p);
-
- static void ServeStringToConnection(struct mg_connection* _c, std::string _str);
+ static void EventHandler(struct mg_connection* pNc, int ev, void* p);
+ static void ServeStringToConnection(struct mg_connection* c, std::string str, int httpStatusCode = 200);
+ static std::string FixUnterminatedString(const char* cstr, const std::size_t len);
- struct mg_mgr* pMgr;
- struct mg_connection* pNc;
- static mg_serve_http_opts pServeOpts;
+ struct mg_mgr* pMgr;
+ struct mg_connection* pNc;
- Logging::Logger* log;
-
- bool isBootedSuccessfully;
-};
+ Logging::Logger* log;
+ bool isBootedSuccessfully;
+ };
+}
diff --git a/Tubio/RestQueryHandler.cpp b/Tubio/RestQueryHandler.cpp
new file mode 100644
index 0000000..e4fe605
--- /dev/null
+++ b/Tubio/RestQueryHandler.cpp
@@ -0,0 +1,92 @@
+#include "RestQueryHandler.h"
+
+using namespace Rest;
+using namespace Logging;
+using namespace JasonPP;
+
+void RestQueryHandler::PreInit()
+{
+ log = new Logger("RestQueryHandler");
+
+ return;
+}
+
+bool RestQueryHandler::ProcessQuery(const Json& request, JsonBlock& responseBody, HTTP_STATUS_CODE& responseCode)
+{
+ if (!ValidateField("request", JSON_DATA_TYPE::STRING, request, responseBody))
+ {
+ responseCode = BAD_REQUEST;
+ return false;
+ }
+ JsonBlock requestBody = request.AsJson;
+ std::string requestName = requestBody.Get("request").AsString;
+
+ if (requestName == "kill_yourself") return KillYourself(requestBody, responseBody, responseCode);
+
+
+
+ responseBody.CloneFrom(RestResponseTemplates::GetByCode(NOT_FOUND, "The requested request was not found."));
+ responseCode = NOT_FOUND;
+ return false;
+}
+
+void Rest::RestQueryHandler::PostExit()
+{
+ delete log;
+ log = nullptr;
+
+ return;
+}
+
+bool RestQueryHandler::KillYourself(const JsonBlock& request, JsonBlock& responseBody, HTTP_STATUS_CODE& responseCode)
+{
+ XGControl::keepServerRunning = false;
+
+ log->cout << "Shutting down server upon rest request...";
+ log->Flush();
+
+ responseCode = OK;
+ responseBody.CloneFrom(RestResponseTemplates::GetByCode(OK));
+ responseBody.Set("message") = "Goodbye! :3";
+ return true;
+}
+
+bool RestQueryHandler::ValidateField(const std::string name, const JasonPP::JSON_DATA_TYPE type, const JasonPP::Json& checkThat, JasonPP::JsonBlock& putErrorResponseHere)
+{
+ if (checkThat.GetDataType() != JSON_DATA_TYPE::JSON)
+ {
+ putErrorResponseHere = RestResponseTemplates::GetByCode(BAD_REQUEST, "The request body must be a json struct! No json array or similar...");
+ return false;
+ }
+
+ const JsonBlock& cachedJson = checkThat.AsJson;
+
+ if (cachedJson.DoesShorthandExist(name))
+ {
+ const JsonData& cached = cachedJson.ShorthandGet(name);
+
+ if ((cached.GetDataType() == type) ||
+ ((cached.IsOfNumericType()) && (type == JSON_DATA_TYPE::INT)) ||
+ ((cached.IsOfNumericType()) && (type == JSON_DATA_TYPE::FLOAT)))
+ {
+ return true;
+ }
+ else
+ {
+ std::stringstream ss;
+ ss << "Mandatory value \"" << name << "\" is of wrong type (" << JsonDataType2String(cached.GetDataType()) << ")" << std::endl;
+ ss << "Should be of type " << JsonDataType2String(type) << "! (Integers can be casted to floats)";
+
+ putErrorResponseHere.CloneFrom(RestResponseTemplates::GetByCode(BAD_REQUEST, ss.str()));
+ }
+ }
+ else
+ {
+ putErrorResponseHere.CloneFrom(RestResponseTemplates::GetByCode(BAD_REQUEST, std::string("Missing mandatory value '" + name + "'")));
+ return false;
+ }
+
+ return false;
+}
+
+Logger* RestQueryHandler::log;
\ No newline at end of file
diff --git a/Tubio/RestQueryHandler.h b/Tubio/RestQueryHandler.h
new file mode 100644
index 0000000..8291555
--- /dev/null
+++ b/Tubio/RestQueryHandler.h
@@ -0,0 +1,25 @@
+#pragma once
+#include "JasonPP.hpp"
+#include "RestResponseTemplates.h"
+#include "XGControl.h"
+#include "Logger.h"
+
+namespace Rest
+{
+ class RestQueryHandler
+ {
+ public:
+ static void PreInit();
+
+ static bool ProcessQuery(const JasonPP::Json& request, JasonPP::JsonBlock& responseBody, HTTP_STATUS_CODE& responseCode);
+
+ static void PostExit();
+
+ private:
+ static bool KillYourself(const JasonPP::JsonBlock& request, JasonPP::JsonBlock& responseBody, HTTP_STATUS_CODE& responseCode);
+
+ static bool ValidateField(const std::string name, const JasonPP::JSON_DATA_TYPE type, const JasonPP::Json& checkThat, JasonPP::JsonBlock& putErrorResponseHere);
+
+ static Logging::Logger* log;
+ };
+}
diff --git a/Tubio/RestResponseTemplates.cpp b/Tubio/RestResponseTemplates.cpp
new file mode 100644
index 0000000..6d84ed1
--- /dev/null
+++ b/Tubio/RestResponseTemplates.cpp
@@ -0,0 +1,89 @@
+#include "RestResponseTemplates.h"
+
+using namespace JasonPP;
+
+/*
+Every query MUST have a value for "status"
+Every query with status = "ERROR" MUST have a value for "description" and "message"!
+*/
+
+JsonBlock Rest::RestResponseTemplates::GetByCode(HTTP_STATUS_CODE code, std::string message)
+{
+ switch (code)
+ {
+ case HTTP_STATUS_CODE::OK:
+ return OK();
+ case HTTP_STATUS_CODE::BAD_REQUEST:
+ return BadRequest(message);
+ case HTTP_STATUS_CODE::FORBIDDEN:
+ return Forbidden((message.length() > 0) ? message : "Could be disabled in the config file!");
+ case HTTP_STATUS_CODE::NOT_FOUND:
+ return NotFound((message.length() > 0) ? message : "not found");
+ case HTTP_STATUS_CODE::INTERNAL_SERVER_ERROR:
+ return InternalServerError((message.length() > 0) ? message : "Well, that's not good.");
+ case HTTP_STATUS_CODE::NOT_IMPLEMENTED:
+ return NotImplemented(message);
+ }
+ return InternalServerError("No template found for this http-status-code");
+}
+
+JsonBlock Rest::RestResponseTemplates::OK()
+{
+ return JsonBlock({
+ Ele("status", "OK"),
+ });
+}
+
+JsonBlock Rest::RestResponseTemplates::BadRequest(std::string message)
+{
+ return JsonBlock({
+ Ele("status", "ERROR"),
+ Ele("description", "Bad request"),
+ Ele("message", message)
+ });
+}
+
+JsonBlock Rest::RestResponseTemplates::Unauthorized(std::string message)
+{
+ return JsonBlock({
+ Ele("status", "ERROR"),
+ Ele("description", "Unauthorized"),
+ Ele("message", message)
+ });
+}
+
+JsonBlock Rest::RestResponseTemplates::Forbidden(std::string message)
+{
+ return JsonBlock({
+ Ele("status", "ERROR"),
+ Ele("description", "Forbidden"),
+ Ele("message", message)
+ });
+}
+
+JsonBlock Rest::RestResponseTemplates::NotFound(std::string message)
+{
+ return JsonBlock({
+ Ele("status", "ERROR"),
+ Ele("description", "Not found"),
+ Ele("message", message)
+ });
+}
+
+JsonBlock Rest::RestResponseTemplates::InternalServerError(std::string message)
+{
+ return JsonBlock({
+ Ele("status", "ERROR"),
+ Ele("description", "Internal server error"),
+ Ele("message", message)
+ });
+}
+
+JsonBlock Rest::RestResponseTemplates::NotImplemented(std::string message)
+{
+ return JsonBlock({
+ Ele("status", "ERROR"),
+ Ele("description", "Not implemented"),
+ Ele("message", message)
+ });
+}
diff --git a/Tubio/RestResponseTemplates.h b/Tubio/RestResponseTemplates.h
new file mode 100644
index 0000000..56473fa
--- /dev/null
+++ b/Tubio/RestResponseTemplates.h
@@ -0,0 +1,33 @@
+#pragma once
+#include "JasonPP.hpp"
+
+namespace Rest
+{
+ enum HTTP_STATUS_CODE {
+ OK = 200,
+ BAD_REQUEST = 400,
+ UNAUTHORIZED = 401,
+ FORBIDDEN = 403,
+ NOT_FOUND = 404,
+ METHOD_NOT_ALLOWED = 405,
+ INTERNAL_SERVER_ERROR = 500,
+ NOT_IMPLEMENTED = 501
+ };
+
+ class RestResponseTemplates
+ {
+ public:
+ static JasonPP::JsonBlock GetByCode(HTTP_STATUS_CODE code, std::string message = "");
+
+ private:
+ static JasonPP::JsonBlock OK();
+ static JasonPP::JsonBlock BadRequest(std::string message);
+ static JasonPP::JsonBlock Unauthorized(std::string message);
+ static JasonPP::JsonBlock Forbidden(std::string message);
+ static JasonPP::JsonBlock NotFound(std::string message);
+ static JasonPP::JsonBlock MethodNotAllowed(std::string message);
+
+ static JasonPP::JsonBlock InternalServerError(std::string message);
+ static JasonPP::JsonBlock NotImplemented(std::string message);
+ };
+}
diff --git a/Tubio/Tubio.vcxproj b/Tubio/Tubio.vcxproj
index d263da1..5a7fda0 100644
--- a/Tubio/Tubio.vcxproj
+++ b/Tubio/Tubio.vcxproj
@@ -145,7 +145,10 @@
+
+
+
@@ -154,7 +157,10 @@
+
+
+
diff --git a/Tubio/Tubio.vcxproj.filters b/Tubio/Tubio.vcxproj.filters
index 16dc41a..b84e1dc 100644
--- a/Tubio/Tubio.vcxproj.filters
+++ b/Tubio/Tubio.vcxproj.filters
@@ -39,6 +39,15 @@
Quelldateien
+
+ Quelldateien
+
+
+ Quelldateien
+
+
+ Quelldateien
+
@@ -62,5 +71,14 @@
Headerdateien
+
+ Headerdateien
+
+
+ Headerdateien
+
+
+ Headerdateien
+
\ No newline at end of file
diff --git a/Tubio/XGControl.cpp b/Tubio/XGControl.cpp
new file mode 100644
index 0000000..9ddc0d2
--- /dev/null
+++ b/Tubio/XGControl.cpp
@@ -0,0 +1,3 @@
+#include "XGControl.h"
+
+bool XGControl::keepServerRunning = false;
diff --git a/Tubio/XGControl.h b/Tubio/XGControl.h
new file mode 100644
index 0000000..d12aa6e
--- /dev/null
+++ b/Tubio/XGControl.h
@@ -0,0 +1,11 @@
+#pragma once
+
+///
+/// Class to house control variables
+///
+class XGControl
+{
+public:
+ static bool keepServerRunning;
+};
+
diff --git a/enc_temp_folder/279148d2e95bb05a299ee9c83973619a/RestInterface.cpp b/enc_temp_folder/279148d2e95bb05a299ee9c83973619a/RestInterface.cpp
deleted file mode 100644
index a59e3b4..0000000
--- a/enc_temp_folder/279148d2e95bb05a299ee9c83973619a/RestInterface.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-#include "RestInterface.h"
-
-using namespace Logging;
-
-RestInterface::RestInterface()
-{
- pMgr = new mg_mgr();
- pNc = nullptr;
- log = new Logger("WebServer");
-
- isBootedSuccessfully = false;
-
- return;
-}
-
-RestInterface::~RestInterface()
-{
- delete pMgr;
- delete log;
-
- log = nullptr;
- pMgr = nullptr;
-
- return;
-}
-
-void RestInterface::PostInit()
-{
- isBootedSuccessfully = InitWebServer();
-
-
- return;
-}
-
-bool RestInterface::InitWebServer()
-{
- mg_mgr_init(pMgr, NULL);
-
- log->cout << "Starting web server on port " << WEBAPI_SERVER_PORT << "...";
- log->Flush();
-
- pNc = mg_bind(pMgr, WEBAPI_SERVER_PORT, this->EventHandler);
-
- if (pNc == NULL)
- {
- log->cout << log->Err() << "Failed to boot the web server! - Unable to bind listener!";
- log->Flush();
- return false;
- }
-
- mg_set_protocol_http_websocket(pNc);
-
- log->cout << "Started web server successfully!";
- log->Flush();
- isBootedSuccessfully = true;
-
- return true;
-}
-
-void RestInterface::Update()
-{
- mg_mgr_poll(pMgr, WEBAPI_SERVER_POLLRATE);
-
- return;
-}
-
-void RestInterface::ServeStringToConnection(struct mg_connection* _c, std::string _str)
-{
- mg_send_head(_c, 200, _str.length(), "content-type: application/json\nAccess-Control-Allow-Origin: *");
- mg_printf(_c, _str.c_str());
-
- return;
-}
-
-
-void RestInterface::EventHandler(mg_connection* _pNc, int _ev, void* _p)
-{
- switch (_ev)
- {
- case MG_EV_HTTP_REQUEST:
-
- /*
- StringParser sp(_pNc->recv_mbuf.buf);
-
- sp.Skip("GET /");
- std::string rawRequest = sp.ExtSeek(" HTTP/");
- std::string jsonQuery = StringTools::UrlDecode(rawRequest);
-
- std::string queryResult = RestAPIQueryHandler::ProcessQuery(jsonQuery);
-
-
-
- ServeStringToConnection(_pNc, queryResult);
- */
-
- //std::cout << _pNc->recv_mbuf.buf << std::endl;
-
- http_message* hpm = (http_message*)_p;
-
- char buf[500];
- mg_get_http_var(&hpm->body, "data", buf, 500);
-
- ServeStringToConnection(_pNc, _pNc->recv_mbuf.buf);
-
- break;
- }
-
- return;
-}
-
-void RestInterface::OnExit()
-{
- mg_mgr_free(pMgr);
-
- return;
-}
diff --git a/enc_temp_folder/c03316ad742a6c4782beb0cc156430/RestInterface.cpp b/enc_temp_folder/c03316ad742a6c4782beb0cc156430/RestInterface.cpp
deleted file mode 100644
index 535cac5..0000000
--- a/enc_temp_folder/c03316ad742a6c4782beb0cc156430/RestInterface.cpp
+++ /dev/null
@@ -1,114 +0,0 @@
-#include "RestInterface.h"
-
-using namespace Logging;
-
-RestInterface::RestInterface()
-{
- pMgr = new mg_mgr();
- pNc = nullptr;
- log = new Logger("WebServer");
-
- isBootedSuccessfully = false;
-
- return;
-}
-
-RestInterface::~RestInterface()
-{
- delete pMgr;
- delete log;
-
- log = nullptr;
- pMgr = nullptr;
-
- return;
-}
-
-void RestInterface::PostInit()
-{
- isBootedSuccessfully = InitWebServer();
-
-
- return;
-}
-
-bool RestInterface::InitWebServer()
-{
- mg_mgr_init(pMgr, NULL);
-
- log->cout << "Starting web server on port " << WEBAPI_SERVER_PORT << "...";
- log->Flush();
-
- pNc = mg_bind(pMgr, WEBAPI_SERVER_PORT, this->EventHandler);
-
- if (pNc == NULL)
- {
- log->cout << log->Err() << "Failed to boot the web server! - Unable to bind listener!";
- log->Flush();
- return false;
- }
-
- mg_set_protocol_http_websocket(pNc);
-
- log->cout << "Started web server successfully!";
- log->Flush();
- isBootedSuccessfully = true;
-
- return true;
-}
-
-void RestInterface::Update()
-{
- mg_mgr_poll(pMgr, WEBAPI_SERVER_POLLRATE);
-
- return;
-}
-
-void RestInterface::ServeStringToConnection(struct mg_connection* _c, std::string _str)
-{
- mg_send_head(_c, 200, _str.length(), "content-type: application/json\nAccess-Control-Allow-Origin: *");
- mg_printf(_c, _str.c_str());
-
- return;
-}
-
-
-void RestInterface::EventHandler(mg_connection* _pNc, int _ev, void* _p)
-{
- switch (_ev)
- {
- case MG_EV_HTTP_REQUEST:
-
- /*
- StringParser sp(_pNc->recv_mbuf.buf);
-
- sp.Skip("GET /");
- std::string rawRequest = sp.ExtSeek(" HTTP/");
- std::string jsonQuery = StringTools::UrlDecode(rawRequest);
-
- std::string queryResult = RestAPIQueryHandler::ProcessQuery(jsonQuery);
-
-
-
- ServeStringToConnection(_pNc, queryResult);
- */
-
- std::cout << _pNc->recv_mbuf.buf << std::endl;
-
- http_message* hpm = (http_message*)_p;
-
- std::cout << hpm << std::endl;
- ServeStringToConnection(_pNc, _pNc->recv_mbuf.buf);
-
- break;
- }
-
- return;
-}
-
-void RestInterface::OnExit()
-{
- mg_mgr_free(pMgr);
-
- return;
-}