in http-server/src/main/scala/com/twitter/finatra/http/internal/routing/Trie.scala [55:128]
private[this] def findNonConstantRoute(
node: TrieNode,
method: Method,
path: String,
startIndex: Int
): MatchedNonConstantRoute = {
val nextIndex = path.indexOf('/', startIndex)
if (startIndex == 0 || startIndex >= path.length) {
if (node.routes.isEmpty) {
MatchedNonConstantRoute()
} else {
node.routes.get(method.name).orElse(node.routes.get(AnyMethod.name)) match {
case Some(route) =>
if (isMatchedRoute(node, route, path)) {
val incomingPath = toMatchPath(route.hasOptionalTrailingSlash, path)
val matchedParams: Map[String, String] =
node.pattern.head.extract(incomingPath).getOrElse(Map.empty[String, String])
if (matchedParams.isEmpty) {
MatchedNonConstantRoute()
} else {
val routeAndParameter = Some(RouteAndParameter(route, matchedParams))
MatchedNonConstantRoute(routeAndParameter)
}
} else {
MatchedNonConstantRoute()
}
case _ => MatchedNonConstantRoute(None, methodNotAllowed = true)
}
}
} else {
val currentSegment =
if (nextIndex == -1) path.substring(startIndex, path.length)
else path.substring(startIndex, nextIndex)
/**
* We look for a match from non-constant routes based on insertion order
*/
var result: MatchedNonConstantRoute = MatchedNonConstantRoute()
var methodNotAllowed: Boolean = false
val childIterator = node.children.valuesIterator
while (childIterator.hasNext) {
val child = childIterator.next()
if (result.routeAndParamOpt.isEmpty) {
if (child.constantSegment) {
// we make sure to compare the segment match ignoring the `/`,
// this is because for paths with optional trailing slash (`/?`),
// we store the last segment with `/`, and this should match the
// case where the incoming path is without a `/`.
if (child.segment.endsWith("/") && child.segment.regionMatches(
true,
0,
currentSegment,
0,
currentSegment.length)) {
result = findNonConstantRoute(child, method, path, nextIndex + 1)
methodNotAllowed = methodNotAllowed || result.methodNotAllowed
} else if (child.segment.equals(currentSegment)) {
result = findNonConstantRoute(child, method, path, nextIndex + 1)
methodNotAllowed = methodNotAllowed || result.methodNotAllowed
}
} else if (child.segment.last == '*') {
result = findNonConstantRoute(child, method, path, 0)
methodNotAllowed = methodNotAllowed || result.methodNotAllowed
} else {
result = findNonConstantRoute(child, method, path, nextIndex + 1)
methodNotAllowed = methodNotAllowed || result.methodNotAllowed
}
}
}
MatchedNonConstantRoute(result.routeAndParamOpt, methodNotAllowed)
}
}