diff --git a/CMakeLists.txt b/CMakeLists.txt
index f65016f7..bee55de2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -118,6 +118,11 @@ file(GLOB dvmhost_SRC
file(GLOB dvmcmd_SRC
"network/UDPSocket.h"
"network/UDPSocket.cpp"
+ "network/json/*.h"
+ "network/rest/*.h"
+ "network/rest/*.cpp"
+ "network/rest/http/*.h"
+ "network/rest/http/*.cpp"
"remote/*.h"
"remote/*.cpp"
"edac/SHA256.h"
diff --git a/Defines.h b/Defines.h
index 16c2143a..22de6c86 100644
--- a/Defines.h
+++ b/Defines.h
@@ -236,6 +236,17 @@ inline std::string strtolower(const std::string value) {
return v;
}
+///
+/// Helper to upper-case an input string.
+///
+///
+///
+inline std::string strtoupper(const std::string value) {
+ std::string v = value;
+ std::transform(v.begin(), v.end(), v.begin(), ::toupper);
+ return v;
+}
+
// ---------------------------------------------------------------------------
// Macros
// ---------------------------------------------------------------------------
diff --git a/network/RESTAPI.cpp b/network/RESTAPI.cpp
index a706c860..fdad64fc 100644
--- a/network/RESTAPI.cpp
+++ b/network/RESTAPI.cpp
@@ -70,7 +70,7 @@ using namespace modem;
///
void setResponseDefaultStatus(json::object& obj)
{
- int s = (int)HTTPReply::OK;
+ int s = (int)HTTPPayload::OK;
obj["status"].set(s);
}
@@ -80,9 +80,9 @@ void setResponseDefaultStatus(json::object& obj)
///
///
///
-void errorReply(HTTPReply& reply, std::string message, HTTPReply::StatusType status = HTTPReply::BAD_REQUEST)
+void errorPayload(HTTPPayload& reply, std::string message, HTTPPayload::StatusType status = HTTPPayload::BAD_REQUEST)
{
- HTTPReply rep;
+ HTTPPayload rep;
rep.status = status;
json::object response = json::object();
@@ -91,7 +91,7 @@ void errorReply(HTTPReply& reply, std::string message, HTTPReply::StatusType sta
response["status"].set(s);
response["message"].set(message);
- reply.reply(response);
+ reply.payload(response);
}
///
@@ -101,11 +101,11 @@ void errorReply(HTTPReply& reply, std::string message, HTTPReply::StatusType sta
///
///
///
-bool parseRequestBody(const HTTPRequest& request, HTTPReply& reply, json::object& obj)
+bool parseRequestBody(const HTTPPayload& request, HTTPPayload& reply, json::object& obj)
{
std::string contentType = request.headers.find("Content-Type");
if (contentType != "application/json") {
- reply = HTTPReply::stockReply(HTTPReply::BAD_REQUEST, "application/json");
+ reply = HTTPPayload::statusPayload(HTTPPayload::BAD_REQUEST, "application/json");
return false;
}
@@ -113,13 +113,13 @@ bool parseRequestBody(const HTTPRequest& request, HTTPReply& reply, json::object
json::value v;
std::string err = json::parse(v, request.content);
if (!err.empty()) {
- errorReply(reply, err);
+ errorPayload(reply, err);
return false;
}
// ensure parsed JSON is an object
if (!v.is()) {
- errorReply(reply, "Request was not a valid JSON object.");
+ errorPayload(reply, "Request was not a valid JSON object.");
return false;
}
@@ -313,12 +313,12 @@ void RESTAPI::invalidateHostToken(const std::string host)
///
///
///
-bool RESTAPI::validateAuth(const HTTPRequest& request, HTTPReply& reply)
+bool RESTAPI::validateAuth(const HTTPPayload& request, HTTPPayload& reply)
{
std::string host = request.headers.find("Host");
std::string headerToken = request.headers.find("X-DVM-Auth-Token");
if (headerToken == "") {
- errorReply(reply, "invalid authentication token", HTTPReply::UNAUTHORIZED);
+ errorPayload(reply, "invalid authentication token", HTTPPayload::UNAUTHORIZED);
return false;
}
@@ -330,12 +330,12 @@ bool RESTAPI::validateAuth(const HTTPRequest& request, HTTPReply& reply)
return true;
} else {
m_authTokens.erase(host); // devalidate host
- errorReply(reply, "invalid authentication token", HTTPReply::UNAUTHORIZED);
+ errorPayload(reply, "invalid authentication token", HTTPPayload::UNAUTHORIZED);
return false;
}
}
else {
- errorReply(reply, "invalid authentication token", HTTPReply::UNAUTHORIZED);
+ errorPayload(reply, "invalid authentication token", HTTPPayload::UNAUTHORIZED);
return false;
}
@@ -348,7 +348,7 @@ bool RESTAPI::validateAuth(const HTTPRequest& request, HTTPReply& reply)
///
///
///
-void RESTAPI::restAPI_PutAuth(const HTTPRequest& request, HTTPReply& reply, const RequestMatch& match)
+void RESTAPI::restAPI_PutAuth(const HTTPPayload& request, HTTPPayload& reply, const RequestMatch& match)
{
std::string host = request.headers.find("Host");
json::object response = json::object();
@@ -362,26 +362,26 @@ void RESTAPI::restAPI_PutAuth(const HTTPRequest& request, HTTPReply& reply, cons
// validate auth is a string within the JSON blob
if (!req["auth"].is()) {
invalidateHostToken(host);
- errorReply(reply, "password was not a valid string");
+ errorPayload(reply, "password was not a valid string");
return;
}
std::string auth = req["auth"].get();
if (auth.empty()) {
invalidateHostToken(host);
- errorReply(reply, "auth cannot be empty");
+ errorPayload(reply, "auth cannot be empty");
return;
}
if (auth.size() > 64) {
invalidateHostToken(host);
- errorReply(reply, "auth cannot be longer than 64 characters");
+ errorPayload(reply, "auth cannot be longer than 64 characters");
return;
}
if (!(auth.find_first_not_of("0123456789abcdefABCDEF", 2) == std::string::npos)) {
invalidateHostToken(host);
- errorReply(reply, "auth contains invalid characters");
+ errorPayload(reply, "auth contains invalid characters");
return;
}
@@ -406,7 +406,7 @@ void RESTAPI::restAPI_PutAuth(const HTTPRequest& request, HTTPReply& reply, cons
// compare hashes
if (::memcmp(m_passwordHash, passwordHash, 32U) != 0) {
invalidateHostToken(host);
- errorReply(reply, "invalid password");
+ errorPayload(reply, "invalid password");
return;
}
@@ -418,7 +418,7 @@ void RESTAPI::restAPI_PutAuth(const HTTPRequest& request, HTTPReply& reply, cons
m_authTokens[host] = salt;
response["token"].set(std::to_string(salt));
- reply.reply(response);
+ reply.payload(response);
}
///
@@ -427,7 +427,7 @@ void RESTAPI::restAPI_PutAuth(const HTTPRequest& request, HTTPReply& reply, cons
///
///
///
-void RESTAPI::restAPI_GetVersion(const HTTPRequest& request, HTTPReply& reply, const RequestMatch& match)
+void RESTAPI::restAPI_GetVersion(const HTTPPayload& request, HTTPPayload& reply, const RequestMatch& match)
{
if (!validateAuth(request, reply)) {
return;
@@ -437,7 +437,7 @@ void RESTAPI::restAPI_GetVersion(const HTTPRequest& request, HTTPReply& reply, c
setResponseDefaultStatus(response);
response["version"].set(std::string((__PROG_NAME__ " " __VER__ " (" DESCR_DMR DESCR_P25 DESCR_NXDN "CW Id, Network) (built " __BUILD__ ")")));
- reply.reply(response);
+ reply.payload(response);
}
///
@@ -446,7 +446,7 @@ void RESTAPI::restAPI_GetVersion(const HTTPRequest& request, HTTPReply& reply, c
///
///
///
-void RESTAPI::restAPI_GetStatus(const HTTPRequest& request, HTTPReply& reply, const RequestMatch& match)
+void RESTAPI::restAPI_GetStatus(const HTTPPayload& request, HTTPPayload& reply, const RequestMatch& match)
{
if (!validateAuth(request, reply)) {
return;
@@ -563,7 +563,7 @@ void RESTAPI::restAPI_GetStatus(const HTTPRequest& request, HTTPReply& reply, co
response["modem"].set(modemInfo);
}
- reply.reply(response);
+ reply.payload(response);
}
///
@@ -572,7 +572,7 @@ void RESTAPI::restAPI_GetStatus(const HTTPRequest& request, HTTPReply& reply, co
///
///
///
-void RESTAPI::restAPI_GetVoiceCh(const HTTPRequest& request, HTTPReply& reply, const RequestMatch& match)
+void RESTAPI::restAPI_GetVoiceCh(const HTTPPayload& request, HTTPPayload& reply, const RequestMatch& match)
{
if (!validateAuth(request, reply)) {
return;
@@ -599,7 +599,7 @@ void RESTAPI::restAPI_GetVoiceCh(const HTTPRequest& request, HTTPReply& reply, c
}
response["channels"].set(channels);
- reply.reply(response);
+ reply.payload(response);
}
///
@@ -608,7 +608,7 @@ void RESTAPI::restAPI_GetVoiceCh(const HTTPRequest& request, HTTPReply& reply, c
///
///
///
-void RESTAPI::restAPI_PutModemMode(const HTTPRequest& request, HTTPReply& reply, const RequestMatch& match)
+void RESTAPI::restAPI_PutModemMode(const HTTPPayload& request, HTTPPayload& reply, const RequestMatch& match)
{
if (!validateAuth(request, reply)) {
return;
@@ -624,7 +624,7 @@ void RESTAPI::restAPI_PutModemMode(const HTTPRequest& request, HTTPReply& reply,
// validate mode is a string within the JSON blob
if (!req["mode"].is()) {
- errorReply(reply, "password was not a valid string");
+ errorPayload(reply, "password was not a valid string");
return;
}
@@ -638,7 +638,7 @@ void RESTAPI::restAPI_PutModemMode(const HTTPRequest& request, HTTPReply& reply,
uint8_t hostMode = m_host->m_state;
response["mode"].set(hostMode);
- reply.reply(response);
+ reply.payload(response);
}
else if (mode == MODE_OPT_LCKOUT) {
m_host->m_fixedMode = false;
@@ -648,7 +648,7 @@ void RESTAPI::restAPI_PutModemMode(const HTTPRequest& request, HTTPReply& reply,
uint8_t hostMode = m_host->m_state;
response["mode"].set(hostMode);
- reply.reply(response);
+ reply.payload(response);
}
#if defined(ENABLE_DMR)
else if (mode == MODE_OPT_FDMR) {
@@ -660,10 +660,10 @@ void RESTAPI::restAPI_PutModemMode(const HTTPRequest& request, HTTPReply& reply,
uint8_t hostMode = m_host->m_state;
response["mode"].set(hostMode);
- reply.reply(response);
+ reply.payload(response);
}
else {
- errorReply(reply, "DMR mode is not enabled", HTTPReply::SERVICE_UNAVAILABLE);
+ errorPayload(reply, "DMR mode is not enabled", HTTPPayload::SERVICE_UNAVAILABLE);
}
}
#endif // defined(ENABLE_DMR)
@@ -677,10 +677,10 @@ void RESTAPI::restAPI_PutModemMode(const HTTPRequest& request, HTTPReply& reply,
uint8_t hostMode = m_host->m_state;
response["mode"].set(hostMode);
- reply.reply(response);
+ reply.payload(response);
}
else {
- errorReply(reply, "P25 mode is not enabled", HTTPReply::SERVICE_UNAVAILABLE);
+ errorPayload(reply, "P25 mode is not enabled", HTTPPayload::SERVICE_UNAVAILABLE);
}
}
#endif // defined(ENABLE_P25)
@@ -694,15 +694,15 @@ void RESTAPI::restAPI_PutModemMode(const HTTPRequest& request, HTTPReply& reply,
uint8_t hostMode = m_host->m_state;
response["mode"].set(hostMode);
- reply.reply(response);
+ reply.payload(response);
}
else {
- errorReply(reply, "NXDN mode is not enabled", HTTPReply::SERVICE_UNAVAILABLE);
+ errorPayload(reply, "NXDN mode is not enabled", HTTPPayload::SERVICE_UNAVAILABLE);
}
}
#endif // defined(ENABLE_NXDN)
else {
- errorReply(reply, "invalid mode");
+ errorPayload(reply, "invalid mode");
}
}
@@ -712,7 +712,7 @@ void RESTAPI::restAPI_PutModemMode(const HTTPRequest& request, HTTPReply& reply,
///
///
///
-void RESTAPI::restAPI_PutModemKill(const HTTPRequest& request, HTTPReply& reply, const RequestMatch& match)
+void RESTAPI::restAPI_PutModemKill(const HTTPPayload& request, HTTPPayload& reply, const RequestMatch& match)
{
if (!validateAuth(request, reply)) {
return;
@@ -723,7 +723,7 @@ void RESTAPI::restAPI_PutModemKill(const HTTPRequest& request, HTTPReply& reply,
return;
}
- errorReply(reply, "OK", HTTPReply::OK);
+ errorPayload(reply, "OK", HTTPPayload::OK);
if (!req["force"].is()) {
g_killed = true;
@@ -744,7 +744,7 @@ void RESTAPI::restAPI_PutModemKill(const HTTPRequest& request, HTTPReply& reply,
///
///
///
-void RESTAPI::restAPI_PutPermitTG(const HTTPRequest& request, HTTPReply& reply, const RequestMatch& match)
+void RESTAPI::restAPI_PutPermitTG(const HTTPPayload& request, HTTPPayload& reply, const RequestMatch& match)
{
if (!validateAuth(request, reply)) {
return;
@@ -755,16 +755,16 @@ void RESTAPI::restAPI_PutPermitTG(const HTTPRequest& request, HTTPReply& reply,
return;
}
- errorReply(reply, "OK", HTTPReply::OK);
+ errorPayload(reply, "OK", HTTPPayload::OK);
if (!m_host->m_authoritative) {
- errorReply(reply, "Host is authoritative, cannot permit TG");
+ errorPayload(reply, "Host is authoritative, cannot permit TG");
return;
}
// validate state is a string within the JSON blob
if (!req["state"].is()) {
- errorReply(reply, "state was not a valid integer");
+ errorPayload(reply, "state was not a valid integer");
return;
}
@@ -772,14 +772,14 @@ void RESTAPI::restAPI_PutPermitTG(const HTTPRequest& request, HTTPReply& reply,
// validate destination ID is a integer within the JSON blob
if (!req["dstId"].is()) {
- errorReply(reply, "destination ID was not a valid integer");
+ errorPayload(reply, "destination ID was not a valid integer");
return;
}
uint32_t dstId = req["dstId"].get();
if (dstId == 0U) {
- errorReply(reply, "destination ID is an illegal TGID");
+ errorPayload(reply, "destination ID is an illegal TGID");
return;
}
@@ -789,14 +789,14 @@ void RESTAPI::restAPI_PutPermitTG(const HTTPRequest& request, HTTPReply& reply,
{
// validate slot is a integer within the JSON blob
if (!req["slot"].is()) {
- errorReply(reply, "slot was not a valid integer");
+ errorPayload(reply, "slot was not a valid integer");
return;
}
uint8_t slot = (uint8_t)req["slot"].get();
if (slot == 0U || slot > 2U) {
- errorReply(reply, "illegal DMR slot");
+ errorPayload(reply, "illegal DMR slot");
return;
}
@@ -804,12 +804,12 @@ void RESTAPI::restAPI_PutPermitTG(const HTTPRequest& request, HTTPReply& reply,
m_dmr->permittedTG(dstId, slot);
}
else {
- errorReply(reply, "DMR mode is not enabled", HTTPReply::SERVICE_UNAVAILABLE);
+ errorPayload(reply, "DMR mode is not enabled", HTTPPayload::SERVICE_UNAVAILABLE);
}
}
#else
{
- errorReply(reply, "DMR operations are unavailable", HTTPReply::SERVICE_UNAVAILABLE);
+ errorPayload(reply, "DMR operations are unavailable", HTTPPayload::SERVICE_UNAVAILABLE);
}
#endif // defined(ENABLE_DMR)
break;
@@ -820,12 +820,12 @@ void RESTAPI::restAPI_PutPermitTG(const HTTPRequest& request, HTTPReply& reply,
m_p25->permittedTG(dstId);
}
else {
- errorReply(reply, "P25 mode is not enabled", HTTPReply::SERVICE_UNAVAILABLE);
+ errorPayload(reply, "P25 mode is not enabled", HTTPPayload::SERVICE_UNAVAILABLE);
}
}
#else
{
- errorReply(reply, "P25 operations are unavailable", HTTPReply::SERVICE_UNAVAILABLE);
+ errorPayload(reply, "P25 operations are unavailable", HTTPPayload::SERVICE_UNAVAILABLE);
}
#endif // defined(ENABLE_P25)
break;
@@ -836,17 +836,17 @@ void RESTAPI::restAPI_PutPermitTG(const HTTPRequest& request, HTTPReply& reply,
m_nxdn->permittedTG(dstId);
}
else {
- errorReply(reply, "NXDN mode is not enabled", HTTPReply::SERVICE_UNAVAILABLE);
+ errorPayload(reply, "NXDN mode is not enabled", HTTPPayload::SERVICE_UNAVAILABLE);
}
}
#else
{
- errorReply(reply, "NXDN operations are unavailable", HTTPReply::SERVICE_UNAVAILABLE);
+ errorPayload(reply, "NXDN operations are unavailable", HTTPPayload::SERVICE_UNAVAILABLE);
}
#endif // defined(ENABLE_NXDN)
break;
default:
- errorReply(reply, "invalid mode");
+ errorPayload(reply, "invalid mode");
break;
}
}
@@ -857,7 +857,7 @@ void RESTAPI::restAPI_PutPermitTG(const HTTPRequest& request, HTTPReply& reply,
///
///
///
-void RESTAPI::restAPI_PutGrantTG(const HTTPRequest& request, HTTPReply& reply, const RequestMatch& match)
+void RESTAPI::restAPI_PutGrantTG(const HTTPPayload& request, HTTPPayload& reply, const RequestMatch& match)
{
if (!validateAuth(request, reply)) {
return;
@@ -868,16 +868,16 @@ void RESTAPI::restAPI_PutGrantTG(const HTTPRequest& request, HTTPReply& reply, c
return;
}
- errorReply(reply, "OK", HTTPReply::OK);
+ errorPayload(reply, "OK", HTTPPayload::OK);
if (m_host->m_authoritative && (m_host->m_dmrCtrlChannel || m_host->m_p25CtrlChannel || m_host->m_nxdnCtrlChannel)) {
- errorReply(reply, "Host is authoritative, cannot grant TG");
+ errorPayload(reply, "Host is authoritative, cannot grant TG");
return;
}
// validate state is a string within the JSON blob
if (!req["state"].is()) {
- errorReply(reply, "state was not a valid integer");
+ errorPayload(reply, "state was not a valid integer");
return;
}
@@ -885,27 +885,27 @@ void RESTAPI::restAPI_PutGrantTG(const HTTPRequest& request, HTTPReply& reply, c
// validate destination ID is a integer within the JSON blob
if (!req["dstId"].is()) {
- errorReply(reply, "destination ID was not a valid integer");
+ errorPayload(reply, "destination ID was not a valid integer");
return;
}
uint32_t dstId = req["dstId"].get();
if (dstId == 0U) {
- errorReply(reply, "destination ID is an illegal TGID");
+ errorPayload(reply, "destination ID is an illegal TGID");
return;
}
// validate unit-to-unit is a integer within the JSON blob
if (!req["unitToUnit"].is()) {
- errorReply(reply, "unit-to-unit was not a valid integer");
+ errorPayload(reply, "unit-to-unit was not a valid integer");
return;
}
uint8_t unitToUnit = (uint8_t)req["unitToUnit"].get();
if (unitToUnit > 1U) {
- errorReply(reply, "unit-to-unit must be a 0 or 1");
+ errorPayload(reply, "unit-to-unit must be a 0 or 1");
return;
}
@@ -915,14 +915,14 @@ void RESTAPI::restAPI_PutGrantTG(const HTTPRequest& request, HTTPReply& reply, c
{
// validate slot is a integer within the JSON blob
if (!req["slot"].is()) {
- errorReply(reply, "slot was not a valid integer");
+ errorPayload(reply, "slot was not a valid integer");
return;
}
uint8_t slot = (uint8_t)req["slot"].get();
if (slot == 0U || slot > 2U) {
- errorReply(reply, "illegal DMR slot");
+ errorPayload(reply, "illegal DMR slot");
return;
}
@@ -931,12 +931,12 @@ void RESTAPI::restAPI_PutGrantTG(const HTTPRequest& request, HTTPReply& reply, c
//m_dmr->grantTG(dstId, slot, unitToUnit == 1U);
}
else {
- errorReply(reply, "DMR mode is not enabled", HTTPReply::SERVICE_UNAVAILABLE);
+ errorPayload(reply, "DMR mode is not enabled", HTTPPayload::SERVICE_UNAVAILABLE);
}
}
#else
{
- errorReply(reply, "DMR operations are unavailable", HTTPReply::SERVICE_UNAVAILABLE);
+ errorPayload(reply, "DMR operations are unavailable", HTTPPayload::SERVICE_UNAVAILABLE);
}
#endif // defined(ENABLE_DMR)
break;
@@ -948,12 +948,12 @@ void RESTAPI::restAPI_PutGrantTG(const HTTPRequest& request, HTTPReply& reply, c
//m_p25->grantTG(dstId, unitToUnit == 1U);
}
else {
- errorReply(reply, "P25 mode is not enabled", HTTPReply::SERVICE_UNAVAILABLE);
+ errorPayload(reply, "P25 mode is not enabled", HTTPPayload::SERVICE_UNAVAILABLE);
}
}
#else
{
- errorReply(reply, "P25 operations are unavailable", HTTPReply::SERVICE_UNAVAILABLE);
+ errorPayload(reply, "P25 operations are unavailable", HTTPPayload::SERVICE_UNAVAILABLE);
}
#endif // defined(ENABLE_P25)
break;
@@ -965,17 +965,17 @@ void RESTAPI::restAPI_PutGrantTG(const HTTPRequest& request, HTTPReply& reply, c
//nxdn->grantTG(dstId, unitToUnit == 1U);
}
else {
- errorReply(reply, "NXDN mode is not enabled", HTTPReply::SERVICE_UNAVAILABLE);
+ errorPayload(reply, "NXDN mode is not enabled", HTTPPayload::SERVICE_UNAVAILABLE);
}
}
#else
{
- errorReply(reply, "NXDN operations are unavailable", HTTPReply::SERVICE_UNAVAILABLE);
+ errorPayload(reply, "NXDN operations are unavailable", HTTPPayload::SERVICE_UNAVAILABLE);
}
#endif // defined(ENABLE_NXDN)
break;
default:
- errorReply(reply, "invalid mode");
+ errorPayload(reply, "invalid mode");
}
}
@@ -985,13 +985,13 @@ void RESTAPI::restAPI_PutGrantTG(const HTTPRequest& request, HTTPReply& reply, c
///
///
///
-void RESTAPI::restAPI_GetReleaseGrants(const HTTPRequest& request, HTTPReply& reply, const RequestMatch& match)
+void RESTAPI::restAPI_GetReleaseGrants(const HTTPPayload& request, HTTPPayload& reply, const RequestMatch& match)
{
if (!validateAuth(request, reply)) {
return;
}
- errorReply(reply, "OK", HTTPReply::OK);
+ errorPayload(reply, "OK", HTTPPayload::OK);
#if defined(ENABLE_DMR)
if (m_dmr != nullptr) {
m_dmr->affiliations().releaseGrant(0, true);
@@ -1015,13 +1015,13 @@ void RESTAPI::restAPI_GetReleaseGrants(const HTTPRequest& request, HTTPReply& re
///
///
///
-void RESTAPI::restAPI_GetReleaseAffs(const HTTPRequest& request, HTTPReply& reply, const RequestMatch& match)
+void RESTAPI::restAPI_GetReleaseAffs(const HTTPPayload& request, HTTPPayload& reply, const RequestMatch& match)
{
if (!validateAuth(request, reply)) {
return;
}
- errorReply(reply, "OK", HTTPReply::OK);
+ errorPayload(reply, "OK", HTTPPayload::OK);
#if defined(ENABLE_DMR)
if (m_dmr != nullptr) {
m_dmr->affiliations().clearGroupAff(0, true);
@@ -1045,25 +1045,25 @@ void RESTAPI::restAPI_GetReleaseAffs(const HTTPRequest& request, HTTPReply& repl
///
///
///
-void RESTAPI::restAPI_GetRIDWhitelist(const HTTPRequest& request, HTTPReply& reply, const RequestMatch& match)
+void RESTAPI::restAPI_GetRIDWhitelist(const HTTPPayload& request, HTTPPayload& reply, const RequestMatch& match)
{
if (!validateAuth(request, reply)) {
return;
}
if (match.size() < 2) {
- errorReply(reply, "invalid API call arguments");
+ errorPayload(reply, "invalid API call arguments");
return;
}
- errorReply(reply, "OK", HTTPReply::OK);
+ errorPayload(reply, "OK", HTTPPayload::OK);
uint32_t srcId = (uint32_t)::strtoul(match.str(1).c_str(), NULL, 10);
if (srcId != 0U) {
m_ridLookup->toggleEntry(srcId, true);
}
else {
- errorReply(reply, "tried to whitelist RID 0");
+ errorPayload(reply, "tried to whitelist RID 0");
}
}
@@ -1073,25 +1073,25 @@ void RESTAPI::restAPI_GetRIDWhitelist(const HTTPRequest& request, HTTPReply& rep
///
///
///
-void RESTAPI::restAPI_GetRIDBlacklist(const HTTPRequest& request, HTTPReply& reply, const RequestMatch& match)
+void RESTAPI::restAPI_GetRIDBlacklist(const HTTPPayload& request, HTTPPayload& reply, const RequestMatch& match)
{
if (!validateAuth(request, reply)) {
return;
}
if (match.size() < 2) {
- errorReply(reply, "invalid API call arguments");
+ errorPayload(reply, "invalid API call arguments");
return;
}
- errorReply(reply, "OK", HTTPReply::OK);
+ errorPayload(reply, "OK", HTTPPayload::OK);
uint32_t srcId = (uint32_t)::strtoul(match.str(1).c_str(), NULL, 10);
if (srcId != 0U) {
m_ridLookup->toggleEntry(srcId, false);
}
else {
- errorReply(reply, "tried to blacklist RID 0");
+ errorPayload(reply, "tried to blacklist RID 0");
}
}
@@ -1105,29 +1105,29 @@ void RESTAPI::restAPI_GetRIDBlacklist(const HTTPRequest& request, HTTPReply& rep
///
///
///
-void RESTAPI::restAPI_GetDMRBeacon(const HTTPRequest& request, HTTPReply& reply, const RequestMatch& match)
+void RESTAPI::restAPI_GetDMRBeacon(const HTTPPayload& request, HTTPPayload& reply, const RequestMatch& match)
{
if (!validateAuth(request, reply)) {
return;
}
#if defined(ENABLE_DMR)
- errorReply(reply, "OK", HTTPReply::OK);
+ errorPayload(reply, "OK", HTTPPayload::OK);
if (m_dmr != nullptr) {
if (m_host->m_dmrBeacons) {
g_fireDMRBeacon = true;
}
else {
- errorReply(reply, "DMR beacons are not enabled", HTTPReply::SERVICE_UNAVAILABLE);
+ errorPayload(reply, "DMR beacons are not enabled", HTTPPayload::SERVICE_UNAVAILABLE);
return;
}
}
else {
- errorReply(reply, "DMR mode is not enabled", HTTPReply::SERVICE_UNAVAILABLE);
+ errorPayload(reply, "DMR mode is not enabled", HTTPPayload::SERVICE_UNAVAILABLE);
return;
}
#else
- errorReply(reply, "DMR operations are unavailable", HTTPReply::SERVICE_UNAVAILABLE);
+ errorPayload(reply, "DMR operations are unavailable", HTTPPayload::SERVICE_UNAVAILABLE);
#endif // defined(ENABLE_DMR)
}
@@ -1137,7 +1137,7 @@ void RESTAPI::restAPI_GetDMRBeacon(const HTTPRequest& request, HTTPReply& reply,
///
///
///
-void RESTAPI::restAPI_GetDMRDebug(const HTTPRequest& request, HTTPReply& reply, const RequestMatch& match)
+void RESTAPI::restAPI_GetDMRDebug(const HTTPPayload& request, HTTPPayload& reply, const RequestMatch& match)
{
if (!validateAuth(request, reply)) {
return;
@@ -1146,7 +1146,7 @@ void RESTAPI::restAPI_GetDMRDebug(const HTTPRequest& request, HTTPReply& reply,
json::object response = json::object();
setResponseDefaultStatus(response);
#if defined(ENABLE_DMR)
- errorReply(reply, "OK", HTTPReply::OK);
+ errorPayload(reply, "OK", HTTPPayload::OK);
if (m_dmr != nullptr) {
if (match.size() <= 1) {
bool debug = m_dmr->getDebug();
@@ -1155,7 +1155,7 @@ void RESTAPI::restAPI_GetDMRDebug(const HTTPRequest& request, HTTPReply& reply,
response["debug"].set(debug);
response["verbose"].set(verbose);
- reply.reply(response);
+ reply.payload(response);
return;
}
else {
@@ -1167,11 +1167,11 @@ void RESTAPI::restAPI_GetDMRDebug(const HTTPRequest& request, HTTPReply& reply,
}
}
else {
- errorReply(reply, "DMR mode is not enabled", HTTPReply::SERVICE_UNAVAILABLE);
+ errorPayload(reply, "DMR mode is not enabled", HTTPPayload::SERVICE_UNAVAILABLE);
return;
}
#else
- errorReply(reply, "DMR operations are unavailable", HTTPReply::SERVICE_UNAVAILABLE);
+ errorPayload(reply, "DMR operations are unavailable", HTTPPayload::SERVICE_UNAVAILABLE);
#endif // defined(ENABLE_DMR)
}
@@ -1181,7 +1181,7 @@ void RESTAPI::restAPI_GetDMRDebug(const HTTPRequest& request, HTTPReply& reply,
///
///
///
-void RESTAPI::restAPI_GetDMRDumpCSBK(const HTTPRequest& request, HTTPReply& reply, const RequestMatch& match)
+void RESTAPI::restAPI_GetDMRDumpCSBK(const HTTPPayload& request, HTTPPayload& reply, const RequestMatch& match)
{
if (!validateAuth(request, reply)) {
return;
@@ -1190,14 +1190,14 @@ void RESTAPI::restAPI_GetDMRDumpCSBK(const HTTPRequest& request, HTTPReply& repl
json::object response = json::object();
setResponseDefaultStatus(response);
#if defined(ENABLE_DMR)
- errorReply(reply, "OK", HTTPReply::OK);
+ errorPayload(reply, "OK", HTTPPayload::OK);
if (m_dmr != nullptr) {
if (match.size() <= 1) {
bool csbkDump = m_dmr->getCSBKVerbose();
response["verbose"].set(csbkDump);
- reply.reply(response);
+ reply.payload(response);
return;
}
else {
@@ -1208,11 +1208,11 @@ void RESTAPI::restAPI_GetDMRDumpCSBK(const HTTPRequest& request, HTTPReply& repl
}
}
else {
- errorReply(reply, "DMR mode is not enabled", HTTPReply::SERVICE_UNAVAILABLE);
+ errorPayload(reply, "DMR mode is not enabled", HTTPPayload::SERVICE_UNAVAILABLE);
return;
}
#else
- errorReply(reply, "DMR operations are unavailable", HTTPReply::SERVICE_UNAVAILABLE);
+ errorPayload(reply, "DMR operations are unavailable", HTTPPayload::SERVICE_UNAVAILABLE);
#endif // defined(ENABLE_DMR)
}
@@ -1222,7 +1222,7 @@ void RESTAPI::restAPI_GetDMRDumpCSBK(const HTTPRequest& request, HTTPReply& repl
///
///
///
-void RESTAPI::restAPI_PutDMRRID(const HTTPRequest& request, HTTPReply& reply, const RequestMatch& match)
+void RESTAPI::restAPI_PutDMRRID(const HTTPPayload& request, HTTPPayload& reply, const RequestMatch& match)
{
if (!validateAuth(request, reply)) {
return;
@@ -1233,7 +1233,7 @@ void RESTAPI::restAPI_PutDMRRID(const HTTPRequest& request, HTTPReply& reply, co
return;
}
- errorReply(reply, "OK", HTTPReply::OK);
+ errorPayload(reply, "OK", HTTPPayload::OK);
}
///
@@ -1242,18 +1242,18 @@ void RESTAPI::restAPI_PutDMRRID(const HTTPRequest& request, HTTPReply& reply, co
///
///
///
-void RESTAPI::restAPI_GetDMRCCEnable(const HTTPRequest& request, HTTPReply& reply, const RequestMatch& match)
+void RESTAPI::restAPI_GetDMRCCEnable(const HTTPPayload& request, HTTPPayload& reply, const RequestMatch& match)
{
if (!validateAuth(request, reply)) {
return;
}
if (match.size() < 2) {
- errorReply(reply, "invalid API call arguments");
+ errorPayload(reply, "invalid API call arguments");
return;
}
- errorReply(reply, "OK", HTTPReply::OK);
+ errorPayload(reply, "OK", HTTPPayload::OK);
}
///
@@ -1262,18 +1262,18 @@ void RESTAPI::restAPI_GetDMRCCEnable(const HTTPRequest& request, HTTPReply& repl
///
///
///
-void RESTAPI::restAPI_GetDMRCCBroadcast(const HTTPRequest& request, HTTPReply& reply, const RequestMatch& match)
+void RESTAPI::restAPI_GetDMRCCBroadcast(const HTTPPayload& request, HTTPPayload& reply, const RequestMatch& match)
{
if (!validateAuth(request, reply)) {
return;
}
if (match.size() < 2) {
- errorReply(reply, "invalid API call arguments");
+ errorPayload(reply, "invalid API call arguments");
return;
}
- errorReply(reply, "OK", HTTPReply::OK);
+ errorPayload(reply, "OK", HTTPPayload::OK);
}
/*
@@ -1286,29 +1286,29 @@ void RESTAPI::restAPI_GetDMRCCBroadcast(const HTTPRequest& request, HTTPReply& r
///
///
///
-void RESTAPI::restAPI_GetP25CC(const HTTPRequest& request, HTTPReply& reply, const RequestMatch& match)
+void RESTAPI::restAPI_GetP25CC(const HTTPPayload& request, HTTPPayload& reply, const RequestMatch& match)
{
if (!validateAuth(request, reply)) {
return;
}
#if defined(ENABLE_P25)
- errorReply(reply, "OK", HTTPReply::OK);
+ errorPayload(reply, "OK", HTTPPayload::OK);
if (m_p25 != nullptr) {
if (m_host->m_p25CCData) {
g_fireP25Control = true;
}
else {
- errorReply(reply, "P25 control data is not enabled", HTTPReply::SERVICE_UNAVAILABLE);
+ errorPayload(reply, "P25 control data is not enabled", HTTPPayload::SERVICE_UNAVAILABLE);
return;
}
}
else {
- errorReply(reply, "P25 mode is not enabled", HTTPReply::SERVICE_UNAVAILABLE);
+ errorPayload(reply, "P25 mode is not enabled", HTTPPayload::SERVICE_UNAVAILABLE);
return;
}
#else
- errorReply(reply, "P25 operations are unavailable", HTTPReply::SERVICE_UNAVAILABLE);
+ errorPayload(reply, "P25 operations are unavailable", HTTPPayload::SERVICE_UNAVAILABLE);
#endif // defined(ENABLE_P25)
}
@@ -1318,7 +1318,7 @@ void RESTAPI::restAPI_GetP25CC(const HTTPRequest& request, HTTPReply& reply, con
///
///
///
-void RESTAPI::restAPI_GetP25Debug(const HTTPRequest& request, HTTPReply& reply, const RequestMatch& match)
+void RESTAPI::restAPI_GetP25Debug(const HTTPPayload& request, HTTPPayload& reply, const RequestMatch& match)
{
if (!validateAuth(request, reply)) {
return;
@@ -1327,7 +1327,7 @@ void RESTAPI::restAPI_GetP25Debug(const HTTPRequest& request, HTTPReply& reply,
json::object response = json::object();
setResponseDefaultStatus(response);
#if defined(ENABLE_P25)
- errorReply(reply, "OK", HTTPReply::OK);
+ errorPayload(reply, "OK", HTTPPayload::OK);
if (m_dmr != nullptr) {
if (match.size() <= 1) {
bool debug = m_p25->getDebug();
@@ -1336,7 +1336,7 @@ void RESTAPI::restAPI_GetP25Debug(const HTTPRequest& request, HTTPReply& reply,
response["debug"].set(debug);
response["verbose"].set(verbose);
- reply.reply(response);
+ reply.payload(response);
return;
}
else {
@@ -1348,11 +1348,11 @@ void RESTAPI::restAPI_GetP25Debug(const HTTPRequest& request, HTTPReply& reply,
}
}
else {
- errorReply(reply, "P25 mode is not enabled", HTTPReply::SERVICE_UNAVAILABLE);
+ errorPayload(reply, "P25 mode is not enabled", HTTPPayload::SERVICE_UNAVAILABLE);
return;
}
#else
- errorReply(reply, "P25 operations are unavailable", HTTPReply::SERVICE_UNAVAILABLE);
+ errorPayload(reply, "P25 operations are unavailable", HTTPPayload::SERVICE_UNAVAILABLE);
#endif // defined(ENABLE_P25)
}
@@ -1362,7 +1362,7 @@ void RESTAPI::restAPI_GetP25Debug(const HTTPRequest& request, HTTPReply& reply,
///
///
///
-void RESTAPI::restAPI_GetP25DumpTSBK(const HTTPRequest& request, HTTPReply& reply, const RequestMatch& match)
+void RESTAPI::restAPI_GetP25DumpTSBK(const HTTPPayload& request, HTTPPayload& reply, const RequestMatch& match)
{
if (!validateAuth(request, reply)) {
return;
@@ -1371,14 +1371,14 @@ void RESTAPI::restAPI_GetP25DumpTSBK(const HTTPRequest& request, HTTPReply& repl
json::object response = json::object();
setResponseDefaultStatus(response);
#if defined(ENABLE_P25)
- errorReply(reply, "OK", HTTPReply::OK);
+ errorPayload(reply, "OK", HTTPPayload::OK);
if (m_p25 != nullptr) {
if (match.size() <= 1) {
bool tsbkDump = m_p25->trunk()->getTSBKVerbose();
response["verbose"].set(tsbkDump);
- reply.reply(response);
+ reply.payload(response);
return;
}
else {
@@ -1389,11 +1389,11 @@ void RESTAPI::restAPI_GetP25DumpTSBK(const HTTPRequest& request, HTTPReply& repl
}
}
else {
- errorReply(reply, "P25 mode is not enabled", HTTPReply::SERVICE_UNAVAILABLE);
+ errorPayload(reply, "P25 mode is not enabled", HTTPPayload::SERVICE_UNAVAILABLE);
return;
}
#else
- errorReply(reply, "P25 operations are unavailable", HTTPReply::SERVICE_UNAVAILABLE);
+ errorPayload(reply, "P25 operations are unavailable", HTTPPayload::SERVICE_UNAVAILABLE);
#endif // defined(ENABLE_P25)
}
@@ -1403,7 +1403,7 @@ void RESTAPI::restAPI_GetP25DumpTSBK(const HTTPRequest& request, HTTPReply& repl
///
///
///
-void RESTAPI::restAPI_PutP25RID(const HTTPRequest& request, HTTPReply& reply, const RequestMatch& match)
+void RESTAPI::restAPI_PutP25RID(const HTTPPayload& request, HTTPPayload& reply, const RequestMatch& match)
{
if (!validateAuth(request, reply)) {
return;
@@ -1414,7 +1414,7 @@ void RESTAPI::restAPI_PutP25RID(const HTTPRequest& request, HTTPReply& reply, co
return;
}
- errorReply(reply, "OK", HTTPReply::OK);
+ errorPayload(reply, "OK", HTTPPayload::OK);
}
///
@@ -1423,18 +1423,18 @@ void RESTAPI::restAPI_PutP25RID(const HTTPRequest& request, HTTPReply& reply, co
///
///
///
-void RESTAPI::restAPI_GetP25CCEnable(const HTTPRequest& request, HTTPReply& reply, const RequestMatch& match)
+void RESTAPI::restAPI_GetP25CCEnable(const HTTPPayload& request, HTTPPayload& reply, const RequestMatch& match)
{
if (!validateAuth(request, reply)) {
return;
}
if (match.size() < 2) {
- errorReply(reply, "invalid API call arguments");
+ errorPayload(reply, "invalid API call arguments");
return;
}
- errorReply(reply, "OK", HTTPReply::OK);
+ errorPayload(reply, "OK", HTTPPayload::OK);
}
///
@@ -1443,18 +1443,18 @@ void RESTAPI::restAPI_GetP25CCEnable(const HTTPRequest& request, HTTPReply& repl
///
///
///
-void RESTAPI::restAPI_GetP25CCBroadcast(const HTTPRequest& request, HTTPReply& reply, const RequestMatch& match)
+void RESTAPI::restAPI_GetP25CCBroadcast(const HTTPPayload& request, HTTPPayload& reply, const RequestMatch& match)
{
if (!validateAuth(request, reply)) {
return;
}
if (match.size() < 2) {
- errorReply(reply, "invalid API call arguments");
+ errorPayload(reply, "invalid API call arguments");
return;
}
- errorReply(reply, "OK", HTTPReply::OK);
+ errorPayload(reply, "OK", HTTPPayload::OK);
}
/*
@@ -1467,7 +1467,7 @@ void RESTAPI::restAPI_GetP25CCBroadcast(const HTTPRequest& request, HTTPReply& r
///
///
///
-void RESTAPI::restAPI_GetNXDNDebug(const HTTPRequest& request, HTTPReply& reply, const RequestMatch& match)
+void RESTAPI::restAPI_GetNXDNDebug(const HTTPPayload& request, HTTPPayload& reply, const RequestMatch& match)
{
if (!validateAuth(request, reply)) {
return;
@@ -1476,7 +1476,7 @@ void RESTAPI::restAPI_GetNXDNDebug(const HTTPRequest& request, HTTPReply& reply,
json::object response = json::object();
setResponseDefaultStatus(response);
#if defined(ENABLE_NXDN)
- errorReply(reply, "OK", HTTPReply::OK);
+ errorPayload(reply, "OK", HTTPPayload::OK);
if (m_dmr != nullptr) {
if (match.size() <= 1) {
bool debug = m_nxdn->getDebug();
@@ -1485,7 +1485,7 @@ void RESTAPI::restAPI_GetNXDNDebug(const HTTPRequest& request, HTTPReply& reply,
response["debug"].set(debug);
response["verbose"].set(verbose);
- reply.reply(response);
+ reply.payload(response);
return;
}
else {
@@ -1497,11 +1497,11 @@ void RESTAPI::restAPI_GetNXDNDebug(const HTTPRequest& request, HTTPReply& reply,
}
}
else {
- errorReply(reply, "NXDN mode is not enabled", HTTPReply::SERVICE_UNAVAILABLE);
+ errorPayload(reply, "NXDN mode is not enabled", HTTPPayload::SERVICE_UNAVAILABLE);
return;
}
#else
- errorReply(reply, "NXDN operations are unavailable", HTTPReply::SERVICE_UNAVAILABLE);
+ errorPayload(reply, "NXDN operations are unavailable", HTTPPayload::SERVICE_UNAVAILABLE);
#endif // defined(ENABLE_NXDN)
}
@@ -1511,7 +1511,7 @@ void RESTAPI::restAPI_GetNXDNDebug(const HTTPRequest& request, HTTPReply& reply,
///
///
///
-void RESTAPI::restAPI_GetNXDNDumpRCCH(const HTTPRequest& request, HTTPReply& reply, const RequestMatch& match)
+void RESTAPI::restAPI_GetNXDNDumpRCCH(const HTTPPayload& request, HTTPPayload& reply, const RequestMatch& match)
{
if (!validateAuth(request, reply)) {
return;
@@ -1520,14 +1520,14 @@ void RESTAPI::restAPI_GetNXDNDumpRCCH(const HTTPRequest& request, HTTPReply& rep
json::object response = json::object();
setResponseDefaultStatus(response);
#if defined(ENABLE_NXDN)
- errorReply(reply, "OK", HTTPReply::OK);
+ errorPayload(reply, "OK", HTTPPayload::OK);
if (m_p25 != nullptr) {
if (match.size() <= 1) {
bool rcchDump = m_nxdn->getRCCHVerbose();
response["verbose"].set(rcchDump);
- reply.reply(response);
+ reply.payload(response);
return;
}
else {
@@ -1538,10 +1538,10 @@ void RESTAPI::restAPI_GetNXDNDumpRCCH(const HTTPRequest& request, HTTPReply& rep
}
}
else {
- errorReply(reply, "NXDN mode is not enabled", HTTPReply::SERVICE_UNAVAILABLE);
+ errorPayload(reply, "NXDN mode is not enabled", HTTPPayload::SERVICE_UNAVAILABLE);
return;
}
#else
- errorReply(reply, "NXDN operations are unavailable", HTTPReply::SERVICE_UNAVAILABLE);
+ errorPayload(reply, "NXDN operations are unavailable", HTTPPayload::SERVICE_UNAVAILABLE);
#endif // defined(ENABLE_NXDN)
}
diff --git a/network/RESTAPI.h b/network/RESTAPI.h
index ab45018f..cc39f903 100644
--- a/network/RESTAPI.h
+++ b/network/RESTAPI.h
@@ -118,9 +118,8 @@ public:
void close();
private:
- typedef network::rest::RequestDispatcher RESTDispatcherType;
- typedef network::rest::http::HTTPRequest HTTPRequest;
- typedef network::rest::http::HTTPReply HTTPReply;
+ typedef network::rest::RequestDispatcher RESTDispatcherType;
+ typedef network::rest::http::HTTPPayload HTTPPayload;
RESTDispatcherType m_dispatcher;
network::rest::http::HTTPServer m_restServer;
@@ -152,79 +151,79 @@ private:
///
void invalidateHostToken(const std::string host);
///
- bool validateAuth(const HTTPRequest& request, HTTPReply& reply);
+ bool validateAuth(const HTTPPayload& request, HTTPPayload& reply);
///
- void restAPI_PutAuth(const HTTPRequest& request, HTTPReply& reply, const network::rest::RequestMatch& match);
+ void restAPI_PutAuth(const HTTPPayload& request, HTTPPayload& reply, const network::rest::RequestMatch& match);
///
- void restAPI_GetVersion(const HTTPRequest& request, HTTPReply& reply, const network::rest::RequestMatch& match);
+ void restAPI_GetVersion(const HTTPPayload& request, HTTPPayload& reply, const network::rest::RequestMatch& match);
///
- void restAPI_GetStatus(const HTTPRequest& request, HTTPReply& reply, const network::rest::RequestMatch& match);
+ void restAPI_GetStatus(const HTTPPayload& request, HTTPPayload& reply, const network::rest::RequestMatch& match);
///
- void restAPI_GetVoiceCh(const HTTPRequest& request, HTTPReply& reply, const network::rest::RequestMatch& match);
+ void restAPI_GetVoiceCh(const HTTPPayload& request, HTTPPayload& reply, const network::rest::RequestMatch& match);
///
- void restAPI_PutModemMode(const HTTPRequest& request, HTTPReply& reply, const network::rest::RequestMatch& match);
+ void restAPI_PutModemMode(const HTTPPayload& request, HTTPPayload& reply, const network::rest::RequestMatch& match);
///
- void restAPI_PutModemKill(const HTTPRequest& request, HTTPReply& reply, const network::rest::RequestMatch& match);
+ void restAPI_PutModemKill(const HTTPPayload& request, HTTPPayload& reply, const network::rest::RequestMatch& match);
///
- void restAPI_PutPermitTG(const HTTPRequest& request, HTTPReply& reply, const network::rest::RequestMatch& match);
+ void restAPI_PutPermitTG(const HTTPPayload& request, HTTPPayload& reply, const network::rest::RequestMatch& match);
///
- void restAPI_PutGrantTG(const HTTPRequest& request, HTTPReply& reply, const network::rest::RequestMatch& match);
+ void restAPI_PutGrantTG(const HTTPPayload& request, HTTPPayload& reply, const network::rest::RequestMatch& match);
///
- void restAPI_GetReleaseGrants(const HTTPRequest& request, HTTPReply& reply, const network::rest::RequestMatch& match);
+ void restAPI_GetReleaseGrants(const HTTPPayload& request, HTTPPayload& reply, const network::rest::RequestMatch& match);
///
- void restAPI_GetReleaseAffs(const HTTPRequest& request, HTTPReply& reply, const network::rest::RequestMatch& match);
+ void restAPI_GetReleaseAffs(const HTTPPayload& request, HTTPPayload& reply, const network::rest::RequestMatch& match);
///
- void restAPI_GetRIDWhitelist(const HTTPRequest& request, HTTPReply& reply, const network::rest::RequestMatch& match);
+ void restAPI_GetRIDWhitelist(const HTTPPayload& request, HTTPPayload& reply, const network::rest::RequestMatch& match);
///
- void restAPI_GetRIDBlacklist(const HTTPRequest& request, HTTPReply& reply, const network::rest::RequestMatch& match);
+ void restAPI_GetRIDBlacklist(const HTTPPayload& request, HTTPPayload& reply, const network::rest::RequestMatch& match);
/*
** Digital Mobile Radio
*/
///
- void restAPI_GetDMRBeacon(const HTTPRequest& request, HTTPReply& reply, const network::rest::RequestMatch& match);
+ void restAPI_GetDMRBeacon(const HTTPPayload& request, HTTPPayload& reply, const network::rest::RequestMatch& match);
///
- void restAPI_GetDMRDebug(const HTTPRequest& request, HTTPReply& reply, const network::rest::RequestMatch& match);
+ void restAPI_GetDMRDebug(const HTTPPayload& request, HTTPPayload& reply, const network::rest::RequestMatch& match);
///
- void restAPI_GetDMRDumpCSBK(const HTTPRequest& request, HTTPReply& reply, const network::rest::RequestMatch& match);
+ void restAPI_GetDMRDumpCSBK(const HTTPPayload& request, HTTPPayload& reply, const network::rest::RequestMatch& match);
///
- void restAPI_PutDMRRID(const HTTPRequest& request, HTTPReply& reply, const network::rest::RequestMatch& match);
+ void restAPI_PutDMRRID(const HTTPPayload& request, HTTPPayload& reply, const network::rest::RequestMatch& match);
///
- void restAPI_GetDMRCCEnable(const HTTPRequest& request, HTTPReply& reply, const network::rest::RequestMatch& match);
+ void restAPI_GetDMRCCEnable(const HTTPPayload& request, HTTPPayload& reply, const network::rest::RequestMatch& match);
///
- void restAPI_GetDMRCCBroadcast(const HTTPRequest& request, HTTPReply& reply, const network::rest::RequestMatch& match);
+ void restAPI_GetDMRCCBroadcast(const HTTPPayload& request, HTTPPayload& reply, const network::rest::RequestMatch& match);
/*
** Project 25
*/
///
- void restAPI_GetP25CC(const HTTPRequest& request, HTTPReply& reply, const network::rest::RequestMatch& match);
+ void restAPI_GetP25CC(const HTTPPayload& request, HTTPPayload& reply, const network::rest::RequestMatch& match);
///
- void restAPI_GetP25Debug(const HTTPRequest& request, HTTPReply& reply, const network::rest::RequestMatch& match);
+ void restAPI_GetP25Debug(const HTTPPayload& request, HTTPPayload& reply, const network::rest::RequestMatch& match);
///
- void restAPI_GetP25DumpTSBK(const HTTPRequest& request, HTTPReply& reply, const network::rest::RequestMatch& match);
+ void restAPI_GetP25DumpTSBK(const HTTPPayload& request, HTTPPayload& reply, const network::rest::RequestMatch& match);
///
- void restAPI_PutP25RID(const HTTPRequest& request, HTTPReply& reply, const network::rest::RequestMatch& match);
+ void restAPI_PutP25RID(const HTTPPayload& request, HTTPPayload& reply, const network::rest::RequestMatch& match);
///
- void restAPI_GetP25CCEnable(const HTTPRequest& request, HTTPReply& reply, const network::rest::RequestMatch& match);
+ void restAPI_GetP25CCEnable(const HTTPPayload& request, HTTPPayload& reply, const network::rest::RequestMatch& match);
///
- void restAPI_GetP25CCBroadcast(const HTTPRequest& request, HTTPReply& reply, const network::rest::RequestMatch& match);
+ void restAPI_GetP25CCBroadcast(const HTTPPayload& request, HTTPPayload& reply, const network::rest::RequestMatch& match);
/*
** Next Generation Digital Narrowband
*/
///
- void restAPI_GetNXDNDebug(const HTTPRequest& request, HTTPReply& reply, const network::rest::RequestMatch& match);
+ void restAPI_GetNXDNDebug(const HTTPPayload& request, HTTPPayload& reply, const network::rest::RequestMatch& match);
///
- void restAPI_GetNXDNDumpRCCH(const HTTPRequest& request, HTTPReply& reply, const network::rest::RequestMatch& match);
+ void restAPI_GetNXDNDumpRCCH(const HTTPPayload& request, HTTPPayload& reply, const network::rest::RequestMatch& match);
};
#endif // __REST_API_H__
diff --git a/network/rest/RequestDispatcher.h b/network/rest/RequestDispatcher.h
index 5d76f20c..d5aa3a54 100644
--- a/network/rest/RequestDispatcher.h
+++ b/network/rest/RequestDispatcher.h
@@ -27,8 +27,7 @@
#define __REST__DISPATCHER_H__
#include "Defines.h"
-#include "network/rest/http/HTTPRequest.h"
-#include "network/rest/http/HTTPReply.h"
+#include "network/rest/http/HTTPPayload.h"
#include "Log.h"
#include
@@ -68,27 +67,27 @@ namespace network
///
RequestMatcher& get(RequestHandlerType handler) {
- m_handlers["GET"] = handler;
+ m_handlers[HTTP_GET] = handler;
return *this;
}
///
RequestMatcher& post(RequestHandlerType handler) {
- m_handlers["POST"] = handler;
+ m_handlers[HTTP_POST] = handler;
return *this;
}
///
RequestMatcher& put(RequestHandlerType handler) {
- m_handlers["PUT"] = handler;
+ m_handlers[HTTP_PUT] = handler;
return *this;
}
///
RequestMatcher& del(RequestHandlerType handler) {
- m_handlers["DELETE"] = handler;
+ m_handlers[HTTP_DELETE] = handler;
return *this;
}
///
RequestMatcher& options(RequestHandlerType handler) {
- m_handlers["OPTIONS"] = handler;
+ m_handlers[HTTP_OPTIONS] = handler;
return *this;
}
@@ -116,7 +115,7 @@ namespace network
// This class implements RESTful web request dispatching.
// ---------------------------------------------------------------------------
- template
+ template
class RequestDispatcher {
typedef RequestMatcher MatcherType;
public:
@@ -174,7 +173,7 @@ namespace network
}
::LogError(LOG_REST, "unknown endpoint, uri = %s", request.uri.c_str());
- reply = http::HTTPReply::stockReply(http::HTTPReply::BAD_REQUEST, "application/json");
+ reply = http::HTTPPayload::statusPayload(http::HTTPPayload::BAD_REQUEST, "application/json");
}
private:
@@ -186,7 +185,7 @@ namespace network
bool m_debug;
};
- typedef RequestDispatcher DefaultRequestDispatcher;
+ typedef RequestDispatcher DefaultRequestDispatcher;
} // namespace rest
} // namespace network
diff --git a/network/rest/http/Connection.h b/network/rest/http/Connection.h
index e0b95af5..e8119898 100644
--- a/network/rest/http/Connection.h
+++ b/network/rest/http/Connection.h
@@ -38,9 +38,8 @@
#define __REST_HTTP__CONNECTION_H__
#include "Defines.h"
-#include "network/rest/http/HTTPRequest.h"
-#include "network/rest/http/HTTPRequestLexer.h"
-#include "network/rest/http/HTTPReply.h"
+#include "network/rest/http/HTTPLexer.h"
+#include "network/rest/http/HTTPPayload.h"
#include
#include
@@ -75,11 +74,13 @@ namespace network
public:
/// Initializes a new instance of the Connection class.
explicit Connection(asio::ip::tcp::socket socket, ConnectionManagerType& manager, RequestHandlerType& handler,
- bool persistent = false) :
+ bool persistent = false, bool client = false) :
m_socket(std::move(socket)),
m_connectionManager(manager),
m_requestHandler(handler),
- m_persistent(persistent)
+ m_lexer(HTTPLexer(client)),
+ m_persistent(persistent),
+ m_client(client)
{
/* stub */
}
@@ -88,7 +89,7 @@ namespace network
///
Connection& operator=(const Connection&) = delete;
-
+
/// Start the first asynchronous operation for the connection.
void start() { read(); }
/// Stop all asynchronous operations associated with the connection.
@@ -103,7 +104,7 @@ namespace network
m_socket.async_read_some(asio::buffer(m_buffer), [=](asio::error_code ec, std::size_t bytes_transferred) {
if (!ec) {
- HTTPRequestLexer::ResultType result;
+ HTTPLexer::ResultType result;
char* content;
std::tie(result, content) = m_lexer.parse(m_request, m_buffer.data(), m_buffer.data() + bytes_transferred);
@@ -114,20 +115,30 @@ namespace network
m_request.content = std::string(content, length);
}
- if (result == HTTPRequestLexer::GOOD) {
+ if (m_client) {
m_requestHandler.handleRequest(m_request, m_reply);
- write();
- }
- else if (result == HTTPRequestLexer::BAD) {
- m_reply = HTTPReply::stockReply(HTTPReply::BAD_REQUEST);
- write();
}
else {
- read();
+ if (result == HTTPLexer::GOOD) {
+ m_requestHandler.handleRequest(m_request, m_reply);
+ write();
+ }
+ else if (result == HTTPLexer::BAD) {
+ m_reply = HTTPPayload::statusPayload(HTTPPayload::BAD_REQUEST);
+ write();
+ }
+ else {
+ read();
+ }
}
}
else if (ec != asio::error::operation_aborted) {
- m_connectionManager.stop(this->shared_from_this());
+ if (m_client) {
+ m_socket.close();
+ }
+ else {
+ m_connectionManager.stop(this->shared_from_this());
+ }
}
});
}
@@ -135,6 +146,10 @@ namespace network
/// Perform an asynchronous write operation.
void write()
{
+ if (m_client) {
+ return;
+ }
+
if (!m_persistent) {
auto self(this->shared_from_this());
} else {
@@ -145,9 +160,9 @@ namespace network
if (m_persistent) {
m_lexer.reset();
m_reply.headers = HTTPHeaders();
- m_reply.status = HTTPReply::OK;
+ m_reply.status = HTTPPayload::OK;
m_reply.content = "";
- m_request = HTTPRequest();
+ m_request = HTTPPayload();
read();
}
else
@@ -166,13 +181,18 @@ namespace network
}
asio::ip::tcp::socket m_socket;
+
ConnectionManagerType& m_connectionManager;
RequestHandlerType& m_requestHandler;
+
std::array m_buffer;
- HTTPRequest m_request;
- HTTPRequestLexer m_lexer;
- HTTPReply m_reply;
+
+ HTTPPayload m_request;
+ HTTPLexer m_lexer;
+ HTTPPayload m_reply;
+
bool m_persistent;
+ bool m_client;
};
} // namespace http
} // namespace rest
diff --git a/network/rest/http/HTTPClient.h b/network/rest/http/HTTPClient.h
new file mode 100644
index 00000000..86a7755b
--- /dev/null
+++ b/network/rest/http/HTTPClient.h
@@ -0,0 +1,180 @@
+/**
+* Digital Voice Modem - Host Software
+* GPLv2 Open Source. Use is subject to license terms.
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* @package DVM / Host Software
+*
+*/
+/*
+* Copyright (C) 2023 by Bryan Biedenkapp N2PLL
+*
+* Permission is hereby granted, free of charge, to any person or organization
+* obtaining a copy of the software and accompanying documentation covered by
+* this license (the “Software”) to use, reproduce, display, distribute, execute,
+* and transmit the Software, and to prepare derivative works of the Software, and
+* to permit third-parties to whom the Software is furnished to do so, all subject
+* to the following:
+*
+* The copyright notices in the Software and this entire statement, including the
+* above license grant, this restriction and the following disclaimer, must be included
+* in all copies of the Software, in whole or in part, and all derivative works of the
+* Software, unless such copies or derivative works are solely in the form of
+* machine-executable object code generated by a source language processor.
+*
+* THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+* PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE
+* DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN
+* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#if !defined(__REST_HTTP__HTTP_CLIENT_H__)
+#define __REST_HTTP__HTTP_CLIENT_H__
+
+#include "Defines.h"
+#include "network/rest/http/Connection.h"
+#include "network/rest/http/ConnectionManager.h"
+#include "network/rest/http/HTTPRequestHandler.h"
+#include "Thread.h"
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace network
+{
+ namespace rest
+ {
+ namespace http
+ {
+
+ // ---------------------------------------------------------------------------
+ // Class Declaration
+ // This class implements top-level routines of the HTTP client.
+ // ---------------------------------------------------------------------------
+
+ template class ConnectionImpl = Connection>
+ class HTTPClient : private Thread {
+ public:
+ /// Initializes a new instance of the HTTPClient class.
+ explicit HTTPClient(const std::string& address, uint16_t port) :
+ m_address(address),
+ m_port(port),
+ m_connection(nullptr),
+ m_ioContext(),
+ m_connectionManager(),
+ m_socket(m_ioContext),
+ m_requestHandler()
+ {
+ /* stub */
+ }
+ /// Initializes a copy instance of the HTTPClient class.
+ HTTPClient(const HTTPClient&) = delete;
+
+ ///
+ HTTPClient& operator=(const HTTPClient&) = delete;
+
+ /// Helper to set the HTTP request handlers.
+ template
+ void setHandler(Handler&& handler)
+ {
+ m_requestHandler = RequestHandlerType(std::forward(handler));
+ }
+
+ /// Send HTTP request to HTTP server.
+ void request(HTTPPayload& request)
+ {
+ asio::post(m_ioContext, [this, request]() {
+ std::lock_guard guard(m_lock);
+ {
+ write(request);
+ }
+ });
+ }
+
+ /// Opens connection to the network.
+ bool open()
+ {
+ return run();
+ }
+
+ /// Closes connection to the network.
+ void close()
+ {
+ if (m_connection != nullptr) {
+ m_connection.stop();
+ }
+
+ wait();
+ }
+
+ private:
+ ///
+ virtual void entry()
+ {
+ asio::ip::tcp::resolver resolver(m_ioContext);
+ auto endpoints = resolver.resolve(m_address, std::to_string(m_port));
+
+ connect(endpoints);
+
+ // the entry() call will block until all asynchronous operations
+ // have finished
+ m_ioContext.run();
+ }
+
+ /// Perform an asynchronous connect operation.
+ void connect(asio::ip::basic_resolver_results& endpoints)
+ {
+ asio::async_connect(m_socket, endpoints, [this](asio::error_code ec, asio::ip::tcp::endpoint) {
+ if (!ec) {
+ m_connection = std::make_shared(std::move(m_socket), m_connectionManager, m_requestHandler, false, true);
+ m_connection->start();
+ }
+ });
+ }
+
+ /// Perform an asynchronous write operation.
+ void write(HTTPPayload& request)
+ {
+ asio::async_write(m_socket, request.toBuffers(), [=](asio::error_code ec, std::size_t) {
+ if (!ec) {
+ // initiate graceful connection closure
+ asio::error_code ignored_ec;
+ m_socket.shutdown(asio::ip::tcp::socket::shutdown_both, ignored_ec);
+ }
+
+ if (ec != asio::error::operation_aborted) {
+ m_socket.close();
+ }
+ });
+ }
+
+ std::string m_address;
+ uint16_t m_port;
+
+ typedef ConnectionImpl ConnectionType;
+ typedef std::shared_ptr ConnectionTypePtr;
+
+ ConnectionTypePtr m_connection;
+
+ asio::io_context m_ioContext;
+
+ ConnectionManager m_connectionManager;
+
+ asio::ip::tcp::socket m_socket;
+
+ RequestHandlerType m_requestHandler;
+
+ std::mutex m_lock;
+ };
+ } // namespace http
+ } // namespace rest
+} // namespace network
+
+#endif // __REST_HTTP__HTTP_CLIENT_H__
diff --git a/network/rest/http/HTTPHeaders.h b/network/rest/http/HTTPHeaders.h
index 8ca10d46..146aba48 100644
--- a/network/rest/http/HTTPHeaders.h
+++ b/network/rest/http/HTTPHeaders.h
@@ -54,7 +54,7 @@ namespace network
// Class Prototypes
// ---------------------------------------------------------------------------
- struct HTTPReply;
+ struct HTTPPayload;
// ---------------------------------------------------------------------------
// Structure Declaration
@@ -122,7 +122,7 @@ namespace network
}
private:
- friend struct HTTPReply;
+ friend struct HTTPPayload;
std::vector m_headers;
};
} // namespace http
diff --git a/network/rest/http/HTTPRequestLexer.cpp b/network/rest/http/HTTPLexer.cpp
similarity index 77%
rename from network/rest/http/HTTPRequestLexer.cpp
rename to network/rest/http/HTTPLexer.cpp
index 70cd5adb..ba483b74 100644
--- a/network/rest/http/HTTPRequestLexer.cpp
+++ b/network/rest/http/HTTPLexer.cpp
@@ -35,8 +35,8 @@
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "Defines.h"
-#include "network/rest/http/HTTPRequestLexer.h"
-#include "network/rest/http/HTTPRequest.h"
+#include "network/rest/http/HTTPLexer.h"
+#include "network/rest/http/HTTPPayload.h"
#include "Log.h"
using namespace network::rest::http;
@@ -48,20 +48,27 @@ using namespace network::rest::http;
// ---------------------------------------------------------------------------
///
-/// Initializes a new instance of the HTTPRequestLexer class.
+/// Initializes a new instance of the HTTPLexer class.
///
-
-HTTPRequestLexer::HTTPRequestLexer() :
+///
+HTTPLexer::HTTPLexer(bool clientLexer) :
m_headers(),
+ m_clientLexer(clientLexer),
m_state(METHOD_START)
{
- /* stub */
+ if (m_clientLexer) {
+ m_state = HTTP_VERSION_H;
+ }
}
/// Reset to initial parser state.
-void HTTPRequestLexer::reset()
+void HTTPLexer::reset()
{
m_state = METHOD_START;
+ if (m_clientLexer) {
+ m_state = HTTP_VERSION_H;
+ }
+
m_headers = std::vector();
}
@@ -75,7 +82,7 @@ void HTTPRequestLexer::reset()
///
///
///
-HTTPRequestLexer::ResultType HTTPRequestLexer::consume(HTTPRequest& req, char input)
+HTTPLexer::ResultType HTTPLexer::consume(HTTPPayload& req, char input)
{
switch (m_state)
{
@@ -123,6 +130,7 @@ HTTPRequestLexer::ResultType HTTPRequestLexer::consume(HTTPRequest& req, char in
/*
** HTTP/1.0
+ ** HTTP/1.0 200 OK
*/
case HTTP_VERSION_H:
if (input == 'H') {
@@ -197,19 +205,86 @@ HTTPRequestLexer::ResultType HTTPRequestLexer::consume(HTTPRequest& req, char in
return BAD;
}
case HTTP_VERSION_MINOR:
- if (input == '\r')
- {
+ if (input == '\r') {
m_state = EXPECTING_NEWLINE_1;
- return INDETERMINATE;
+ if (m_clientLexer) {
+ return BAD;
+ }
+ else {
+ return INDETERMINATE;
+ }
}
- else if (isDigit(input))
- {
+ else if (input == ' ') {
+ if (m_clientLexer) {
+ m_state = HTTP_STATUS_1;
+ return INDETERMINATE;
+ }
+ else {
+ return BAD;
+ }
+ }
+ else if (isDigit(input)) {
req.httpVersionMinor = req.httpVersionMinor * 10 + input - '0';
return INDETERMINATE;
}
else {
return BAD;
}
+ case HTTP_STATUS_1:
+ if (isDigit(input)) {
+ m_state = HTTP_STATUS_2;
+ m_status = m_status * 10 + input - '0';
+ return INDETERMINATE;
+ }
+ else {
+ return BAD;
+ }
+ case HTTP_STATUS_2:
+ if (isDigit(input)) {
+ m_state = HTTP_STATUS_3;
+ m_status = m_status * 10 + input - '0';
+ return INDETERMINATE;
+ }
+ else {
+ return BAD;
+ }
+ case HTTP_STATUS_3:
+ if (isDigit(input)) {
+ m_state = HTTP_STATUS_END;
+ m_status = m_status * 10 + input - '0';
+ req.status = (HTTPPayload::StatusType)m_status;
+ return INDETERMINATE;
+ }
+ else {
+ return BAD;
+ }
+ case HTTP_STATUS_END:
+ if (input == ' ') {
+ m_state = HTTP_STATUS_MESSAGE;
+ return INDETERMINATE;
+ }
+ else {
+ return BAD;
+ }
+ case HTTP_STATUS_MESSAGE_START:
+ if (!isChar(input) || isControl(input) || isSpecial(input)) {
+ return BAD;
+ }
+ else {
+ m_state = HTTP_STATUS_MESSAGE;
+ return INDETERMINATE;
+ }
+ case HTTP_STATUS_MESSAGE:
+ if (input == '\r') {
+ m_state = EXPECTING_NEWLINE_1;
+ return INDETERMINATE;
+ }
+ else if (!isChar(input) || isControl(input) || isSpecial(input)) {
+ return BAD;
+ }
+ else {
+ return INDETERMINATE;
+ }
case EXPECTING_NEWLINE_1:
if (input == '\n') {
@@ -275,8 +350,7 @@ HTTPRequestLexer::ResultType HTTPRequestLexer::consume(HTTPRequest& req, char in
}
case SPACE_BEFORE_HEADER_VALUE:
- if (input == ' ')
- {
+ if (input == ' ') {
m_state = HEADER_VALUE;
return INDETERMINATE;
}
@@ -309,7 +383,7 @@ HTTPRequestLexer::ResultType HTTPRequestLexer::consume(HTTPRequest& req, char in
case EXPECTING_NEWLINE_3:
if (input == '\n') {
for (auto header : m_headers) {
- //::LogDebug(LOG_REST, "HTTPRequestLexer::consume(), header = %s, value = %s", header.name.c_str(), header.value.c_str());
+ //::LogDebug(LOG_REST, "HTTPLexer::consume(), header = %s, value = %s", header.name.c_str(), header.value.c_str());
req.headers.add(header.name, header.value);
}
@@ -328,7 +402,7 @@ HTTPRequestLexer::ResultType HTTPRequestLexer::consume(HTTPRequest& req, char in
///
///
///
-bool HTTPRequestLexer::isChar(int c)
+bool HTTPLexer::isChar(int c)
{
return c >= 0 && c <= 127;
}
@@ -338,7 +412,7 @@ bool HTTPRequestLexer::isChar(int c)
///
///
///
-bool HTTPRequestLexer::isControl(int c)
+bool HTTPLexer::isControl(int c)
{
return (c >= 0 && c <= 31) || (c == 127);
}
@@ -348,7 +422,7 @@ bool HTTPRequestLexer::isControl(int c)
///
///
///
-bool HTTPRequestLexer::isSpecial(int c)
+bool HTTPLexer::isSpecial(int c)
{
switch (c)
{
@@ -367,7 +441,7 @@ bool HTTPRequestLexer::isSpecial(int c)
///
///
///
-bool HTTPRequestLexer::isDigit(int c)
+bool HTTPLexer::isDigit(int c)
{
return c >= '0' && c <= '9';
}
diff --git a/network/rest/http/HTTPRequestLexer.h b/network/rest/http/HTTPLexer.h
similarity index 87%
rename from network/rest/http/HTTPRequestLexer.h
rename to network/rest/http/HTTPLexer.h
index 769b607b..9a805a2e 100644
--- a/network/rest/http/HTTPRequestLexer.h
+++ b/network/rest/http/HTTPLexer.h
@@ -34,8 +34,10 @@
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-#if !defined(__REST_HTTP__HTTP_REQUEST_PARSER_H__)
-#define __REST_HTTP__HTTP_REQUEST_PARSER_H__
+#if !defined(__REST_HTTP__HTTP_LEXER_H__)
+#define __REST_HTTP__HTTP_LEXER_H__
+
+#include "Defines.h"
#include
#include
@@ -51,20 +53,20 @@ namespace network
// Class Prototypes
// ---------------------------------------------------------------------------
- struct HTTPRequest;
+ struct HTTPPayload;
// ---------------------------------------------------------------------------
// Class Declaration
- // This class implements the lexer for incoming requests.
+ // This class implements the lexer for incoming payloads.
// ---------------------------------------------------------------------------
- class HTTPRequestLexer
+ class HTTPLexer
{
public:
enum ResultType { GOOD, BAD, INDETERMINATE };
- /// Initializes a new instance of the HTTPRequestLexer class.
- HTTPRequestLexer();
+ /// Initializes a new instance of the HTTPLexer class.
+ HTTPLexer(bool clientLexer);
/// Reset to initial parser state.
void reset();
@@ -74,10 +76,10 @@ namespace network
/// required. The InputIterator return value indicates how much of the input
/// has been consumed.
template
- std::tuple parse(HTTPRequest& req, InputIterator begin, InputIterator end)
+ std::tuple parse(HTTPPayload& payload, InputIterator begin, InputIterator end)
{
while (begin != end) {
- ResultType result = consume(req, *begin++);
+ ResultType result = consume(payload, *begin++);
if (result == GOOD || result == BAD)
return std::make_tuple(result, begin);
}
@@ -86,7 +88,7 @@ namespace network
private:
/// Handle the next character of input.
- ResultType consume(HTTPRequest& req, char input);
+ ResultType consume(HTTPPayload& payload, char input);
/// Check if a byte is an HTTP character.
static bool isChar(int c);
@@ -107,6 +109,8 @@ namespace network
};
std::vector m_headers;
+ uint16_t m_status;
+ bool m_clientLexer = false;
enum state
{
@@ -122,6 +126,12 @@ namespace network
HTTP_VERSION_MAJOR,
HTTP_VERSION_MINOR_START,
HTTP_VERSION_MINOR,
+ HTTP_STATUS_1,
+ HTTP_STATUS_2,
+ HTTP_STATUS_3,
+ HTTP_STATUS_END,
+ HTTP_STATUS_MESSAGE_START,
+ HTTP_STATUS_MESSAGE,
EXPECTING_NEWLINE_1,
HEADER_LINE_START,
HEADER_LWS,
@@ -136,4 +146,4 @@ namespace network
} // namespace rest
} // namespace network
-#endif // __REST_HTTP__HTTP_REQUEST_PARSER_H__
+#endif // __REST_HTTP__HTTP_LEXER_H__
diff --git a/network/rest/http/HTTPReply.cpp b/network/rest/http/HTTPPayload.cpp
similarity index 73%
rename from network/rest/http/HTTPReply.cpp
rename to network/rest/http/HTTPPayload.cpp
index 3922a97b..3ef52f3c 100644
--- a/network/rest/http/HTTPReply.cpp
+++ b/network/rest/http/HTTPPayload.cpp
@@ -35,7 +35,7 @@
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "Defines.h"
-#include "network/rest/http/HTTPReply.h"
+#include "network/rest/http/HTTPPayload.h"
#include "Log.h"
using namespace network::rest::http;
@@ -60,41 +60,41 @@ namespace status_strings {
const std::string bad_gateway = "HTTP/1.0 502 Bad Gateway\r\n";
const std::string service_unavailable = "HTTP/1.0 503 Service Unavailable\r\n";
- asio::const_buffer toBuffer(HTTPReply::StatusType status)
+ asio::const_buffer toBuffer(HTTPPayload::StatusType status)
{
switch (status)
{
- case HTTPReply::OK:
+ case HTTPPayload::OK:
return asio::buffer(ok);
- case HTTPReply::CREATED:
+ case HTTPPayload::CREATED:
return asio::buffer(created);
- case HTTPReply::ACCEPTED:
+ case HTTPPayload::ACCEPTED:
return asio::buffer(accepted);
- case HTTPReply::NO_CONTENT:
+ case HTTPPayload::NO_CONTENT:
return asio::buffer(no_content);
- case HTTPReply::MULTIPLE_CHOICES:
+ case HTTPPayload::MULTIPLE_CHOICES:
return asio::buffer(multiple_choices);
- case HTTPReply::MOVED_PERMANENTLY:
+ case HTTPPayload::MOVED_PERMANENTLY:
return asio::buffer(moved_permanently);
- case HTTPReply::MOVED_TEMPORARILY:
+ case HTTPPayload::MOVED_TEMPORARILY:
return asio::buffer(moved_temporarily);
- case HTTPReply::NOT_MODIFIED:
+ case HTTPPayload::NOT_MODIFIED:
return asio::buffer(not_modified);
- case HTTPReply::BAD_REQUEST:
+ case HTTPPayload::BAD_REQUEST:
return asio::buffer(bad_request);
- case HTTPReply::UNAUTHORIZED:
+ case HTTPPayload::UNAUTHORIZED:
return asio::buffer(unauthorized);
- case HTTPReply::FORBIDDEN:
+ case HTTPPayload::FORBIDDEN:
return asio::buffer(forbidden);
- case HTTPReply::NOT_FOUND:
+ case HTTPPayload::NOT_FOUND:
return asio::buffer(not_found);
- case HTTPReply::INTERNAL_SERVER_ERROR:
+ case HTTPPayload::INTERNAL_SERVER_ERROR:
return asio::buffer(internal_server_error);
- case HTTPReply::NOT_IMPLEMENTED:
+ case HTTPPayload::NOT_IMPLEMENTED:
return asio::buffer(not_implemented);
- case HTTPReply::BAD_GATEWAY:
+ case HTTPPayload::BAD_GATEWAY:
return asio::buffer(bad_gateway);
- case HTTPReply::SERVICE_UNAVAILABLE:
+ case HTTPPayload::SERVICE_UNAVAILABLE:
return asio::buffer(service_unavailable);
default:
return asio::buffer(internal_server_error);
@@ -201,43 +201,43 @@ namespace stock_replies {
"