extract request related parts

This commit is contained in:
John
2023-07-08 11:08:29 +02:00
parent e295cc3434
commit c1624f528f
8 changed files with 490 additions and 353 deletions
+46 -91
View File
@@ -105,12 +105,13 @@ result_t UserList::addFromFile(const string& filename, unsigned int lineNo, map<
#define VERBOSITY_4 (VERBOSITY_3 | OF_ALL_ATTRS)
MainLoop::MainLoop(const struct options& opt, Device *device, MessageMap* messages, ScanHelper* scanHelper)
MainLoop::MainLoop(const struct options& opt, Device *device, MessageMap* messages, ScanHelper* scanHelper,
Queue<Request*>* requestQueue)
: Thread(), m_device(device), m_reconnectCount(0), m_userList(opt.accessLevel), m_messages(messages),
m_scanHelper(scanHelper), m_address(opt.address), m_scanConfig(opt.scanConfig),
m_initialScan(opt.readOnly ? ESC : opt.initialScan), m_scanStatus(SCAN_STATUS_NONE),
m_polling(opt.pollInterval > 0), m_enableHex(opt.enableHex),
m_shutdown(false), m_runUpdateCheck(opt.updateCheck), m_httpClient() {
m_shutdown(false), m_runUpdateCheck(opt.updateCheck), m_httpClient(), m_requestQueue(requestQueue) {
m_device->setListener(this);
// open Device
result_t result = m_device->open();
@@ -160,8 +161,6 @@ MainLoop::MainLoop(const struct options& opt, Device *device, MessageMap* messag
// create network
m_htmlPath = opt.htmlPath;
m_network = new Network(opt.localOnly, opt.port, opt.httpPort, &m_netQueue);
m_network->start("network");
logInfo(lf_main, "registering data handlers");
if (datahandler_register(&m_userList, m_busHandler, messages, &m_dataHandlers)) {
logInfo(lf_main, "registered data handlers");
@@ -192,10 +191,6 @@ MainLoop::~MainLoop() {
delete m_logRawFile;
m_logRawFile = nullptr;
}
if (m_network != nullptr) {
delete m_network;
m_network = nullptr;
}
if (m_busHandler != nullptr) {
delete m_busHandler;
m_busHandler = nullptr;
@@ -204,10 +199,6 @@ MainLoop::~MainLoop() {
delete m_device;
m_device = nullptr;
}
NetMessage* msg;
while ((msg = m_netQueue.pop()) != nullptr) {
delete msg;
}
if (m_newlyDefinedMessages) {
delete m_newlyDefinedMessages;
m_newlyDefinedMessages = nullptr;
@@ -245,8 +236,8 @@ void MainLoop::run() {
dataHandler->startHandler();
}
while (!m_shutdown) {
// pick the next message to handle
NetMessage* netMessage = m_netQueue.pop(taskDelay);
// pick the next request to handle
Request* req = m_requestQueue->pop(taskDelay);
time(&now);
if (now < lastTaskRun) {
// clock skew
@@ -410,66 +401,62 @@ void MainLoop::run() {
m_messages->unlock();
sinkSince = now;
}
if (netMessage == nullptr) {
if (req == nullptr) {
continue;
}
if (m_shutdown) {
netMessage->setResult("ERR: shutdown", "", nullptr, now, true);
req->setResult("ERR: shutdown", "", nullptr, now, true);
break;
}
string request = netMessage->getRequest();
string user = netMessage->getUser();
ClientSettings settings = netMessage->getSettings(&since);
if (!netMessage->isListeningMode()) {
string user = req->getUser();
RequestMode reqMode = req->getMode(&since);
if (reqMode.listenMode == lm_none) {
since = now;
}
ostringstream ostream;
bool connected = true;
if (request.length() > 0) {
logDebug(lf_main, ">>> %s", request.c_str());
result_t result = decodeMessage(request, netMessage->isHttp(), &connected, &settings, &user, &reload, &ostream);
if (!netMessage->isHttp() && (ostream.tellp() == 0 || result != RESULT_OK)) {
if (settings.mode != cm_direct) {
if (!req->empty()) {
req->log();
result_t result = decodeRequest(req, &connected, &reqMode, &user, &reload, &ostream);
if (!req->isHttp() && (ostream.tellp() == 0 || result != RESULT_OK)) {
if (reqMode.listenMode != lm_direct) {
ostream.str("");
}
ostream << getResultCode(result);
}
if (ostream.tellp() > 100) {
logDebug(lf_main, "<<< %s ...", ostream.str().substr(0, 100).c_str());
} else {
logDebug(lf_main, "<<< %s", ostream.str().c_str());
}
const auto resp = ostream.str();
req->log(&resp);
if (ostream.tellp() == 0) {
ostream << "\n"; // only for HTTP
} else if (!netMessage->isHttp()) {
ostream << (settings.mode == cm_direct ? "\n" : "\n\n");
} else if (!req->isHttp()) {
ostream << (reqMode.listenMode == lm_direct ? "\n" : "\n\n");
}
}
if (settings.mode == cm_listen) {
if (!settings.listenOnlyUnknown) {
if (reqMode.listenMode == lm_listen) {
if (!reqMode.listenOnlyUnknown) {
string levels = getUserLevels(user);
messages.clear();
m_messages->findAll("", "", levels, false, true, true, true, true, true, since, now, true, &messages);
for (const auto message : messages) {
ostream << message->getCircuit() << " " << message->getName() << " = " << dec;
message->decodeLastData(false, nullptr, -1, settings.format, &ostream);
message->decodeLastData(false, nullptr, -1, reqMode.format, &ostream);
ostream << endl;
}
}
if (settings.listenWithUnknown || settings.listenOnlyUnknown) {
if (reqMode.listenWithUnknown || reqMode.listenOnlyUnknown) {
if (m_busHandler->isGrabEnabled()) {
m_busHandler->formatGrabResult(true, OF_NONE, &ostream, true, since, now);
} else {
m_busHandler->enableGrab(true); // needed for listening to all messages
}
}
} else if (settings.mode == cm_direct) {
} else if (reqMode.listenMode == lm_direct) {
if (m_busHandler->isGrabEnabled()) {
m_busHandler->formatGrabResult(false, OF_NONE, &ostream, true, since, now);
}
}
// send result to client
netMessage->setResult(ostream.str(), user, &settings, now, !connected);
req->setResult(ostream.str(), user, &reqMode, now, !connected);
}
}
@@ -529,49 +516,18 @@ void MainLoop::notifyStatus(bool error, const char* message) {
}
}
result_t MainLoop::decodeMessage(const string &data, bool isHttp, bool* connected, ClientSettings* settings,
result_t MainLoop::decodeRequest(Request* req, bool* connected, RequestMode* reqMode,
string* user, bool* reload, ostringstream* ostream) {
string token, previous;
istringstream stream(data);
vector<string> args;
char escaped = 0;
char delim = ' ';
while (getline(stream, token, delim)) {
if (!isHttp) {
if (escaped) {
args.pop_back();
if (token.length() > 0 && token[token.length()-1] == escaped) {
token.erase(token.length() - 1, 1);
escaped = 0;
}
token = previous + " " + token;
} else if (token.length() == 0) { // allow multiple space chars for a single delimiter
continue;
} else if (token[0] == '"' || token[0] == '\'') {
escaped = token[0];
token.erase(0, 1);
if (token.length() > 0 && token[token.length()-1] == escaped) {
token.erase(token.length() - 1, 1);
escaped = 0;
}
}
}
args.push_back(token);
previous = token;
if (isHttp) {
delim = (args.size() == 1) ? '?' : '\n';
}
}
if (isHttp) {
req->split(&args);
string cmd = args.size() > 0 ? args[0] : "";
if (req->isHttp()) {
if (args.size() < 2) {
*connected = false;
*ostream << "HTTP/1.0 400 Bad Request\r\n\r\n";
return RESULT_OK;
}
const char* str = args.size() > 0 ? args[0].c_str() : "";
if (strcmp(str, "GET") == 0) {
if (cmd == "GET") {
return executeGet(args, connected, ostream);
}
*connected = false;
@@ -579,7 +535,6 @@ result_t MainLoop::decodeMessage(const string &data, bool isHttp, bool* connecte
return RESULT_OK;
}
string cmd = args.size() > 0 ? args[0] : "";
transform(cmd.begin(), cmd.end(), cmd.begin(), ::toupper);
if (cmd == "?" || cmd == "H" || cmd == "HELP") {
// found "HELP CMD"
@@ -587,8 +542,8 @@ result_t MainLoop::decodeMessage(const string &data, bool isHttp, bool* connecte
transform(cmd.begin(), cmd.end(), cmd.begin(), ::toupper);
args.clear(); // empty args is used as command help indicator
}
if (settings->mode == cm_direct) {
return executeDirect(args, &settings->mode, ostream);
if (reqMode->listenMode == lm_direct) {
return executeDirect(args, reqMode, ostream);
}
if (cmd.empty() && args.size() == 0) {
return executeHelp(ostream);
@@ -620,10 +575,10 @@ result_t MainLoop::decodeMessage(const string &data, bool isHttp, bool* connecte
return executeFind(args, getUserLevels(*user), ostream);
}
if (cmd == "L" || cmd == "LISTEN") {
return executeListen(args, settings, ostream);
return executeListen(args, reqMode, ostream);
}
if (cmd == "DIRECT") {
return executeDirect(args, &settings->mode, ostream);
return executeDirect(args, reqMode, ostream);
}
if (cmd == "S" || cmd == "STATE") {
return executeState(args, ostream);
@@ -1293,10 +1248,10 @@ result_t MainLoop::executeHex(const vector<string>& args, ostringstream* ostream
return RESULT_OK;
}
result_t MainLoop::executeDirect(const vector<string>& args, ClientMode* mode, ostringstream* ostream) {
if (*mode != cm_direct) {
result_t MainLoop::executeDirect(const vector<string>& args, RequestMode* reqMode, ostringstream* ostream) {
if (reqMode->listenMode != lm_direct) {
if (args.size() == 1) {
*mode = cm_direct;
reqMode->listenMode = lm_direct;
m_busHandler->enableGrab(true); // needed for listening to all messages
*ostream << "direct mode started";
return RESULT_OK;
@@ -1308,7 +1263,7 @@ result_t MainLoop::executeDirect(const vector<string>& args, ClientMode* mode, o
if (args.size() > 0) {
string firstArg = args[0];
if (firstArg == "stop") {
*mode = cm_normal;
reqMode->listenMode = lm_none;
*ostream << "direct mode stopped";
return RESULT_OK;
}
@@ -1321,7 +1276,7 @@ result_t MainLoop::executeDirect(const vector<string>& args, ClientMode* mode, o
}
*ostream << ":";
if (!m_enableHex) {
*ostream << "ERR: command not enabled";
*ostream << "ERR: hex command not enabled";
return RESULT_OK;
}
size_t argPos = 0;
@@ -1560,7 +1515,7 @@ result_t MainLoop::executeFind(const vector<string>& args, const string& levels,
return RESULT_OK;
}
result_t MainLoop::executeListen(const vector<string>& args, ClientSettings* settings, ostringstream* ostream) {
result_t MainLoop::executeListen(const vector<string>& args, RequestMode* reqMode, ostringstream* ostream) {
size_t argPos = 1;
OutputFormat verbosity = OF_NONE;
bool listenWithUnknown = false;
@@ -1594,17 +1549,17 @@ result_t MainLoop::executeListen(const vector<string>& args, ClientSettings* set
argPos++;
}
if (argPos > 0 && args.size() == argPos) {
settings->format = verbosity;
settings->listenWithUnknown = listenWithUnknown;
settings->listenOnlyUnknown = listenOnlyUnknown;
reqMode->format = verbosity;
reqMode->listenWithUnknown = listenWithUnknown;
reqMode->listenOnlyUnknown = listenOnlyUnknown;
if (listenWithUnknown || listenOnlyUnknown) {
m_busHandler->enableGrab(true); // needed for listening to all messages
}
if (settings->mode == cm_listen) {
if (reqMode->listenMode == lm_listen) {
*ostream << "listen continued";
return RESULT_OK;
}
settings->mode = cm_listen;
reqMode->listenMode = lm_listen;
*ostream << "listen started";
return RESULT_OK;
}
@@ -1620,7 +1575,7 @@ result_t MainLoop::executeListen(const vector<string>& args, ClientSettings* set
" -U only show unknown messages";
return RESULT_OK;
}
settings->mode = cm_normal;
reqMode->listenMode = lm_none;
*ostream << "listen stopped";
return RESULT_OK;
}