parse all by default, check topic for match-ability
This commit is contained in:
@@ -197,7 +197,7 @@ static error_t mqtt_parse_opt(int key, char *arg, struct argp_state *state) {
|
|||||||
return EINVAL;
|
return EINVAL;
|
||||||
} else {
|
} else {
|
||||||
MqttReplacer replacer;
|
MqttReplacer replacer;
|
||||||
if (!replacer.parse(arg)) {
|
if (!replacer.parse(arg, true)) {
|
||||||
argp_error(state, "malformed mqtttopic");
|
argp_error(state, "malformed mqtttopic");
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
@@ -624,6 +624,18 @@ bool MqttReplacer::reduce(const map<string, string>& values, string& result, boo
|
|||||||
return true;
|
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 {
|
ssize_t MqttReplacer::matchTopic(const string& topic, string* circuit, string* name, string* field) const {
|
||||||
size_t last = 0;
|
size_t last = 0;
|
||||||
size_t count = m_parts.size();
|
size_t count = m_parts.size();
|
||||||
@@ -967,18 +979,23 @@ MqttHandler::MqttHandler(UserInfo* userInfo, BusHandler* busHandler, MessageMap*
|
|||||||
if (noDefault) {
|
if (noDefault) {
|
||||||
str.resize(str.size()-1);
|
str.resize(str.size()-1);
|
||||||
}
|
}
|
||||||
|
bool parse = true;
|
||||||
if (hasIntegration && !topic.empty()) {
|
if (hasIntegration && !topic.empty()) {
|
||||||
// topic defined in cmdline and integration file.
|
// topic defined in cmdline and integration file.
|
||||||
if (str.find('%')!=string::npos) {
|
if (str.find('%')==string::npos) {
|
||||||
// cmdline topic is more than just a prefix => override integration topic completely
|
|
||||||
topic.parse(str);
|
|
||||||
} else {
|
|
||||||
// cmdline topic is only the prefix, use it
|
// cmdline topic is only the prefix, use it
|
||||||
m_replacers.set("prefix", str);
|
m_replacers.set("prefix", str);
|
||||||
m_replacers.set("prefixn", removeTrailingNonTopicPart(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) {
|
if (!noDefault) {
|
||||||
topic.ensureDefault();
|
topic.ensureDefault();
|
||||||
@@ -1038,9 +1055,9 @@ MqttHandler::MqttHandler(UserInfo* userInfo, BusHandler* busHandler, MessageMap*
|
|||||||
m_subscribeConfigRestartTopic = m_replacers.get("config_restart-topic", false, false);
|
m_subscribeConfigRestartTopic = m_replacers.get("config_restart-topic", false, false);
|
||||||
m_subscribeConfigRestartPayload = m_replacers.get("config_restart-payload", false, false);
|
m_subscribeConfigRestartPayload = m_replacers.get("config_restart-payload", false, false);
|
||||||
if (g_globalTopic) {
|
if (g_globalTopic) {
|
||||||
m_globalTopic.parse(g_globalTopic, true);
|
m_globalTopic.parse(g_globalTopic);
|
||||||
} else {
|
} else {
|
||||||
m_globalTopic.parse(getTopic(nullptr, "%circuit/%name"), true);
|
m_globalTopic.parse(getTopic(nullptr, "%circuit/%name"));
|
||||||
}
|
}
|
||||||
if (m_globalTopic.has("circuit")) {
|
if (m_globalTopic.has("circuit")) {
|
||||||
map<string, string> values;
|
map<string, string> values;
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ class MqttReplacer {
|
|||||||
* is empty or not defined.
|
* is empty or not defined.
|
||||||
* @return true on success, false on malformed template string.
|
* @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).
|
* 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;
|
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.
|
* Match a topic string against the constant and variables parts.
|
||||||
* @param topic the topic string to match.
|
* @param topic the topic string to match.
|
||||||
|
|||||||
Reference in New Issue
Block a user