Browse Source

Refactor TopicFilterComparer

release/3.x.x
Christian 6 years ago
parent
commit
8077d8dfeb
2 changed files with 51 additions and 49 deletions
  1. +2
    -2
      Frameworks/MQTTnet.NetStandard/Server/MqttClientSessionsManager.cs
  2. +49
    -47
      Frameworks/MQTTnet.NetStandard/Server/MqttTopicFilterComparer.cs

+ 2
- 2
Frameworks/MQTTnet.NetStandard/Server/MqttClientSessionsManager.cs View File

@@ -136,9 +136,9 @@ namespace MQTTnet.Server
return Task.FromResult((IList<IMqttClientSessionStatus>)result); return Task.FromResult((IList<IMqttClientSessionStatus>)result);
} }


public Task StartDispatchApplicationMessage(MqttClientSession senderClientSession, MqttApplicationMessage applicationMessage)
public void StartDispatchApplicationMessage(MqttClientSession senderClientSession, MqttApplicationMessage applicationMessage)
{ {
return DispatchApplicationMessageAsync(senderClientSession, applicationMessage);
Task.Run(() => DispatchApplicationMessageAsync(senderClientSession, applicationMessage));
} }


public Task SubscribeAsync(string clientId, IList<TopicFilter> topicFilters) public Task SubscribeAsync(string clientId, IList<TopicFilter> topicFilters)


+ 49
- 47
Frameworks/MQTTnet.NetStandard/Server/MqttTopicFilterComparer.cs View File

@@ -4,114 +4,116 @@ namespace MQTTnet.Server
{ {
public static class MqttTopicFilterComparer public static class MqttTopicFilterComparer
{ {
private const char LEVEL_SEPARATOR = '/';
private const char WILDCARD_MULTI_LEVEL = '#';
private const char WILDCARD_SINGLE_LEVEL = '+';
private const char LevelSeparator = '/';
private const char MultiLevelWildcard = '#';
private const char SingleLevelWildcard = '+';


public static bool IsMatch(string topic, string filter) public static bool IsMatch(string topic, string filter)
{ {
if (string.IsNullOrEmpty(topic)) throw new ArgumentNullException(nameof(topic)); if (string.IsNullOrEmpty(topic)) throw new ArgumentNullException(nameof(topic));
if (string.IsNullOrEmpty(filter)) throw new ArgumentNullException(nameof(filter)); if (string.IsNullOrEmpty(filter)) throw new ArgumentNullException(nameof(filter));


int spos = 0;
int slen = filter.Length;
int tpos = 0;
int tlen = topic.Length;
var sPos = 0;
var sLen = filter.Length;
var tPos = 0;
var tLen = topic.Length;


while (spos < slen && tpos < tlen)
while (sPos < sLen && tPos < tLen)
{ {
if (filter[spos] == topic[tpos])
if (filter[sPos] == topic[tPos])
{ {
if (tpos == tlen - 1)
if (tPos == tLen - 1)
{ {
/* Check for e.g. foo matching foo/# */
if (spos == slen - 3
&& filter[spos + 1] == LEVEL_SEPARATOR
&& filter[spos + 2] == WILDCARD_MULTI_LEVEL)
// Check for e.g. foo matching foo/#
if (sPos == sLen - 3
&& filter[sPos + 1] == LevelSeparator
&& filter[sPos + 2] == MultiLevelWildcard)
{ {
return true; return true;
} }
} }
spos++;
tpos++;
if (spos == slen && tpos == tlen)

sPos++;
tPos++;

if (sPos == sLen && tPos == tLen)
{ {
return true; return true;
} }
else if (tpos == tlen && spos == slen - 1 && filter[spos] == WILDCARD_SINGLE_LEVEL)

if (tPos == tLen && sPos == sLen - 1 && filter[sPos] == SingleLevelWildcard)
{ {
if (spos > 0 && filter[spos - 1] != LEVEL_SEPARATOR)
if (sPos > 0 && filter[sPos - 1] != LevelSeparator)
{ {
// Invalid filter string // Invalid filter string
return false; return false;
} }
spos++;
return true; return true;
} }
} }
else else
{ {
if (filter[spos] == WILDCARD_SINGLE_LEVEL)
if (filter[sPos] == SingleLevelWildcard)
{ {
/* Check for bad "+foo" or "a/+foo" subscription */
if (spos > 0 && filter[spos - 1] != LEVEL_SEPARATOR)
// Check for bad "+foo" or "a/+foo" subscription
if (sPos > 0 && filter[sPos - 1] != LevelSeparator)
{ {
// Invalid filter string // Invalid filter string
return false; return false;
} }
/* Check for bad "foo+" or "foo+/a" subscription */
if (spos < slen - 1 && filter[spos + 1] != LEVEL_SEPARATOR)

// Check for bad "foo+" or "foo+/a" subscription
if (sPos < sLen - 1 && filter[sPos + 1] != LevelSeparator)
{ {
// Invalid filter string // Invalid filter string
return false; return false;
} }
spos++;
while (tpos < tlen && topic[tpos] != LEVEL_SEPARATOR)

sPos++;
while (tPos < tLen && topic[tPos] != LevelSeparator)
{ {
tpos++;
tPos++;
} }
if (tpos == tlen && spos == slen)

if (tPos == tLen && sPos == sLen)
{ {
return true; return true;
} }
} }
else if (filter[spos] == WILDCARD_MULTI_LEVEL)
else if (filter[sPos] == MultiLevelWildcard)
{ {
if (spos > 0 && filter[spos - 1] != LEVEL_SEPARATOR)
if (sPos > 0 && filter[sPos - 1] != LevelSeparator)
{ {
// Invalid filter string // Invalid filter string
return false; return false;
} }
if (spos + 1 != slen)

if (sPos + 1 != sLen)
{ {
// Invalid filter string // Invalid filter string
return false; return false;
} }
else
{
return true;
}

return true;
} }
else else
{ {
/* Check for e.g. foo/bar matching foo/+/# */
if (spos > 0
&& spos + 2 == slen
&& tpos == tlen
&& filter[spos - 1] == WILDCARD_SINGLE_LEVEL
&& filter[spos] == LEVEL_SEPARATOR
&& filter[spos + 1] == WILDCARD_MULTI_LEVEL)
// Check for e.g. foo/bar matching foo/+/#
if (sPos > 0
&& sPos + 2 == sLen
&& tPos == tLen
&& filter[sPos - 1] == SingleLevelWildcard
&& filter[sPos] == LevelSeparator
&& filter[sPos + 1] == MultiLevelWildcard)
{ {
return true; return true;
} }

return false; return false;
} }
} }
} }
if (tpos < tlen || spos < slen)
{
return false;
}


return false; return false;
} }


Loading…
Cancel
Save