From 6a7fb095cb1841be589a66ebf6ca7403a1ce91ac Mon Sep 17 00:00:00 2001 From: Hannu Hartikainen Date: Wed, 31 Oct 2018 09:48:13 +0200 Subject: [PATCH] Support stripping multiple slashes One inspiration for stripping/adding slashes automatically in reitit was https://github.com/julienschmidt/httprouter which can handle any number of slashes. Make the implementation a bit better by stripping as many slashes as there are. This still doesn't support redirecting from a multiple-slash URI to a single-slash URI. That could be handled as a special case, but in the end I think the correct solution would be to convert both the router and request URIs to a canonical form before matching. Then the question of slashes is just a question of formatting. --- modules/reitit-ring/src/reitit/ring.cljc | 2 +- test/cljc/reitit/ring_test.cljc | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/modules/reitit-ring/src/reitit/ring.cljc b/modules/reitit-ring/src/reitit/ring.cljc index c61598e1..8d0a1989 100644 --- a/modules/reitit-ring/src/reitit/ring.cljc +++ b/modules/reitit-ring/src/reitit/ring.cljc @@ -131,7 +131,7 @@ (let [uri (:uri request)] (if (str/ends-with? uri "/") (if (not= method :add) - (maybe-redirect request (subs uri 0 (-> uri count dec)))) + (maybe-redirect request (str/replace-first uri #"/+$" ""))) (if (not= method :strip) (maybe-redirect request (str uri "/"))))))] (fn diff --git a/test/cljc/reitit/ring_test.cljc b/test/cljc/reitit/ring_test.cljc index 010d6a88..3edc486a 100644 --- a/test/cljc/reitit/ring_test.cljc +++ b/test/cljc/reitit/ring_test.cljc @@ -281,7 +281,11 @@ (testing "strips slashes" (is (= 301 (:status (app {:request-method :get, :uri "/slash-less/"})))) - (is (= 308 (:status (app {:request-method :post, :uri "/slash-less/"}))))))) + (is (= 308 (:status (app {:request-method :post, :uri "/slash-less/"}))))) + + (testing "strips multiple 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 @@ -300,7 +304,11 @@ (testing "strips slashes" (is (= 301 (:status (app {:request-method :get, :uri "/slash-less/"})))) - (is (= 308 (:status (app {:request-method :post, :uri "/slash-less/"}))))))))) + (is (= 308 (:status (app {:request-method :post, :uri "/slash-less/"}))))) + + (testing "strips multiple 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)]