diff --git a/modules/reitit-core/java-src/reitit/SegmentTrie.java b/modules/reitit-core/java-src/reitit/SegmentTrie.java index 3cb58981..fd6c6b30 100644 --- a/modules/reitit-core/java-src/reitit/SegmentTrie.java +++ b/modules/reitit-core/java-src/reitit/SegmentTrie.java @@ -3,7 +3,7 @@ package reitit; import clojure.lang.Keyword; import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; +import java.net.URLDecoder; import java.util.*; public class SegmentTrie { @@ -30,7 +30,7 @@ public class SegmentTrie { if (s.contains("+")) { _s = s.replace("+", "%2B"); } - return URLEncoder.encode(_s, "UTF-8"); + return URLDecoder.decode(_s, "UTF-8"); } } catch (UnsupportedEncodingException ignored) { } @@ -72,6 +72,7 @@ public class SegmentTrie { SegmentTrie s = pointer.catchAll.get(k); if (s == null) { s = new SegmentTrie(); + s.data = data; pointer.catchAll.put(k, s); } break; @@ -103,7 +104,7 @@ public class SegmentTrie { public Matcher matcher() { Matcher m; if (!catchAll.isEmpty()) { - m = new CatchAllMatcher(catchAll.keySet().iterator().next(), catchAll.values().iterator().next().data); + m = new CatchAllMatcher(catchAll.keySet().iterator().next(), data); } else if (!wilds.isEmpty()) { List matchers = new ArrayList<>(); if (data != null) { @@ -118,12 +119,12 @@ public class SegmentTrie { m = new LinearMatcher(matchers); } else if (!childs.isEmpty()) { m = staticMatcher(); + if (data != null) { + m = new LinearMatcher(Arrays.asList(new DataMatcher(data), m)); + } } else { return new DataMatcher(data); } - if (data != null) { - m = new LinearMatcher(Arrays.asList(new DataMatcher(data), m)); - } return m; } @@ -165,10 +166,12 @@ public class SegmentTrie { @Override public Match match(int i, List segments, Match match) { - final Match m = child.match(i + 1, segments, match); - if (m != null) { - m.params.put(parameter, encode(segments.get(i))); - return m; + if (i < segments.size() && !segments.get(i).isEmpty()) { + final Match m = child.match(i + 1, segments, match); + if (m != null) { + m.params.put(parameter, encode(segments.get(i))); + return m; + } } return null; } @@ -294,7 +297,7 @@ public class SegmentTrie { Map m2 = new HashMap<>(); m2.put("user", new WildMatcher(Keyword.intern("id"), new StaticMapMatcher(m1))); m2.put("company", new WildMatcher(Keyword.intern("cid"), new StaticMatcher("dept", new WildMatcher(Keyword.intern("did"), new DataMatcher(3))))); - m2.put("public", new CatchAllMatcher(Keyword.intern("*"), 4)); + m2.put("public", new CatchAllMatcher(Keyword.intern("*"), new DataMatcher(4))); m2.put("kikka", new LinearMatcher(Arrays.asList(new StaticMatcher("ping", new DataMatcher(5)), new WildMatcher(Keyword.intern("id"), new StaticMatcher("ping", new DataMatcher(6)))))); return new StaticMapMatcher(m2); } @@ -302,14 +305,14 @@ public class SegmentTrie { public static void main(String[] args) { SegmentTrie trie = new SegmentTrie(); - //trie.add("/kikka/:id/permissions", 1); - trie.add("/kikka/:id", 2); - trie.add("/kakka/ping", 3); + trie.add("/:abba", 1); + trie.add("/abba/1", 2); + trie.add("/:abba/:dabba/doo", 3); + trie.add("/abba/:dabba/boo", 4); Matcher m = trie.matcher(); System.err.println(m); - System.out.println(lookup(m, "/kikka/1/permissions")); - System.out.println(lookup(m, "/kikka/1")); - + System.err.println(m.getClass()); + System.out.println(lookup(m, "/abba")); /* SegmentTrie trie = new SegmentTrie(); trie.add("/user/:id/profile/:type", 1); diff --git a/modules/reitit-core/src/reitit/core.cljc b/modules/reitit-core/src/reitit/core.cljc index 899410fc..24852b8f 100644 --- a/modules/reitit-core/src/reitit/core.cljc +++ b/modules/reitit-core/src/reitit/core.cljc @@ -289,7 +289,9 @@ names) (match-by-path [_ path] (if-let [match (segment/lookup pl path)] - (assoc (:data match) :path path))) + (-> (:data match) + (assoc :path-params (:path-params match)) + (assoc :path path)))) (match-by-name [_ name] (if-let [match (impl/fast-get lookup name)] (match nil))) diff --git a/modules/reitit-core/src/reitit/segment.cljc b/modules/reitit-core/src/reitit/segment.cljc index b0ff46fa..f62ff2f4 100644 --- a/modules/reitit-core/src/reitit/segment.cljc +++ b/modules/reitit-core/src/reitit/segment.cljc @@ -2,7 +2,7 @@ (:refer-clojure :exclude [-lookup compile]) (:require [reitit.impl :as impl] [clojure.string :as str]) - #?(:clj (:import (reitit SegmentTrie Trie$Match)))) + #?(:clj (:import (reitit SegmentTrie SegmentTrie$Match)))) (defrecord Match [data path-params]) @@ -54,9 +54,9 @@ (defn compile [segment] #?(:cljs segment - :clj (.matcher ^SegmentTrie segment))) + :clj (.matcher ^SegmentTrie (or segment (SegmentTrie.))))) (defn lookup [segment path] #?(:cljs (-lookup segment (impl/segments path) {}) - :clj (if-let [match ^Trie$Match (SegmentTrie/lookup segment path)] + :clj (if-let [match ^SegmentTrie$Match (SegmentTrie/lookup segment path)] (->Match (.data match) (clojure.lang.PersistentHashMap/create (.params match)))))) diff --git a/modules/reitit-http/src/reitit/http.cljc b/modules/reitit-http/src/reitit/http.cljc index 75eda84d..ecb28fca 100644 --- a/modules/reitit-http/src/reitit/http.cljc +++ b/modules/reitit-http/src/reitit/http.cljc @@ -144,7 +144,7 @@ request (enrich-request request path-params match router)] (or (interceptor/execute executor interceptors request) (interceptor/execute executor default-queue request))) - (interceptor/execute executor default-queue (enrich-default-request request)))) + (interceptor/execute executor default-queue (enrich-default-request request router)))) ([request respond raise] (let [default #(interceptor/execute executor default-queue % respond raise)] (if-let [match (r/match-by-path router (:uri request))] @@ -160,7 +160,7 @@ (if interceptors (interceptor/execute executor interceptors request respond' raise) (default request))) - (default (enrich-default-request request)))) + (default (enrich-default-request request router)))) nil)) {::r/router router})))) diff --git a/modules/reitit-ring/src/reitit/ring.cljc b/modules/reitit-ring/src/reitit/ring.cljc index a0913c2f..38df488a 100644 --- a/modules/reitit-ring/src/reitit/ring.cljc +++ b/modules/reitit-ring/src/reitit/ring.cljc @@ -285,7 +285,7 @@ handler (-> result method :handler (or default-handler)) request (enrich-request request path-params match router)] (or (handler request) (default-handler request))) - (default-handler (enrich-default-request request)))) + (default-handler (enrich-default-request request router)))) ([request respond raise] (if-let [match (r/match-by-path router (:uri request))] (let [method (:request-method request) @@ -294,7 +294,7 @@ handler (-> result method :handler (or default-handler)) request (enrich-request request path-params match router)] ((routes handler default-handler) request respond raise)) - (default-handler (enrich-default-request request) respond raise)) + (default-handler (enrich-default-request request router) respond raise)) nil))) {::r/router router})))) diff --git a/perf-test/clj/reitit/calf_perf_test.clj b/perf-test/clj/reitit/calf_perf_test.clj index b97c763f..298b450c 100644 --- a/perf-test/clj/reitit/calf_perf_test.clj +++ b/perf-test/clj/reitit/calf_perf_test.clj @@ -7,7 +7,7 @@ [reitit.impl :as impl] [reitit.ring :as ring] [reitit.core :as r]) - (:import (reitit SegmentTrie Trie$Matcher) + (:import (reitit SegmentTrie SegmentTrie$Matcher) (calfpath Util))) ;; @@ -120,7 +120,7 @@ (cc/quick-bench (r/match-by-path router "/user/1234/profile/compact")))) -(let [lookup ^Trie$Matcher (SegmentTrie/sample)] +(let [lookup ^SegmentTrie$Matcher (SegmentTrie/sample)] (SegmentTrie/lookup lookup "/user/1234/profile/compact") #_(cc/quick-bench (SegmentTrie/lookup lookup "/user/1234/profile/compact"))) @@ -172,20 +172,20 @@ (comment - (let [matcher ^Trie$Matcher (SegmentTrie/sample)] + (let [matcher ^SegmentTrie$Matcher (SegmentTrie/sample)] (SegmentTrie/lookup matcher "/user/1234/profile/compact") (cc/quick-bench (SegmentTrie/lookup matcher "/user/1234/profile/compact"))) ;; 173ns - (let [lookup ^Trie$Matcher (SegmentTrie/tree2)] + (let [lookup ^SegmentTrie$Matcher (SegmentTrie/tree2)] (SegmentTrie/lookup lookup "/user/1234/profile/compact") (cc/quick-bench (SegmentTrie/lookup lookup "/user/1234/profile/compact"))) ;; 140ns - (let [lookup ^Trie$Matcher (SegmentTrie/tree1)] + (let [lookup ^SegmentTrie$Matcher (SegmentTrie/tree1)] (SegmentTrie/lookup lookup "/user/1234/profile/compact") (cc/quick-bench (SegmentTrie/lookup lookup "/user/1234/profile/compact")))