When having overlapping paths, the HttpRouter will pick the incorrect path.
I have the following test, which fails:
let handler: ((HttpRequest) -> HttpResponse) = { _ in
return HttpResponse.accepted
}
let router = HttpRouter()
router.register("GET", path: "a/b", handler: handler)
router.register("GET", path: "a/:id/c", handler: handler)
let foundHandler = router.route("GET", path: "a/b")
XCTAssertNotNil(foundHandler)
let foundSecondHandler = router.route("GET", path: "a/b/c")
XCTAssertNotNil(foundSecondHandler)
The problem is in the implementation of HttpRouter.findHandler(), which has two issues:
- Path parameters are chosen before a path segment, which means, in the first assertion in the above test, the route
"a/:id/c" will be chosen over "a/b". This can be fixed, in HttpRouter.findHandler(), by looking for the pathToken before checking for variableNodes.
However, with the first issue fixed, the HttpRouter will still not correctly find the handler for the second assertion in the above test. The reason for this is the second issue:
- The
HttpRouter.findHandler() does not reevaluate if a nil handler is found. If the found handler is nil, it might indicate that the routing was incorrect, and a different route should be selected. One could introduce if let optional unwrapping of the handler returned by calls to findHandler() in order to not return the found handler, but instead just continue the search for a fitting route. However, the generator used in the findHandler() function is "global" and has already been advanced to the next pathToken.
When having overlapping paths, the HttpRouter will pick the incorrect path.
I have the following test, which fails:
The problem is in the implementation of
HttpRouter.findHandler(), which has two issues:"a/:id/c"will be chosen over"a/b". This can be fixed, inHttpRouter.findHandler(), by looking for thepathTokenbefore checking forvariableNodes.However, with the first issue fixed, the
HttpRouterwill still not correctly find the handler for the second assertion in the above test. The reason for this is the second issue:HttpRouter.findHandler()does not reevaluate if anilhandler is found. If the found handler isnil, it might indicate that the routing was incorrect, and a different route should be selected. One could introduceif letoptional unwrapping of the handler returned by calls tofindHandler()in order to not return the found handler, but instead just continue the search for a fitting route. However, the generator used in thefindHandler()function is "global" and has already been advanced to the nextpathToken.