in shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/trie/ShenyuTrie.java [278:357]
public ShenyuTrieNode match(final String uriPath, final String bizInfo) {
String strippedPath = StringUtils.strip(uriPath, "/");
String[] pathParts = StringUtils.split(strippedPath, "/");
if (ArrayUtils.isEmpty(pathParts)) {
return null;
}
ShenyuTrieNode currentNode = keyRootMap.get(bizInfo);
int startIndex = 0;
int[] matchAll = new int[pathParts.length];
int[] wildcard = new int[pathParts.length];
int[] pathVariable = new int[pathParts.length];
ShenyuTrieNode matchNode;
while (startIndex < pathParts.length) {
String pathPart = pathParts[startIndex];
if (Objects.isNull(currentNode)) {
return null;
}
if (containsKey(currentNode.getChildren(), pathPart)) {
currentNode = currentNode.getChildren().get(pathPart);
} else if (hasWildcardNode(currentNode.getChildren(), pathPart) && Objects.nonNull(matchNode = findMatchWildcard(currentNode.getChildren(), pathPart)) && wildcard[startIndex] == 0) {
currentNode = matchNode;
wildcard[startIndex] = 1;
} else if (containsKey(currentNode.getChildren(), MATCH_ALL) && matchAll[startIndex] == 0) {
currentNode = currentNode.getChildren().get(MATCH_ALL);
matchAll[startIndex] = 1;
int matchAllIndex = startIndex;
while (true) {
if (matchAllIndex == pathParts.length - 1) {
break;
}
matchAllIndex++;
if (containsKey(currentNode.getChildren(), pathParts[matchAllIndex])) {
currentNode = currentNode.getChildren().get(pathParts[matchAllIndex]);
startIndex = matchAllIndex;
break;
} else if (hasWildcardNode(currentNode.getChildren(), pathParts[matchAllIndex])
&& Objects.nonNull(matchNode = findMatchWildcard(currentNode.getChildren(), pathParts[matchAllIndex]))) {
currentNode = matchNode;
wildcard[matchAllIndex] = 1;
startIndex = matchAllIndex;
break;
}
}
} else if (Objects.nonNull(currentNode.getPathVariableNode()) && currentNode.getPathVariables().size() == 1 && pathVariable[startIndex] == 0) {
currentNode = currentNode.getPathVariableNode();
pathVariable[startIndex] = 1;
} else {
// fail to match, reset the node to failToNode
ShenyuTrieNode preParentNode = currentNode.getParentNode();
ShenyuTrieNode newCurrentNode = currentNode.getFailToNode();
// search failToNode's parentNode
ShenyuTrieNode parentNode = newCurrentNode.getParentNode();
if (Objects.isNull(parentNode) || Objects.nonNull(parentNode.getFailToNode()) && Objects.nonNull(newCurrentNode.getFailToNode())
&& completeResolveConflict(parentNode, wildcard, matchAll, pathVariable, startIndex)
&& parentNode.getFailToNode().equals(newCurrentNode.getFailToNode()) && "/".equals(parentNode.getParentNode().getMatchStr())) {
return null;
}
startIndex--;
if (preParentNode.equals(parentNode)) {
startIndex--;
currentNode = parentNode.getParentNode();
} else {
while (!preParentNode.equals(parentNode)) {
preParentNode = preParentNode.getParentNode();
startIndex--;
}
currentNode = parentNode;
}
continue;
}
if (startIndex < pathParts.length - 1 && Objects.nonNull(currentNode) && !currentNode.getEndOfPath()) {
startIndex++;
continue;
}
if (startIndex == pathParts.length - 1 && checkNode(currentNode, bizInfo) || Objects.nonNull(currentNode) && isMatchAll(currentNode.getMatchStr()) && checkNode(currentNode, bizInfo)) {
return currentNode;
}
}
return null;
}