parse all by default, check topic for match-ability

This commit is contained in:
John
2022-02-12 08:45:50 +01:00
parent f1a5d87aab
commit 9a893252a4
2 changed files with 33 additions and 10 deletions
+26 -9
View File
@@ -197,7 +197,7 @@ static error_t mqtt_parse_opt(int key, char *arg, struct argp_state *state) {
return EINVAL;
} else {
MqttReplacer replacer;
if (!replacer.parse(arg)) {
if (!replacer.parse(arg, true)) {
argp_error(state, "malformed mqtttopic");
return EINVAL;
}
@@ -624,6 +624,18 @@ bool MqttReplacer::reduce(const map<string, string>& values, string& result, boo
return true;
}
bool MqttReplacer::checkMatch() const {
bool lastField = false;
for (const auto& part : m_parts) {
bool field = part.second >= 0;
if (field && lastField) {
return false;
}
lastField = field;
}
return true;
}
ssize_t MqttReplacer::matchTopic(const string& topic, string* circuit, string* name, string* field) const {
size_t last = 0;
size_t count = m_parts.size();
@@ -967,18 +979,23 @@ MqttHandler::MqttHandler(UserInfo* userInfo, BusHandler* busHandler, MessageMap*
if (noDefault) {
str.resize(str.size()-1);
}
bool parse = true;
if (hasIntegration && !topic.empty()) {
// topic defined in cmdline and integration file.
if (str.find('%')!=string::npos) {
// cmdline topic is more than just a prefix => override integration topic completely
topic.parse(str);
} else {
if (str.find('%')==string::npos) {
// cmdline topic is only the prefix, use it
m_replacers.set("prefix", str);
m_replacers.set("prefixn", removeTrailingNonTopicPart(str));
parse = false;
} // else: cmdline topic is more than just a prefix => override integration topic completely
}
if (parse) {
if (!topic.parse(str, true, true)) {
logOtherNotice("mqtt", "unknown or duplicate topic parts potentially prevent matching incoming topics");
topic.parse(str, true);
} else if (!topic.checkMatch()) {
logOtherNotice("mqtt", "missing separators between topic parts potentially prevent matching incoming topics");
}
} else {
topic.parse(str);
}
if (!noDefault) {
topic.ensureDefault();
@@ -1038,9 +1055,9 @@ MqttHandler::MqttHandler(UserInfo* userInfo, BusHandler* busHandler, MessageMap*
m_subscribeConfigRestartTopic = m_replacers.get("config_restart-topic", false, false);
m_subscribeConfigRestartPayload = m_replacers.get("config_restart-payload", false, false);
if (g_globalTopic) {
m_globalTopic.parse(g_globalTopic, true);
m_globalTopic.parse(g_globalTopic);
} else {
m_globalTopic.parse(getTopic(nullptr, "%circuit/%name"), true);
m_globalTopic.parse(getTopic(nullptr, "%circuit/%name"));
}
if (m_globalTopic.has("circuit")) {
map<string, string> values;
+7 -1
View File
@@ -82,7 +82,7 @@ class MqttReplacer {
* is empty or not defined.
* @return true on success, false on malformed template string.
*/
bool parse(const string& templateStr, bool onlyKnown = true, bool noKnownDuplicates = true, bool emptyIfMissing = false);
bool parse(const string& templateStr, bool onlyKnown = false, bool noKnownDuplicates = false, bool emptyIfMissing = false);
/**
* Ensure the default topic parts are present (circuit and message).
@@ -150,6 +150,12 @@ class MqttReplacer {
*/
bool reduce(const map<string, string>& values, string& result, bool onlyAlphanum = false) const;
/**
* Check match-ability against topics.
* @return true on success, false on bad match-ability.
*/
bool checkMatch() const;
/**
* Match a topic string against the constant and variables parts.
* @param topic the topic string to match.