@@ -81,47 +81,76 @@ open class HttpRouter {
8181 }
8282
8383 private func findHandler( _ node: inout Node , params: inout [ String : String ] , generator: inout IndexingIterator < [ String ] > ) -> ( ( HttpRequest ) -> HttpResponse ) ? {
84- guard let pathToken = generator. next ( ) ? . removingPercentEncoding else {
85- // if it's the last element of the requested URL, check if there is a pattern with variable tail.
86- if let variableNode = node. nodes. filter ( { $0. 0 . first == " : " } ) . first {
87- if variableNode. value. nodes. isEmpty {
88- params [ variableNode. 0 ] = " "
89- return variableNode. value. handler
84+
85+ var matchedRoutes = [ Node] ( )
86+ findHandler ( & node, params: & params, generator: & generator, matchedNodes: & matchedRoutes, index: 0 , count: generator. reversed ( ) . count)
87+ return matchedRoutes. first? . handler
88+ }
89+
90+ /// Find the handlers for a specified route
91+ ///
92+ /// - Parameters:
93+ /// - node: The root node of the tree representing all the routes
94+ /// - params: The parameters of the match
95+ /// - generator: The IndexingIterator to iterate through the pattern to match
96+ /// - matchedNodes: An array with the nodes matching the route
97+ /// - index: The index of current position in the generator
98+ /// - count: The number of elements if the route to match
99+ private func findHandler( _ node: inout Node , params: inout [ String : String ] , generator: inout IndexingIterator < [ String ] > , matchedNodes: inout [ Node ] , index: Int , count: Int ) {
100+
101+ if let pathToken = generator. next ( ) ? . removingPercentEncoding {
102+
103+ var currentIndex = index + 1
104+ let variableNodes = node. nodes. filter { $0. 0 . first == " : " }
105+ if let variableNode = variableNodes. first {
106+ if variableNode. 1 . nodes. count == 0 {
107+ // if it's the last element of the pattern and it's a variable, stop the search and
108+ // append a tail as a value for the variable.
109+ let tail = generator. joined ( separator: " / " )
110+ if tail. count > 0 {
111+ params [ variableNode. 0 ] = pathToken + " / " + tail
112+ } else {
113+ params [ variableNode. 0 ] = pathToken
114+ }
115+
116+ matchedNodes. append ( variableNode. value)
117+ return
90118 }
119+ params [ variableNode. 0 ] = pathToken
120+ findHandler ( & node. nodes [ variableNode. 0 ] !, params: & params, generator: & generator, matchedNodes: & matchedNodes, index: currentIndex, count: count)
91121 }
92- return node. handler
93- }
94- let variableNodes = node. nodes. filter { $0. 0 . first == " : " }
95- if let variableNode = variableNodes. first {
96- if variableNode. 1 . nodes. count == 0 {
97- // if it's the last element of the pattern and it's a variable, stop the search and
98- // append a tail as a value for the variable.
99- let tail = generator. joined ( separator: " / " )
100- if tail. count > 0 {
101- params [ variableNode. 0 ] = pathToken + " / " + tail
102- } else {
103- params [ variableNode. 0 ] = pathToken
104- }
105- return variableNode. 1 . handler
122+
123+ if var node = node. nodes [ pathToken] {
124+ findHandler ( & node, params: & params, generator: & generator, matchedNodes: & matchedNodes, index: currentIndex, count: count)
106125 }
107- params [ variableNode. 0 ] = pathToken
108- return findHandler ( & node. nodes [ variableNode. 0 ] !, params: & params, generator: & generator)
109- }
110- if var node = node. nodes [ pathToken] {
111- return findHandler ( & node, params: & params, generator: & generator)
112- }
113- if var node = node. nodes [ " * " ] {
114- return findHandler ( & node, params: & params, generator: & generator)
115- }
116- if let startStarNode = node. nodes [ " ** " ] {
117- let startStarNodeKeys = startStarNode. nodes. keys
118- while let pathToken = generator. next ( ) {
119- if startStarNodeKeys. contains ( pathToken) {
120- return findHandler ( & startStarNode. nodes [ pathToken] !, params: & params, generator: & generator)
126+
127+ if var node = node. nodes [ " * " ] {
128+ findHandler ( & node, params: & params, generator: & generator, matchedNodes: & matchedNodes, index: currentIndex, count: count)
129+ }
130+
131+ if let startStarNode = node. nodes [ " ** " ] {
132+ let startStarNodeKeys = startStarNode. nodes. keys
133+ while let pathToken = generator. next ( ) {
134+ currentIndex += 1
135+ if startStarNodeKeys. contains ( pathToken) {
136+ findHandler ( & startStarNode. nodes [ pathToken] !, params: & params, generator: & generator, matchedNodes: & matchedNodes, index: currentIndex, count: count)
137+ }
121138 }
122139 }
140+ } else if let variableNode = node. nodes. filter ( { $0. 0 . first == " : " } ) . first {
141+ // if it's the last element of the requested URL, check if there is a pattern with variable tail.
142+ if variableNode. value. nodes. isEmpty {
143+ params [ variableNode. 0 ] = " "
144+ matchedNodes. append ( variableNode. value)
145+ return
146+ }
147+ }
148+
149+ // if it's the last element and the path to match is done then it's a pattern matching
150+ if node. nodes. isEmpty && index == count {
151+ matchedNodes. append ( node)
152+ return
123153 }
124- return nil
125154 }
126155
127156 private func stripQuery( _ path: String ) -> String {
0 commit comments