-
Notifications
You must be signed in to change notification settings - Fork 554
Labels
Description
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, inHttpRouter.findHandler(), by looking for thepathTokenbefore checking forvariableNodes.
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 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.