From ca9de5850279d64a926729598cd3ac53e0bd367d Mon Sep 17 00:00:00 2001 From: Unknown Date: Sun, 28 Oct 2018 16:20:32 +0900 Subject: [PATCH 01/15] gitignore lein files --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 7b183f21..803dc014 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,6 @@ pom.xml.asc /node_modules /_book figwheel_server.log + +/.m2 +/.ash_history From e2e96e8f1ec19b87a377f6f94a850776543e0e97 Mon Sep 17 00:00:00 2001 From: Unknown Date: Sun, 28 Oct 2018 16:20:45 +0900 Subject: [PATCH 02/15] Add ensure-slash function --- modules/reitit-core/src/reitit/core.cljc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/reitit-core/src/reitit/core.cljc b/modules/reitit-core/src/reitit/core.cljc index 9f88600a..0bdeb7ab 100644 --- a/modules/reitit-core/src/reitit/core.cljc +++ b/modules/reitit-core/src/reitit/core.cljc @@ -30,6 +30,12 @@ nil (expand [_ _])) +(defn ensure-slash + [^String string] + (if (.endsWith string "/") + string + (str string "/"))) + (defn walk [raw-routes {:keys [path data routes expand] :or {data [], routes [], expand expand} :as opts}] From 8d4c591f9655f383ecb20c61ffa9cf8a1a0d6368 Mon Sep 17 00:00:00 2001 From: Unknown Date: Sun, 28 Oct 2018 16:21:03 +0900 Subject: [PATCH 03/15] Use ensure-slash at compilation --- modules/reitit-core/src/reitit/core.cljc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/reitit-core/src/reitit/core.cljc b/modules/reitit-core/src/reitit/core.cljc index 0bdeb7ab..53ba7657 100644 --- a/modules/reitit-core/src/reitit/core.cljc +++ b/modules/reitit-core/src/reitit/core.cljc @@ -55,7 +55,9 @@ [maybe-arg (rest args)]) macc (into macc (expand data opts)) child-routes (walk-many (str pacc path) macc (keep identity childs))] - (if (seq childs) (seq child-routes) [[(str pacc path) macc]])))))] + (if (seq childs) + (seq child-routes) + [[(str pacc (ensure-slash path)) macc]])))))] (walk-one path (mapv identity data) raw-routes))) (defn map-data [f routes] From a8d6b32389297845c3ecc66f75867ccaf05cc747 Mon Sep 17 00:00:00 2001 From: Unknown Date: Sun, 28 Oct 2018 16:21:15 +0900 Subject: [PATCH 04/15] Use ensure-path for matching --- modules/reitit-core/src/reitit/core.cljc | 27 +++++++++++++++--------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/modules/reitit-core/src/reitit/core.cljc b/modules/reitit-core/src/reitit/core.cljc index 53ba7657..03a15293 100644 --- a/modules/reitit-core/src/reitit/core.cljc +++ b/modules/reitit-core/src/reitit/core.cljc @@ -208,8 +208,13 @@ (match-by-path [_ path] (reduce (fn [_ ^Route route] - (if-let [path-params ((:matcher route) path)] - (reduced (->Match (:path route) (:data route) (:result route) (impl/url-decode-coll path-params) path)))) + (let [slashed-path (ensure-slash path)] + (if-let [path-params ((:matcher route) slashed-path)] + (reduced (->Match (:path route) + (:data route) + (:result route) + (impl/url-decode-coll path-params) + slashed-path))))) nil pl)) (match-by-name [_ name] (if-let [match (impl/fast-get lookup name)] @@ -255,7 +260,7 @@ (route-names [_] names) (match-by-path [_ path] - (impl/fast-get data path)) + (impl/fast-get data (ensure-slash path))) (match-by-name [_ name] (if-let [match (impl/fast-get lookup name)] (match nil))) @@ -296,10 +301,11 @@ (route-names [_] names) (match-by-path [_ path] - (if-let [match (segment/lookup pl path)] - (-> (:data match) - (assoc :path-params (impl/url-decode-coll (:path-params match))) - (assoc :path path)))) + (let [slashed-path (ensure-slash path)] + (if-let [match (segment/lookup pl slashed-path)] + (-> (:data match) + (assoc :path-params (impl/url-decode-coll (:path-params match))) + (assoc :path slashed-path))))) (match-by-name [_ name] (if-let [match (impl/fast-get lookup name)] (match nil))) @@ -336,7 +342,7 @@ (route-names [_] names) (match-by-path [_ path] - (if (#?(:clj .equals :cljs =) p path) + (if (#?(:clj .equals :cljs =) p (ensure-slash path)) match)) (match-by-name [_ name] (if (= n name) @@ -372,8 +378,9 @@ (route-names [_] names) (match-by-path [_ path] - (or (match-by-path static-router path) - (match-by-path wildcard-router path))) + (let [slashed-path (ensure-slash path)] + (or (match-by-path static-router path) + (match-by-path wildcard-router path)))) (match-by-name [_ name] (or (match-by-name static-router name) (match-by-name wildcard-router name))) From 2ba01028a08293d83f64dcd64e1276c0357b056f Mon Sep 17 00:00:00 2001 From: Unknown Date: Sun, 28 Oct 2018 16:28:12 +0900 Subject: [PATCH 05/15] Remove unnecessary let --- modules/reitit-core/src/reitit/core.cljc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/reitit-core/src/reitit/core.cljc b/modules/reitit-core/src/reitit/core.cljc index 03a15293..ff30fac8 100644 --- a/modules/reitit-core/src/reitit/core.cljc +++ b/modules/reitit-core/src/reitit/core.cljc @@ -378,9 +378,8 @@ (route-names [_] names) (match-by-path [_ path] - (let [slashed-path (ensure-slash path)] - (or (match-by-path static-router path) - (match-by-path wildcard-router path)))) + (or (match-by-path static-router path) + (match-by-path wildcard-router path))) (match-by-name [_ name] (or (match-by-name static-router name) (match-by-name wildcard-router name))) From 33582b4c1c8ff901e8746f8d1cc160c9e2b822d4 Mon Sep 17 00:00:00 2001 From: Unknown Date: Sun, 28 Oct 2018 18:22:41 +0900 Subject: [PATCH 06/15] Strip slash instead Also fix the only failing test --- modules/reitit-core/src/reitit/core.cljc | 4 ++-- test/cljc/reitit/core_test.cljc | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/reitit-core/src/reitit/core.cljc b/modules/reitit-core/src/reitit/core.cljc index ff30fac8..b85e6f3c 100644 --- a/modules/reitit-core/src/reitit/core.cljc +++ b/modules/reitit-core/src/reitit/core.cljc @@ -33,8 +33,8 @@ (defn ensure-slash [^String string] (if (.endsWith string "/") - string - (str string "/"))) + (str/replace string #"/+$" "") + string)) (defn walk [raw-routes {:keys [path data routes expand] :or {data [], routes [], expand expand} diff --git a/test/cljc/reitit/core_test.cljc b/test/cljc/reitit/core_test.cljc index 8a7e3482..cc57e6b1 100644 --- a/test/cljc/reitit/core_test.cljc +++ b/test/cljc/reitit/core_test.cljc @@ -230,8 +230,8 @@ true [["/a/1/2"] ["/*b"]] - false [["/a"] - ["/a/"]] + true [["/a"] + ["/a/"]] false [["/a"] ["/a/1"]] From 46254975d925b35024d7663dcd943769209e5a99 Mon Sep 17 00:00:00 2001 From: Unknown Date: Mon, 29 Oct 2018 09:11:52 +0900 Subject: [PATCH 07/15] Undo ensure-slash --- modules/reitit-core/src/reitit/core.cljc | 32 +++++++----------------- test/cljc/reitit/core_test.cljc | 4 +-- 2 files changed, 11 insertions(+), 25 deletions(-) diff --git a/modules/reitit-core/src/reitit/core.cljc b/modules/reitit-core/src/reitit/core.cljc index b85e6f3c..9f88600a 100644 --- a/modules/reitit-core/src/reitit/core.cljc +++ b/modules/reitit-core/src/reitit/core.cljc @@ -30,12 +30,6 @@ nil (expand [_ _])) -(defn ensure-slash - [^String string] - (if (.endsWith string "/") - (str/replace string #"/+$" "") - string)) - (defn walk [raw-routes {:keys [path data routes expand] :or {data [], routes [], expand expand} :as opts}] @@ -55,9 +49,7 @@ [maybe-arg (rest args)]) macc (into macc (expand data opts)) child-routes (walk-many (str pacc path) macc (keep identity childs))] - (if (seq childs) - (seq child-routes) - [[(str pacc (ensure-slash path)) macc]])))))] + (if (seq childs) (seq child-routes) [[(str pacc path) macc]])))))] (walk-one path (mapv identity data) raw-routes))) (defn map-data [f routes] @@ -208,13 +200,8 @@ (match-by-path [_ path] (reduce (fn [_ ^Route route] - (let [slashed-path (ensure-slash path)] - (if-let [path-params ((:matcher route) slashed-path)] - (reduced (->Match (:path route) - (:data route) - (:result route) - (impl/url-decode-coll path-params) - slashed-path))))) + (if-let [path-params ((:matcher route) path)] + (reduced (->Match (:path route) (:data route) (:result route) (impl/url-decode-coll path-params) path)))) nil pl)) (match-by-name [_ name] (if-let [match (impl/fast-get lookup name)] @@ -260,7 +247,7 @@ (route-names [_] names) (match-by-path [_ path] - (impl/fast-get data (ensure-slash path))) + (impl/fast-get data path)) (match-by-name [_ name] (if-let [match (impl/fast-get lookup name)] (match nil))) @@ -301,11 +288,10 @@ (route-names [_] names) (match-by-path [_ path] - (let [slashed-path (ensure-slash path)] - (if-let [match (segment/lookup pl slashed-path)] - (-> (:data match) - (assoc :path-params (impl/url-decode-coll (:path-params match))) - (assoc :path slashed-path))))) + (if-let [match (segment/lookup pl path)] + (-> (:data match) + (assoc :path-params (impl/url-decode-coll (:path-params match))) + (assoc :path path)))) (match-by-name [_ name] (if-let [match (impl/fast-get lookup name)] (match nil))) @@ -342,7 +328,7 @@ (route-names [_] names) (match-by-path [_ path] - (if (#?(:clj .equals :cljs =) p (ensure-slash path)) + (if (#?(:clj .equals :cljs =) p path) match)) (match-by-name [_ name] (if (= n name) diff --git a/test/cljc/reitit/core_test.cljc b/test/cljc/reitit/core_test.cljc index cc57e6b1..8a7e3482 100644 --- a/test/cljc/reitit/core_test.cljc +++ b/test/cljc/reitit/core_test.cljc @@ -230,8 +230,8 @@ true [["/a/1/2"] ["/*b"]] - true [["/a"] - ["/a/"]] + false [["/a"] + ["/a/"]] false [["/a"] ["/a/1"]] From 875934360e612333ce9c3ed44bf9e0240ea81eaa Mon Sep 17 00:00:00 2001 From: Unknown Date: Mon, 29 Oct 2018 10:10:22 +0900 Subject: [PATCH 08/15] Add trailing slash handler --- modules/reitit-ring/src/reitit/ring.cljc | 29 ++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/modules/reitit-ring/src/reitit/ring.cljc b/modules/reitit-ring/src/reitit/ring.cljc index 933ba065..397eb25b 100644 --- a/modules/reitit-ring/src/reitit/ring.cljc +++ b/modules/reitit-ring/src/reitit/ring.cljc @@ -110,6 +110,35 @@ (respond nil)))] (f handlers)))))) +(defn redirect-trailing-slash-handler + "A ring handler that redirects a missing path if there is an + existing path that only differs in the ending slash. + + | key | description | + |---------|-------------| + | :method | :add - redirects slash-less to slashed | + | | :strip - redirects slashed to slash-less | + | | :both - works both ways (default) | + " + [{:keys [method] :or {method :both}}] + (let [redirect-handler (fn redirect-handler [request] + (let [uri (:uri request) + maybe-redirect (fn maybe-redirect [path] + (if (r/match-by-path (::r/router request) path) + {:status 308 ; permanent redirect + :headers {"Location" path} + :body ""}))] + (if (str/ends-with? uri "/") + (if (not= method :add) + (maybe-redirect (subs uri 0 (-> uri count dec)))) + (if (not= method :strip) + (maybe-redirect (str uri "/"))))))] + (fn + ([request] + (redirect-handler request)) + ([request respond _] + (respond (redirect-handler request)))))) + (defn create-default-handler "A default ring handler that can handle the following cases, configured via options: From 820e13cffbae3e162db72d7d6c3b543d9736e78b Mon Sep 17 00:00:00 2001 From: Unknown Date: Tue, 30 Oct 2018 10:16:30 +0900 Subject: [PATCH 09/15] Use status 301 and 308 --- modules/reitit-ring/src/reitit/ring.cljc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/reitit-ring/src/reitit/ring.cljc b/modules/reitit-ring/src/reitit/ring.cljc index 397eb25b..73a52529 100644 --- a/modules/reitit-ring/src/reitit/ring.cljc +++ b/modules/reitit-ring/src/reitit/ring.cljc @@ -123,9 +123,10 @@ [{:keys [method] :or {method :both}}] (let [redirect-handler (fn redirect-handler [request] (let [uri (:uri request) + status (if (= (:method request) :get) 301 308) maybe-redirect (fn maybe-redirect [path] (if (r/match-by-path (::r/router request) path) - {:status 308 ; permanent redirect + {:status status :headers {"Location" path} :body ""}))] (if (str/ends-with? uri "/") From c10764fb4d172a1513f491ec1c744e7e0238c271 Mon Sep 17 00:00:00 2001 From: Unknown Date: Sun, 28 Oct 2018 16:20:32 +0900 Subject: [PATCH 10/15] Revert "gitignore lein files" This reverts commit ca9de5850279d64a926729598cd3ac53e0bd367d. --- .gitignore | 3 --- 1 file changed, 3 deletions(-) diff --git a/.gitignore b/.gitignore index 803dc014..7b183f21 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,3 @@ pom.xml.asc /node_modules /_book figwheel_server.log - -/.m2 -/.ash_history From c8b2aa7bc47b97ac54b7e612f514e8b8e57a448f Mon Sep 17 00:00:00 2001 From: Unknown Date: Tue, 30 Oct 2018 23:22:38 +0900 Subject: [PATCH 11/15] Fix incorrect request key It's :request-method not :method --- modules/reitit-ring/src/reitit/ring.cljc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/reitit-ring/src/reitit/ring.cljc b/modules/reitit-ring/src/reitit/ring.cljc index 3cccd541..1436c717 100644 --- a/modules/reitit-ring/src/reitit/ring.cljc +++ b/modules/reitit-ring/src/reitit/ring.cljc @@ -123,7 +123,7 @@ [{:keys [method] :or {method :both}}] (let [redirect-handler (fn redirect-handler [request] (let [uri (:uri request) - status (if (= (:method request) :get) 301 308) + status (if (= (:request-method request) :get) 301 308) maybe-redirect (fn maybe-redirect [path] (if (r/match-by-path (::r/router request) path) {:status status From ad8384022ce5be46c90d4c2472a69361024e503e Mon Sep 17 00:00:00 2001 From: Unknown Date: Tue, 30 Oct 2018 23:23:13 +0900 Subject: [PATCH 12/15] Add tests for the slash-redirect :add case --- test/cljc/reitit/ring_test.cljc | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/test/cljc/reitit/ring_test.cljc b/test/cljc/reitit/ring_test.cljc index 636d5028..86e7d27d 100644 --- a/test/cljc/reitit/ring_test.cljc +++ b/test/cljc/reitit/ring_test.cljc @@ -239,6 +239,31 @@ (is (= response (app {:request-method :get, :uri "/any"}))) (is (= response (app {:request-method :options, :uri "/any"})))))))) +(deftest trailing-slash-handler-test + (testing "using :method :add" + (let [ok {:status 200 :body "ok"} + app (ring/ring-handler + (ring/router + [["/slash-less" {:get (constantly ok), + :post (constantly ok)}] + ["/with-slash/" {:get (constantly ok), + :post (constantly ok)}]]) + (ring/redirect-trailing-slash-handler {:method :add}))] + + (testing "exact matches work" + (is (= ok (app {:request-method :get, :uri "/slash-less"}))) + (is (= ok (app {:request-method :post, :uri "/slash-less"}))) + (is (= ok (app {:request-method :get, :uri "/with-slash/"}))) + (is (= ok (app {:request-method :post, :uri "/with-slash/"})))) + + (testing "adds slashes" + (is (= 301 (:status (app {:request-method :get, :uri "/with-slash"})))) + (is (= 308 (:status (app {:request-method :post, :uri "/with-slash"}))))) + + (testing "does not strip slashes" + (is (= nil (app {:request-method :get, :uri "/slash-less/"}))) + (is (= nil (app {:request-method :post, :uri "/slash-less/"}))))))) + (deftest async-ring-test (let [promise #(let [value (atom ::nil)] (fn From b6e8a9d5796dc1765abd326e5b29a893b3f62f27 Mon Sep 17 00:00:00 2001 From: Unknown Date: Tue, 30 Oct 2018 23:48:12 +0900 Subject: [PATCH 13/15] Add 0-ary version --- modules/reitit-ring/src/reitit/ring.cljc | 39 ++++++++++++------------ 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/modules/reitit-ring/src/reitit/ring.cljc b/modules/reitit-ring/src/reitit/ring.cljc index 1436c717..fb00875a 100644 --- a/modules/reitit-ring/src/reitit/ring.cljc +++ b/modules/reitit-ring/src/reitit/ring.cljc @@ -120,25 +120,26 @@ | | :strip - redirects slashed to slash-less | | | :both - works both ways (default) | " - [{:keys [method] :or {method :both}}] - (let [redirect-handler (fn redirect-handler [request] - (let [uri (:uri request) - status (if (= (:request-method request) :get) 301 308) - maybe-redirect (fn maybe-redirect [path] - (if (r/match-by-path (::r/router request) path) - {:status status - :headers {"Location" path} - :body ""}))] - (if (str/ends-with? uri "/") - (if (not= method :add) - (maybe-redirect (subs uri 0 (-> uri count dec)))) - (if (not= method :strip) - (maybe-redirect (str uri "/"))))))] - (fn - ([request] - (redirect-handler request)) - ([request respond _] - (respond (redirect-handler request)))))) + ([] (redirect-trailing-slash-handler {:method :both})) + ([{:keys [method]}] + (let [redirect-handler (fn redirect-handler [request] + (let [uri (:uri request) + status (if (= (:request-method request) :get) 301 308) + maybe-redirect (fn maybe-redirect [path] + (if (r/match-by-path (::r/router request) path) + {:status status + :headers {"Location" path} + :body ""}))] + (if (str/ends-with? uri "/") + (if (not= method :add) + (maybe-redirect (subs uri 0 (-> uri count dec)))) + (if (not= method :strip) + (maybe-redirect (str uri "/"))))))] + (fn + ([request] + (redirect-handler request)) + ([request respond _] + (respond (redirect-handler request))))))) (defn create-default-handler "A default ring handler that can handle the following cases, From da29203cc8bff5e48b63eb2e3b6340bab3a906a2 Mon Sep 17 00:00:00 2001 From: Unknown Date: Tue, 30 Oct 2018 23:48:35 +0900 Subject: [PATCH 14/15] Add tests for :strip and :both --- test/cljc/reitit/ring_test.cljc | 78 ++++++++++++++++++++++++--------- 1 file changed, 58 insertions(+), 20 deletions(-) diff --git a/test/cljc/reitit/ring_test.cljc b/test/cljc/reitit/ring_test.cljc index 86e7d27d..4997ef63 100644 --- a/test/cljc/reitit/ring_test.cljc +++ b/test/cljc/reitit/ring_test.cljc @@ -240,29 +240,67 @@ (is (= response (app {:request-method :options, :uri "/any"})))))))) (deftest trailing-slash-handler-test - (testing "using :method :add" - (let [ok {:status 200 :body "ok"} - app (ring/ring-handler - (ring/router - [["/slash-less" {:get (constantly ok), - :post (constantly ok)}] - ["/with-slash/" {:get (constantly ok), - :post (constantly ok)}]]) - (ring/redirect-trailing-slash-handler {:method :add}))] + (let [ok {:status 200, :body "ok"} + routes [["/slash-less" {:get (constantly ok), + :post (constantly ok)}] + ["/with-slash/" {:get (constantly ok), + :post (constantly ok)}]]] + (testing "using :method :add" + (let [app (ring/ring-handler + (ring/router routes) + (ring/redirect-trailing-slash-handler {:method :add}))] - (testing "exact matches work" - (is (= ok (app {:request-method :get, :uri "/slash-less"}))) - (is (= ok (app {:request-method :post, :uri "/slash-less"}))) - (is (= ok (app {:request-method :get, :uri "/with-slash/"}))) - (is (= ok (app {:request-method :post, :uri "/with-slash/"})))) + (testing "exact matches work" + (is (= ok (app {:request-method :get, :uri "/slash-less"}))) + (is (= ok (app {:request-method :post, :uri "/slash-less"}))) + (is (= ok (app {:request-method :get, :uri "/with-slash/"}))) + (is (= ok (app {:request-method :post, :uri "/with-slash/"})))) - (testing "adds slashes" - (is (= 301 (:status (app {:request-method :get, :uri "/with-slash"})))) - (is (= 308 (:status (app {:request-method :post, :uri "/with-slash"}))))) + (testing "adds slashes" + (is (= 301 (:status (app {:request-method :get, :uri "/with-slash"})))) + (is (= 308 (:status (app {:request-method :post, :uri "/with-slash"}))))) - (testing "does not strip slashes" - (is (= nil (app {:request-method :get, :uri "/slash-less/"}))) - (is (= nil (app {:request-method :post, :uri "/slash-less/"}))))))) + (testing "does not strip slashes" + (is (= nil (app {:request-method :get, :uri "/slash-less/"}))) + (is (= nil (app {:request-method :post, :uri "/slash-less/"})))))) + + (testing "using :method :strip" + (let [app (ring/ring-handler + (ring/router routes) + (ring/redirect-trailing-slash-handler {:method :strip}))] + + (testing "exact matches work" + (is (= ok (app {:request-method :get, :uri "/slash-less"}))) + (is (= ok (app {:request-method :post, :uri "/slash-less"}))) + (is (= ok (app {:request-method :get, :uri "/with-slash/"}))) + (is (= ok (app {:request-method :post, :uri "/with-slash/"})))) + + (testing "does not add slashes" + (is (= nil (app {:request-method :get, :uri "/with-slash"}))) + (is (= nil (app {:request-method :post, :uri "/with-slash"})))) + + (testing "strips slashes" + (is (= 301 (:status (app {:request-method :get, :uri "/slash-less/"})))) + (is (= 308 (:status (app {:request-method :post, :uri "/slash-less/"}))))))) + + (testing "without option (equivalent to using :method :both)" + (let [app (ring/ring-handler + (ring/router routes) + (ring/redirect-trailing-slash-handler))] + + (testing "exact matches work" + (is (= ok (app {:request-method :get, :uri "/slash-less"}))) + (is (= ok (app {:request-method :post, :uri "/slash-less"}))) + (is (= ok (app {:request-method :get, :uri "/with-slash/"}))) + (is (= ok (app {:request-method :post, :uri "/with-slash/"})))) + + (testing "adds slashes" + (is (= 301 (:status (app {:request-method :get, :uri "/with-slash"})))) + (is (= 308 (:status (app {:request-method :post, :uri "/with-slash"}))))) + + (testing "strips slashes" + (is (= 301 (:status (app {:request-method :get, :uri "/slash-less/"})))) + (is (= 308 (:status (app {:request-method :post, :uri "/slash-less/"}))))))))) (deftest async-ring-test (let [promise #(let [value (atom ::nil)] From 1fc4fc7f603b476347ca425870a4e132d3c1b2bc Mon Sep 17 00:00:00 2001 From: Unknown Date: Wed, 31 Oct 2018 00:10:04 +0900 Subject: [PATCH 15/15] Add docs --- doc/cljdoc.edn | 1 + doc/ring/slash_handler.md | 64 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 doc/ring/slash_handler.md diff --git a/doc/cljdoc.edn b/doc/cljdoc.edn index 50d5b8cf..6e4014dd 100644 --- a/doc/cljdoc.edn +++ b/doc/cljdoc.edn @@ -25,6 +25,7 @@ ["Ring-router" {:file "doc/ring/ring.md"}] ["Reverse-routing" {:file "doc/ring/reverse_routing.md"}] ["Default handler" {:file "doc/ring/default_handler.md"}] + ["Slash handler" {:file "doc/ring/slash_handler.md"}] ["Static Resources" {:file "doc/ring/static.md"}] ["Dynamic Extensions" {:file "doc/ring/dynamic_extensions.md"}] ["Data-driven Middleware" {:file "doc/ring/data_driven_middleware.md"}] diff --git a/doc/ring/slash_handler.md b/doc/ring/slash_handler.md new file mode 100644 index 00000000..76c0ad49 --- /dev/null +++ b/doc/ring/slash_handler.md @@ -0,0 +1,64 @@ +# Slash handler + +The router works with precise matches. If a route is defined without a trailing slash, for example, it won't match a request with a slash. + +```clj +(require '[reitit.ring :as ring]) + +(def app + (ring/ring-handler + (ring/router + ["/ping" (constantly {:status 200, :body ""})]))) + +(app {:uri "/ping/"}) +; nil +``` + +Sometimes it is desirable that paths with and without a trailing slash are recognized as the same. + +Setting the `redirect-trailing-slash-handler` as a second argument to `ring-handler`: + +```clj +(def app + (ring/ring-handler + (ring/router + [["/ping" (constantly {:status 200, :body ""})] + ["/pong/" (constantly {:status 200, :body ""})]]) + (ring/redirect-trailing-slash-handler))) + +(app {:uri "/ping/"}) +; {:status 308, :headers {"Location" "/ping"}, :body ""} +(app {:uri "/pong"}) +; {:status 308, :headers {"Location" "/pong/"}, :body ""} +``` + +`redirect-trailing-slash-handler` accepts an optional `:method` parameter that allows configuring how (whether) to handle missing/extra slashes. The default is to handle both. + +```clj +(def app + (ring/ring-handler + (ring/router + [["/ping" (constantly {:status 200, :body ""})] + ["/pong/" (constantly {:status 200, :body ""})]]) + ; only handle extra trailing slash + (ring/redirect-trailing-slash-handler {:method :strip}))) + +(app {:uri "/ping/"}) +; {:status 308, :headers {"Location" "/ping"}, :body ""} +(app {:uri "/pong"}) +; nil +``` +```clj +(def app + (ring/ring-handler + (ring/router + [["/ping" (constantly {:status 200, :body ""})] + ["/pong/" (constantly {:status 200, :body ""})]]) + ; only handle missing trailing slash + (ring/redirect-trailing-slash-handler {:method :add}))) + +(app {:uri "/ping/"}) +; nil +(app {:uri "/pong"}) +; {:status 308, :headers {"Location" "/pong/"}, :body ""} +```