From d48515e084a0f86d24929362a2bc9c4e3703d20f Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Sun, 3 Jun 2018 17:48:47 +0300 Subject: [PATCH 01/17] Strip nil routes from all positions --- CHANGELOG.md | 12 ++++++++++++ modules/reitit-core/src/reitit/core.cljc | 25 ++++++++++++------------ test/cljc/reitit/core_test.cljc | 6 ++++++ 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e56d2723..98500a5d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ ## 0.1.2-SNAPSHOT +### `reitit-core` + +* Better handling of `nil` routes - they filtered away from route syntax before routes are expanded: + +```clj +(testing "nil routes are allowed ans stripped" + (is (= [] (r/routes (r/router nil)))) + (is (= [] (r/routes (r/router [nil [nil] [[nil nil nil]]])))) + (is (= [["/ping" {} nil]] (r/routes (r/router [nil [nil] ["/ping"]])))) + (is (= [["/ping" {} nil]] (r/routes (r/router [[[nil [nil] ["/ping"]]]]))))) +``` + ### `reitit-schema` * updated dependencies: diff --git a/modules/reitit-core/src/reitit/core.cljc b/modules/reitit-core/src/reitit/core.cljc index 35d2c87b..3a98393e 100644 --- a/modules/reitit-core/src/reitit/core.cljc +++ b/modules/reitit-core/src/reitit/core.cljc @@ -37,16 +37,17 @@ [(walk-many [p m r] (reduce #(into %1 (walk-one p m %2)) [] r)) (walk-one [pacc macc routes] - (if (vector? (first routes)) - (walk-many pacc macc routes) - (let [[path & [maybe-arg :as args]] routes - [data childs] (if (vector? maybe-arg) - [{} args] - [maybe-arg (rest args)]) - macc (into macc (expand data opts))] - (if (seq childs) - (walk-many (str pacc path) macc childs) - [[(str pacc path) macc]]))))] + (if-let [routes (seq (keep identity routes))] + (if (vector? (first routes)) + (walk-many pacc macc routes) + (let [[path & [maybe-arg :as args]] routes + [data childs] (if (vector? maybe-arg) + [{} args] + [maybe-arg (rest args)]) + macc (into macc (expand data opts))] + (if (seq childs) + (walk-many (str pacc path) macc childs) + [[(str pacc path) macc]])))))] (walk-one path (mapv identity data) raw-routes))) (defn map-data [f routes] @@ -87,10 +88,10 @@ (conflicts-str conflicts) {:conflicts conflicts}))) -(defn name-lookup [[_ {:keys [name]}] opts] +(defn name-lookup [[_ {:keys [name]}] _] (if name #{name})) -(defn find-names [routes opts] +(defn find-names [routes _] (into [] (keep #(-> % second :name)) routes)) (defn- compile-route [[p m :as route] {:keys [compile] :as opts}] diff --git a/test/cljc/reitit/core_test.cljc b/test/cljc/reitit/core_test.cljc index e8144e75..f5d23bc4 100644 --- a/test/cljc/reitit/core_test.cljc +++ b/test/cljc/reitit/core_test.cljc @@ -108,6 +108,12 @@ r/segment-router :segment-router r/mixed-router :mixed-router)) + (testing "nil routes are allowed ans stripped" + (is (= [] (r/routes (r/router nil)))) + (is (= [] (r/routes (r/router [nil [nil] [[nil nil nil]]])))) + (is (= [["/ping" {} nil]] (r/routes (r/router [nil [nil] ["/ping"]])))) + (is (= [["/ping" {} nil]] (r/routes (r/router [[[nil [nil] ["/ping"]]]]))))) + (testing "route coercion & compilation" (testing "custom compile" From 4be84d22f4d38a63a13af717a153f306f09791bf Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Sun, 3 Jun 2018 17:48:54 +0300 Subject: [PATCH 02/17] Fix example --- modules/reitit-swagger-ui/src/reitit/swagger_ui.cljc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/reitit-swagger-ui/src/reitit/swagger_ui.cljc b/modules/reitit-swagger-ui/src/reitit/swagger_ui.cljc index 202556a8..019c00d1 100644 --- a/modules/reitit-swagger-ui/src/reitit/swagger_ui.cljc +++ b/modules/reitit-swagger-ui/src/reitit/swagger_ui.cljc @@ -26,7 +26,7 @@ ;; with path and url set, swagger validator disabled (swagger-ui/create-swagger-ui-handler - {:path \"\" + {:path \"/\" :url \"/api/swagger.json\" :config {:validator-url nil})" ([] From 68282a3dc7a79f0432c2c226b65151b142d9099a Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Sun, 27 May 2018 09:47:15 +0300 Subject: [PATCH 03/17] Run simple json perf test (defaults, yada, reitit) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … not testing exactly the same thing, so the numbers are not correct in any way. Still, looking good. --- perf-test/clj/reitit/json_perf.cljc | 109 ++++++++++++++++++++++++++++ project.clj | 4 +- 2 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 perf-test/clj/reitit/json_perf.cljc diff --git a/perf-test/clj/reitit/json_perf.cljc b/perf-test/clj/reitit/json_perf.cljc new file mode 100644 index 00000000..b9d81dfd --- /dev/null +++ b/perf-test/clj/reitit/json_perf.cljc @@ -0,0 +1,109 @@ +(ns reitit.json-perf + (:require [criterium.core :as cc] + [reitit.perf-utils :refer :all] + + ;; reitit + [reitit.ring :as ring] + [muuntaja.middleware :as mm] + + ;; bidi-yada + [yada.yada :as yada] + [bidi.ring :as bidi-ring] + [byte-streams :as bs] + + ;; defaults + [ring.middleware.defaults :as defaults] + [compojure.core :as compojure] + [clojure.string :as str])) + +;; +;; start repl with `lein perf repl` +;; perf measured with the following setup: +;; +;; Model Name: MacBook Pro +;; Model Identifier: MacBookPro113 +;; Processor Name: Intel Core i7 +;; Processor Speed: 2,5 GHz +;; Number of Processors: 1 +;; Total Number of Cores: 4 +;; L2 Cache (per Core): 256 KB +;; L3 Cache: 6 MB +;; Memory: 16 GB +;; + +;; TODO: naive implementation +(defn- with-security-headers [response] + (update + response + :headers + (fn [headers] + (-> headers + (assoc "x-frame-options" "SAMEORIGIN") + (assoc "x-xss-protection" "1; mode=block") + (assoc "x-content-type-options" "nosniff"))))) + +(def security-middleware + {:name ::security + :wrap (fn [handler] + (fn [request] + (with-security-headers (handler request))))}) + +(def reitit-app + (ring/ring-handler + (ring/router + ["/api/ping" + {:get {:handler (fn [_] {:status 200, :body {:ping "pong"}})}}] + {:data {:middleware [mm/wrap-format + security-middleware]}}))) + +(def bidi-yada-app + (bidi-ring/make-handler + ["/api/ping" + (yada/resource + {:produces {:media-type "application/json"} + :methods {:get {:response (fn [_] {:ping "pong"})}}})])) + +(def defaults-app + (defaults/wrap-defaults + (mm/wrap-format + (compojure/GET "/api/ping" [] {:status 200, :body {:ping "pong"}})) + defaults/site-defaults)) + +(def request {:request-method :get, :uri "/api/ping"}) + +(comment + (defaults-app request) + @(bidi-yada-app request) + (reitit-app request)) + +(comment + (slurp (:body (defaults-app request))) + (slurp (:body (reitit-app request))) + (bs/to-string (:body @(bidi-yada-app request)))) + + +(defn expect! [body] + (assert (str/starts-with? body "{\"ping\":\"pong\"}"))) + +(defn perf-test [] + + ;; 176µs + (title "compojure + ring-defaults") + (let [f (fn [] (defaults-app request))] + (expect! (-> (f) :body slurp)) + (cc/quick-bench (f))) + + ;; 60µs + (title "bidi + yada") + (let [f (fn [] (bidi-yada-app request))] + (expect! (-> (f) deref :body bs/to-string)) + (cc/quick-bench (f))) + + ;; 5.0µs + (title "reitit-ring") + (let [f (fn [] (reitit-app request))] + (expect! (-> (f) :body slurp)) + (cc/quick-bench (f)))) + +(comment + (perf-test)) diff --git a/project.clj b/project.clj index 7a682cc8..c4a82e6c 100644 --- a/project.clj +++ b/project.clj @@ -53,7 +53,7 @@ [ring "1.6.3"] [ikitommi/immutant-web "3.0.0-alpha1"] - [metosin/muuntaja "0.5.0"] + [metosin/muuntaja "0.6.0-SNAPSHOT"] [metosin/ring-swagger-ui "2.2.10"] [metosin/jsonista "0.2.1"] @@ -70,6 +70,8 @@ [ikitommi/immutant-web "3.0.0-alpha1"] [io.pedestal/pedestal.route "0.5.3"] [org.clojure/core.async "0.4.474"] + [yada "1.2.13"] + [ring/ring-defaults "0.3.1"] [ataraxy "0.4.0"] [bidi "2.1.3"]]} :analyze {:jvm-opts ^:replace ["-server" From d433005df60f0103eb33ea2aeed2354f37f4968e Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Sun, 27 May 2018 13:22:33 +0300 Subject: [PATCH 04/17] mw & interceptor perf tests with 10 items --- .../reitit/middleware_interceptor_perf.clj | 45 ++++++++++--------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/perf-test/clj/reitit/middleware_interceptor_perf.clj b/perf-test/clj/reitit/middleware_interceptor_perf.clj index d769ec61..1079533d 100644 --- a/perf-test/clj/reitit/middleware_interceptor_perf.clj +++ b/perf-test/clj/reitit/middleware_interceptor_perf.clj @@ -31,7 +31,7 @@ (defrecord RequestOrContext [values queue stack]) -(def +items+ 100) +(def +items+ 10) (defn expected! [x] (assert (= (range +items+) (:values x)))) @@ -47,18 +47,19 @@ map-request {} record-request (map->RequestOrContext map-request)] - ;; 10.8 µs + ;; 1000ns (title "middleware - map") (expected! (app map-request)) (cc/quick-bench (app map-request)) - ;; 4.7 µs + ;; 365ns (title "middleware - record") (expected! (app record-request)) (cc/quick-bench (app record-request)) + ;; 6900ns (title "middleware - dynamic") (expected! ((middleware/chain mw identity) record-request)) (cc/quick-bench @@ -110,21 +111,21 @@ {:enter (interceptor value)}) (range +items+))) ctx (io.pedestal.interceptor.chain/enqueue nil is)] - ;; 78 µs + ;; 8400ns (title "pedestal") (cc/quick-bench (io.pedestal.interceptor.chain/execute ctx)))) -(defn pedestal-tuned-chain-text [] - (let [is (map io.pedestal.interceptor/interceptor - (map (fn [value] - {:enter (interceptor value)}) (range +items+))) - ctx (reitit.chain/map->Context (reitit.chain/enqueue nil is))] +#_(defn pedestal-tuned-chain-text [] + (let [is (map io.pedestal.interceptor/interceptor + (map (fn [value] + {:enter (interceptor value)}) (range +items+))) + ctx (reitit.chain/map->Context (reitit.chain/enqueue nil is))] - ;; 67 µs - (title "pedestal - tuned") - (cc/quick-bench - (reitit.chain/execute ctx)))) + ;; 67 µs + (title "pedestal - tuned") + (cc/quick-bench + (reitit.chain/execute ctx)))) ;; ;; Naive chain @@ -140,17 +141,17 @@ (defn interceptor-test [] (let [interceptors (map (fn [value] [interceptor value]) (range +items+)) - app (executor-reduce (interceptor/chain interceptors identity)) + app (executor-reduce (interceptor/chain interceptors identity {})) map-request {} record-request (map->RequestOrContext map-request)] - ;; 13.5 µs (Map) + ;; 1900ns (title "interceptors - map") (expected! (app map-request)) (cc/quick-bench (app map-request)) - ;; 7.2 µs (Record) + ;; 1300ns (title "interceptors - record") (expected! (app record-request)) (cc/quick-bench @@ -212,24 +213,24 @@ (defn interceptor-chain-test [] (let [interceptors (map (fn [value] [interceptor value]) (range +items+)) - app-reduce (executor-reduce (interceptor/chain interceptors identity)) - app-queue (executor-queue (interceptor/chain interceptors identity)) - app-ctx-queue (executor-ctx-queue (interceptor/chain interceptors identity)) + app-reduce (executor-reduce (interceptor/chain interceptors identity {})) + app-queue (executor-queue (interceptor/chain interceptors identity {})) + app-ctx-queue (executor-ctx-queue (interceptor/chain interceptors identity {})) request {}] - ;; 14.2 µs + ;; 2000ns (title "interceptors - reduce") (expected! (app-reduce request)) (cc/quick-bench (app-reduce request)) - ;; 19.4 µs + ;; 2500ns (title "interceptors - queue") (expected! (app-queue request)) (cc/quick-bench (app-queue request)) - ;; 30.9 µs + ;; 3200ns (title "interceptors - ctx-queue") (expected! (app-ctx-queue request)) (cc/quick-bench From 5b928d087370531cd1bd909ce662bb725659564e Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Sun, 3 Jun 2018 18:06:22 +0300 Subject: [PATCH 05/17] measure ring-handler perf --- perf-test/clj/reitit/bide_perf_test.clj | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/perf-test/clj/reitit/bide_perf_test.clj b/perf-test/clj/reitit/bide_perf_test.clj index 9e3aecf8..be26dcde 100644 --- a/perf-test/clj/reitit/bide_perf_test.clj +++ b/perf-test/clj/reitit/bide_perf_test.clj @@ -10,7 +10,8 @@ [io.pedestal.http.route.definition.table :as table] [io.pedestal.http.route.map-tree :as map-tree] [io.pedestal.http.route.router :as pedestal] - [io.pedestal.http.route :as route])) + [io.pedestal.http.route :as route] + [reitit.ring :as ring])) ;; ;; start repl with `lein perf repl` @@ -62,6 +63,26 @@ ["/auth/recovery/token/:token" :auth/recovery] ["/workspace/:project/:page" :workspace/page]])) +(def ring-app + (ring/ring-handler + (ring/router + [["/auth/login" {:get identity}] + ["/auth/recovery/token/:token" {:get identity}] + ["/workspace/:project/:page" {:get identity}]]))) + +(comment + + (ring-app {:request-method :get, :uri "/auth/login"}) + + ;; 213ns + ;; 204ns (remove if) + ;; 163ns (inline fast-assoc) + ;; 156ns (don't inline fast-assoc) + ;; 128ns (single method dispatch) + ;; 80ns --> (don't inject router & match) + (cc/quick-bench + (ring-app {:request-method :post, :uri "/auth/login"}))) + (defn routing-test1 [] (suite "static route") From 56203ba11d93dc140fb7a731c48898fcb0ded608 Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Sun, 3 Jun 2018 18:17:25 +0300 Subject: [PATCH 06/17] no default method in ring --- modules/reitit-ring/src/reitit/ring.cljc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/reitit-ring/src/reitit/ring.cljc b/modules/reitit-ring/src/reitit/ring.cljc index 020ed15d..0ea22e97 100644 --- a/modules/reitit-ring/src/reitit/ring.cljc +++ b/modules/reitit-ring/src/reitit/ring.cljc @@ -129,7 +129,7 @@ (fn ([request] (if-let [match (r/match-by-path router (:uri request))] - (let [method (:request-method request :any) + (let [method (:request-method request) path-params (:path-params match) result (:result match) handler (-> result method :handler (or default-handler)) @@ -141,7 +141,7 @@ (default-handler request))) ([request respond raise] (if-let [match (r/match-by-path router (:uri request))] - (let [method (:request-method request :any) + (let [method (:request-method request) path-params (:path-params match) result (:result match) handler (-> result method :handler (or default-handler)) From 7a544cd52d100f467503ae97951f82e1d192cd28 Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Mon, 4 Jun 2018 10:30:48 +0300 Subject: [PATCH 07/17] Better handling of nil in routing --- CHANGELOG.md | 11 +++++++---- modules/reitit-core/src/reitit/core.cljc | 15 +++++++-------- modules/reitit-core/src/reitit/spec.cljc | 11 ++++++----- test/cljc/reitit/core_test.cljc | 12 +++++++++--- test/cljc/reitit/spec_test.cljc | 22 ++++++++++++++-------- 5 files changed, 43 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 98500a5d..e1274034 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,14 +2,17 @@ ### `reitit-core` -* Better handling of `nil` routes - they filtered away from route syntax before routes are expanded: +* Better handling of `nil` in route syntax: + * explicit `nil` after path string is always handled as `nil` route + * `nil` as path string causes the whole route to be `nil` + * `nil` as child route is stripped away ```clj -(testing "nil routes are allowed ans stripped" +(testing "nil routes are stripped" (is (= [] (r/routes (r/router nil)))) + (is (= [] (r/routes (r/router [nil ["/ping"]])))) (is (= [] (r/routes (r/router [nil [nil] [[nil nil nil]]])))) - (is (= [["/ping" {} nil]] (r/routes (r/router [nil [nil] ["/ping"]])))) - (is (= [["/ping" {} nil]] (r/routes (r/router [[[nil [nil] ["/ping"]]]]))))) + (is (= [] (r/routes (r/router ["/ping" [nil "/pong"]]))))) ``` ### `reitit-schema` diff --git a/modules/reitit-core/src/reitit/core.cljc b/modules/reitit-core/src/reitit/core.cljc index 3a98393e..eea9ab7a 100644 --- a/modules/reitit-core/src/reitit/core.cljc +++ b/modules/reitit-core/src/reitit/core.cljc @@ -37,17 +37,16 @@ [(walk-many [p m r] (reduce #(into %1 (walk-one p m %2)) [] r)) (walk-one [pacc macc routes] - (if-let [routes (seq (keep identity routes))] - (if (vector? (first routes)) - (walk-many pacc macc routes) + (if (vector? (first routes)) + (walk-many pacc macc routes) + (if (string? (first routes)) (let [[path & [maybe-arg :as args]] routes - [data childs] (if (vector? maybe-arg) + [data childs] (if (or (vector? maybe-arg) (nil? maybe-arg)) [{} args] [maybe-arg (rest args)]) - macc (into macc (expand data opts))] - (if (seq childs) - (walk-many (str pacc path) macc childs) - [[(str pacc path) macc]])))))] + 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]])))))] (walk-one path (mapv identity data) raw-routes))) (defn map-data [f routes] diff --git a/modules/reitit-core/src/reitit/spec.cljc b/modules/reitit-core/src/reitit/spec.cljc index d3361f0d..cf98cf24 100644 --- a/modules/reitit-core/src/reitit/spec.cljc +++ b/modules/reitit-core/src/reitit/spec.cljc @@ -9,18 +9,19 @@ (s/def ::path (s/with-gen string? #(gen/fmap (fn [s] (str "/" s)) (s/gen string?)))) -(s/def ::arg (s/and any? (complement vector?))) +(s/def ::arg (s/and some? (complement vector?))) (s/def ::data (s/map-of keyword? any?)) (s/def ::result any?) (s/def ::raw-route - (s/cat :path ::path - :arg (s/? ::arg) - :childs (s/* (s/and (s/nilable ::raw-route))))) + (s/nilable + (s/cat :path ::path + :arg (s/? ::arg) + :childs (s/* (s/and (s/nilable ::raw-routes)))))) (s/def ::raw-routes (s/or :route ::raw-route - :routes (s/coll-of ::raw-route :into []))) + :routes (s/coll-of ::raw-routes :into []))) (s/def ::route (s/cat :path ::path diff --git a/test/cljc/reitit/core_test.cljc b/test/cljc/reitit/core_test.cljc index f5d23bc4..f702f9bd 100644 --- a/test/cljc/reitit/core_test.cljc +++ b/test/cljc/reitit/core_test.cljc @@ -108,11 +108,11 @@ r/segment-router :segment-router r/mixed-router :mixed-router)) - (testing "nil routes are allowed ans stripped" + (testing "nil routes are stripped" (is (= [] (r/routes (r/router nil)))) + (is (= [] (r/routes (r/router [nil ["/ping"]])))) (is (= [] (r/routes (r/router [nil [nil] [[nil nil nil]]])))) - (is (= [["/ping" {} nil]] (r/routes (r/router [nil [nil] ["/ping"]])))) - (is (= [["/ping" {} nil]] (r/routes (r/router [[[nil [nil] ["/ping"]]]]))))) + (is (= [] (r/routes (r/router ["/ping" [nil "/pong"]]))))) (testing "route coercion & compilation" @@ -246,3 +246,9 @@ [["/a"] ["/a"]])))) (testing "can be configured to ignore" (is (not (nil? (r/router [["/a"] ["/a"]] {:conflicts (constantly nil)}))))))) + +(testing "nil routes are stripped" + (is (= [] (r/routes (r/router nil)))) + (is (= [] (r/routes (r/router [nil ["/ping"]])))) + (is (= [] (r/routes (r/router [nil [nil] [[nil nil nil]]])))) + (is (= [] (r/routes (r/router ["/ping" [nil "/pong"]]))))) diff --git a/test/cljc/reitit/spec_test.cljc b/test/cljc/reitit/spec_test.cljc index 62012cd2..6dafb3ba 100644 --- a/test/cljc/reitit/spec_test.cljc +++ b/test/cljc/reitit/spec_test.cljc @@ -1,14 +1,20 @@ (ns reitit.spec-test - (:require [clojure.test :refer [deftest testing is are]] + (:require [clojure.test :refer [deftest testing is are use-fixtures]] [#?(:clj clojure.spec.test.alpha :cljs cljs.spec.test.alpha) :as stest] [clojure.spec.alpha :as s] [reitit.core :as r] - [reitit.spec :as rs] - [expound.alpha :as e]) + [reitit.spec :as rs]) #?(:clj (:import (clojure.lang ExceptionInfo)))) -(stest/instrument) +(defn instrument-all [f] + (try + (stest/instrument) + (f) + (finally + (stest/unstrument)))) + +(use-fixtures :each instrument-all) (deftest router-spec-test @@ -40,9 +46,9 @@ ;; path [:invalid {}] - ;; vector data - ["/api" [] - ["/ipa"]]))) + ;; nested path + ["/api" + [:ipa]]))) (testing "routes conform to spec (can't spec protocol functions)" (is (s/valid? ::rs/routes (r/routes (r/router ["/ping"]))))) @@ -60,7 +66,7 @@ {:conflicts (fn [_])} {:router r/linear-router}) - (are [opts] + #_(are [opts] (is (thrown-with-msg? ExceptionInfo #"Call to #'reitit.core/router did not conform to spec" From fa078470c54576debcff43976a7fcaa61789d30f Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Mon, 4 Jun 2018 11:33:51 +0300 Subject: [PATCH 08/17] swagger-ui path work, wip --- modules/reitit-ring/src/reitit/ring.cljc | 20 ++++++++++--------- .../src/reitit/swagger_ui.cljc | 12 +++++------ 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/modules/reitit-ring/src/reitit/ring.cljc b/modules/reitit-ring/src/reitit/ring.cljc index 0ea22e97..5fa0b40b 100644 --- a/modules/reitit-ring/src/reitit/ring.cljc +++ b/modules/reitit-ring/src/reitit/ring.cljc @@ -96,24 +96,26 @@ (fn ([request] (handler request)) ([request respond _] (respond (handler request))))) + trim-path (fn [& paths] (str/replace (apply str paths) "//" "/")) resource-response (fn [path] - (if-let [response (or (paths path) (response/resource-response path options))] + (if-let [response (or (paths (trim-path "/" path)) (response/resource-response path options))] (response/content-type response (mime-type/ext-mime-type path)))) - path-or-index-response (fn [path] + path-or-index-response (fn [path uri] (or (resource-response path) - (let [separator (if-not (str/ends-with? path "/") "/")] - (loop [[file & files] index-files] - (if file - (or (resource-response (str path separator file)) - (recur files))))))) + (loop [[file & files] index-files] + (if file + (let [path (trim-path path file)] + (if (resource-response path) + {:status 302 :headers {"Location" (trim-path uri "/" path)}} + (recur files))))))) handler (if path (fn [request] (let [uri (:uri request)] (if-let [path (if (>= (count uri) path-size) (subs uri path-size))] - (path-or-index-response path)))) + (path-or-index-response path uri)))) (fn [request] (let [path (-> request :path-params parameter)] - (or (path-or-index-response path) {:status 404}))))] + (or (path-or-index-response path path) {:status 404}))))] (create handler))))) (defn ring-handler diff --git a/modules/reitit-swagger-ui/src/reitit/swagger_ui.cljc b/modules/reitit-swagger-ui/src/reitit/swagger_ui.cljc index 019c00d1..137dbcb5 100644 --- a/modules/reitit-swagger-ui/src/reitit/swagger_ui.cljc +++ b/modules/reitit-swagger-ui/src/reitit/swagger_ui.cljc @@ -42,11 +42,11 @@ (update $ :root (fnil identity "swagger-ui")) (update $ :url (fnil identity "/swagger.json")) (update $ :config #(->> % (map mixed-case-key) (into {}))) - (assoc $ :paths {"conf.js" {:headers {"Content-Type" "application/javascript"} - :status 200 - :body (conf-js $)} - "config.json" {:headers {"Content-Type" "application/json"} - :status 200 - :body (config-json $)}}))] + (assoc $ :paths {"/conf.js" {:headers {"Content-Type" "application/javascript"} + :status 200 + :body (conf-js $)} + "/config.json" {:headers {"Content-Type" "application/json"} + :status 200 + :body (config-json $)}}))] (ring/routes (ring/create-resource-handler options)))))) From a99789216c7b2c30608d20b57c54d33344b048cc Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Mon, 4 Jun 2018 23:21:03 +0300 Subject: [PATCH 09/17] Use redirects for index-files --- modules/reitit-ring/src/reitit/ring.cljc | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/modules/reitit-ring/src/reitit/ring.cljc b/modules/reitit-ring/src/reitit/ring.cljc index 5fa0b40b..3577ed63 100644 --- a/modules/reitit-ring/src/reitit/ring.cljc +++ b/modules/reitit-ring/src/reitit/ring.cljc @@ -96,26 +96,30 @@ (fn ([request] (handler request)) ([request respond _] (respond (handler request))))) - trim-path (fn [& paths] (str/replace (apply str paths) "//" "/")) + join-paths (fn [& paths] + (str/replace (str/replace (str/join "/" paths) #"([/]+)" "/") #"/$" "")) resource-response (fn [path] - (if-let [response (or (paths (trim-path "/" path)) (response/resource-response path options))] + (if-let [response (or (paths (join-paths "/" path)) + (response/resource-response path options))] (response/content-type response (mime-type/ext-mime-type path)))) path-or-index-response (fn [path uri] (or (resource-response path) (loop [[file & files] index-files] (if file - (let [path (trim-path path file)] - (if (resource-response path) - {:status 302 :headers {"Location" (trim-path uri "/" path)}} - (recur files))))))) + (if (resource-response (join-paths path file)) + {:status 302 :headers {"Location" (join-paths uri file)}} + (recur files)))))) handler (if path (fn [request] (let [uri (:uri request)] (if-let [path (if (>= (count uri) path-size) (subs uri path-size))] (path-or-index-response path uri)))) (fn [request] - (let [path (-> request :path-params parameter)] - (or (path-or-index-response path path) {:status 404}))))] + (let [uri (:uri request) + path (-> request :path-params parameter)] + (or (path-or-index-response path uri) + ;; TODO: use generic not-found handler + {:status 404}))))] (create handler))))) (defn ring-handler From 80283dbbd239f5ae844a8f457c46089ff568c9de Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Mon, 4 Jun 2018 23:21:56 +0300 Subject: [PATCH 10/17] Better tests for the static files --- test/cljc/reitit/ring_test.cljc | 197 ++++++++++++++++++++++++-------- 1 file changed, 148 insertions(+), 49 deletions(-) diff --git a/test/cljc/reitit/ring_test.cljc b/test/cljc/reitit/ring_test.cljc index 27a5ad83..200cce36 100644 --- a/test/cljc/reitit/ring_test.cljc +++ b/test/cljc/reitit/ring_test.cljc @@ -3,7 +3,8 @@ [clojure.set :as set] [reitit.middleware :as middleware] [reitit.ring :as ring] - [reitit.core :as r]) + [reitit.core :as r] + [clojure.string :as str]) #?(:clj (:import (clojure.lang ExceptionInfo)))) @@ -267,56 +268,154 @@ #?(:clj (deftest resource-handler-test - (doseq [[test app] [["inside a router" - (ring/ring-handler - (ring/router - [["/ping" (constantly {:status 200, :body "pong"})] - ["/files/*" (ring/create-resource-handler)] - ["/*" (ring/create-resource-handler)]] - {:conflicts (constantly nil)}) - (ring/create-default-handler))] + (let [redirect (fn [uri] {:status 302 :headers {"Location" uri}}) + request (fn [uri] {:uri uri, :request-method :get})] + (testing "inside a router" - ["outside of a router" - (ring/ring-handler - (ring/router - ["/ping" (constantly {:status 200, :body "pong"})]) - (ring/routes - (ring/create-resource-handler {:path "/files"}) - (ring/create-resource-handler {:path "/"}) - (ring/create-default-handler)))]] - prefix ["" "/" "/files" "/files/"] - :let [request (fn [uri] {:uri (str prefix uri), :request-method :get})]] + (testing "from root" + (let [app (ring/ring-handler + (ring/router + ["/*" (ring/create-resource-handler)]) + (ring/create-default-handler))] + (testing test + (testing "different file-types" + (let [response (app (request "/hello.json"))] + (is (= "application/json" (get-in response [:headers "Content-Type"]))) + (is (get-in response [:headers "Last-Modified"])) + (is (= "{\"hello\": \"file\"}" (slurp (:body response))))) + (let [response (app (request "/hello.xml"))] + (is (= "text/xml" (get-in response [:headers "Content-Type"]))) + (is (get-in response [:headers "Last-Modified"])) + (is (= "file\n" (slurp (:body response)))))) - (testing test - (testing "different file-types" - (let [response (app (request "/hello.json"))] - (is (= "application/json" (get-in response [:headers "Content-Type"]))) - (is (get-in response [:headers "Last-Modified"])) - (is (= "{\"hello\": \"file\"}" (slurp (:body response))))) - (let [response (app (request "/hello.xml"))] - (is (= "text/xml" (get-in response [:headers "Content-Type"]))) - (is (get-in response [:headers "Last-Modified"])) - (is (= "file\n" (slurp (:body response)))))) + (testing "index-files" + (let [response (app (request "/docs"))] + (is (= (redirect "/docs/index.html") response))) + (let [response (app (request "/docs/"))] + (is (= (redirect "/docs/index.html") response)))) - (testing "index-files" - (let [response (app (request "/docs"))] - (is (= "text/html" (get-in response [:headers "Content-Type"]))) - (is (get-in response [:headers "Last-Modified"])) - (is (= "

hello

\n" (slurp (:body response))))) - (let [response (app (request "/docs/"))] - (is (= "text/html" (get-in response [:headers "Content-Type"]))) - (is (get-in response [:headers "Last-Modified"])) - (is (= "

hello

\n" (slurp (:body response)))))) + (testing "not found" + (let [response (app (request "/not-found"))] + (is (= 404 (:status response))))) - (testing "not found" - (let [response (app (request "/not-found"))] - (is (= 404 (:status response))))) + (testing "3-arity" + (let [result (atom nil) + respond (partial reset! result) + raise ::not-called] + (app (request "/hello.xml") respond raise) + (is (= "text/xml" (get-in @result [:headers "Content-Type"]))) + (is (get-in @result [:headers "Last-Modified"])) + (is (= "file\n" (slurp (:body @result))))))))) - (testing "3-arity" - (let [result (atom nil) - respond (partial reset! result) - raise ::not-called] - (app (request "/hello.xml") respond raise) - (is (= "text/xml" (get-in @result [:headers "Content-Type"]))) - (is (get-in @result [:headers "Last-Modified"])) - (is (= "file\n" (slurp (:body @result)))))))))) + (testing "from path" + (let [app (ring/ring-handler + (ring/router + ["/files/*" (ring/create-resource-handler)]) + (ring/create-default-handler)) + request #(request (str "/files" %)) + redirect #(redirect (str "/files" %))] + (testing test + (testing "different file-types" + (let [response (app (request "/hello.json"))] + (is (= "application/json" (get-in response [:headers "Content-Type"]))) + (is (get-in response [:headers "Last-Modified"])) + (is (= "{\"hello\": \"file\"}" (slurp (:body response))))) + (let [response (app (request "/hello.xml"))] + (is (= "text/xml" (get-in response [:headers "Content-Type"]))) + (is (get-in response [:headers "Last-Modified"])) + (is (= "file\n" (slurp (:body response)))))) + + (testing "index-files" + (let [response (app (request "/docs"))] + (is (= (redirect "/docs/index.html") response))) + (let [response (app (request "/docs/"))] + (is (= (redirect "/docs/index.html") response)))) + + (testing "not found" + (let [response (app (request "/not-found"))] + (is (= 404 (:status response))))) + + (testing "3-arity" + (let [result (atom nil) + respond (partial reset! result) + raise ::not-called] + (app (request "/hello.xml") respond raise) + (is (= "text/xml" (get-in @result [:headers "Content-Type"]))) + (is (get-in @result [:headers "Last-Modified"])) + (is (= "file\n" (slurp (:body @result)))))))))) + + (testing "outside a router" + + (testing "from root" + (let [app (ring/ring-handler + (ring/router []) + (ring/routes + (ring/create-resource-handler {:path "/"}) + (ring/create-default-handler)))] + (testing test + (testing "different file-types" + (let [response (app (request "/hello.json"))] + (is (= "application/json" (get-in response [:headers "Content-Type"]))) + (is (get-in response [:headers "Last-Modified"])) + (is (= "{\"hello\": \"file\"}" (slurp (:body response))))) + (let [response (app (request "/hello.xml"))] + (is (= "text/xml" (get-in response [:headers "Content-Type"]))) + (is (get-in response [:headers "Last-Modified"])) + (is (= "file\n" (slurp (:body response)))))) + + (testing "index-files" + (let [response (app (request "/docs"))] + (is (= (redirect "/docs/index.html") response))) + (let [response (app (request "/docs/"))] + (is (= (redirect "/docs/index.html") response)))) + + (testing "not found" + (let [response (app (request "/not-found"))] + (is (= 404 (:status response))))) + + (testing "3-arity" + (let [result (atom nil) + respond (partial reset! result) + raise ::not-called] + (app (request "/hello.xml") respond raise) + (is (= "text/xml" (get-in @result [:headers "Content-Type"]))) + (is (get-in @result [:headers "Last-Modified"])) + (is (= "file\n" (slurp (:body @result))))))))) + + (testing "from path" + (let [app (ring/ring-handler + (ring/router []) + (ring/routes + (ring/create-resource-handler {:path "/files"}) + (ring/create-default-handler))) + request #(request (str "/files" %)) + redirect #(redirect (str "/files" %))] + (testing test + (testing "different file-types" + (let [response (app (request "/hello.json"))] + (is (= "application/json" (get-in response [:headers "Content-Type"]))) + (is (get-in response [:headers "Last-Modified"])) + (is (= "{\"hello\": \"file\"}" (slurp (:body response))))) + (let [response (app (request "/hello.xml"))] + (is (= "text/xml" (get-in response [:headers "Content-Type"]))) + (is (get-in response [:headers "Last-Modified"])) + (is (= "file\n" (slurp (:body response)))))) + + (testing "index-files" + (let [response (app (request "/docs"))] + (is (= (redirect "/docs/index.html") response))) + (let [response (app (request "/docs/"))] + (is (= (redirect "/docs/index.html") response)))) + + (testing "not found" + (let [response (app (request "/not-found"))] + (is (= 404 (:status response))))) + + (testing "3-arity" + (let [result (atom nil) + respond (partial reset! result) + raise ::not-called] + (app (request "/hello.xml") respond raise) + (is (= "text/xml" (get-in @result [:headers "Content-Type"]))) + (is (get-in @result [:headers "Last-Modified"])) + (is (= "file\n" (slurp (:body @result))))))))))))) From 21de7a038a2b4f4b20444ec888c28b243cbd0ec9 Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Mon, 4 Jun 2018 23:57:08 +0300 Subject: [PATCH 11/17] 0.1.2-SNAPSHOT --- examples/just-coercion-with-ring/project.clj | 2 +- examples/ring-example/project.clj | 2 +- examples/ring-swagger/project.clj | 2 +- modules/reitit-core/project.clj | 2 +- modules/reitit-ring/project.clj | 2 +- modules/reitit-schema/project.clj | 2 +- modules/reitit-spec/project.clj | 2 +- modules/reitit-swagger-ui/project.clj | 2 +- modules/reitit-swagger/project.clj | 2 +- modules/reitit/project.clj | 2 +- project.clj | 16 ++++++++-------- 11 files changed, 18 insertions(+), 18 deletions(-) diff --git a/examples/just-coercion-with-ring/project.clj b/examples/just-coercion-with-ring/project.clj index d14fe645..e3d0513e 100644 --- a/examples/just-coercion-with-ring/project.clj +++ b/examples/just-coercion-with-ring/project.clj @@ -3,4 +3,4 @@ :dependencies [[org.clojure/clojure "1.9.0"] [ring "1.6.3"] [metosin/muuntaja "0.4.1"] - [metosin/reitit "0.1.1"]]) + [metosin/reitit "0.1.2-SNAPSHOT"]]) diff --git a/examples/ring-example/project.clj b/examples/ring-example/project.clj index 332cb4b8..31429cc4 100644 --- a/examples/ring-example/project.clj +++ b/examples/ring-example/project.clj @@ -3,4 +3,4 @@ :dependencies [[org.clojure/clojure "1.9.0"] [ring "1.6.3"] [metosin/muuntaja "0.4.1"] - [metosin/reitit "0.1.1"]]) + [metosin/reitit "0.1.2-SNAPSHOT"]]) diff --git a/examples/ring-swagger/project.clj b/examples/ring-swagger/project.clj index dfe97c89..37283a17 100644 --- a/examples/ring-swagger/project.clj +++ b/examples/ring-swagger/project.clj @@ -3,5 +3,5 @@ :dependencies [[org.clojure/clojure "1.9.0"] [ring "1.6.3"] [metosin/muuntaja "0.5.0"] - [metosin/reitit "0.1.1"]] + [metosin/reitit "0.1.2-SNAPSHOT"]] :repl-options {:init-ns example.server}) diff --git a/modules/reitit-core/project.clj b/modules/reitit-core/project.clj index 23099fba..d241b12b 100644 --- a/modules/reitit-core/project.clj +++ b/modules/reitit-core/project.clj @@ -1,4 +1,4 @@ -(defproject metosin/reitit-core "0.1.1" +(defproject metosin/reitit-core "0.1.2-SNAPSHOT" :description "Snappy data-driven router for Clojure(Script)" :url "https://github.com/metosin/reitit" :license {:name "Eclipse Public License" diff --git a/modules/reitit-ring/project.clj b/modules/reitit-ring/project.clj index 71be148e..fbb913c1 100644 --- a/modules/reitit-ring/project.clj +++ b/modules/reitit-ring/project.clj @@ -1,4 +1,4 @@ -(defproject metosin/reitit-ring "0.1.1" +(defproject metosin/reitit-ring "0.1.2-SNAPSHOT" :description "Reitit: Ring routing" :url "https://github.com/metosin/reitit" :license {:name "Eclipse Public License" diff --git a/modules/reitit-schema/project.clj b/modules/reitit-schema/project.clj index 0663c72b..d107bada 100644 --- a/modules/reitit-schema/project.clj +++ b/modules/reitit-schema/project.clj @@ -1,4 +1,4 @@ -(defproject metosin/reitit-schema "0.1.1" +(defproject metosin/reitit-schema "0.1.2-SNAPSHOT" :description "Reitit: Plumatic Schema coercion" :url "https://github.com/metosin/reitit" :license {:name "Eclipse Public License" diff --git a/modules/reitit-spec/project.clj b/modules/reitit-spec/project.clj index f217ae61..9ad9b343 100644 --- a/modules/reitit-spec/project.clj +++ b/modules/reitit-spec/project.clj @@ -1,4 +1,4 @@ -(defproject metosin/reitit-spec "0.1.1" +(defproject metosin/reitit-spec "0.1.2-SNAPSHOT" :description "Reitit: clojure.spec coercion" :url "https://github.com/metosin/reitit" :license {:name "Eclipse Public License" diff --git a/modules/reitit-swagger-ui/project.clj b/modules/reitit-swagger-ui/project.clj index 5d530067..528791cd 100644 --- a/modules/reitit-swagger-ui/project.clj +++ b/modules/reitit-swagger-ui/project.clj @@ -1,4 +1,4 @@ -(defproject metosin/reitit-swagger-ui "0.1.1" +(defproject metosin/reitit-swagger-ui "0.1.2-SNAPSHOT" :description "Reitit: Swagger-ui support" :url "https://github.com/metosin/reitit" :license {:name "Eclipse Public License" diff --git a/modules/reitit-swagger/project.clj b/modules/reitit-swagger/project.clj index 0339c0cc..e301f223 100644 --- a/modules/reitit-swagger/project.clj +++ b/modules/reitit-swagger/project.clj @@ -1,4 +1,4 @@ -(defproject metosin/reitit-swagger "0.1.1" +(defproject metosin/reitit-swagger "0.1.2-SNAPSHOT" :description "Reitit: Swagger-support" :url "https://github.com/metosin/reitit" :license {:name "Eclipse Public License" diff --git a/modules/reitit/project.clj b/modules/reitit/project.clj index 51aec6d4..6d1fffa5 100644 --- a/modules/reitit/project.clj +++ b/modules/reitit/project.clj @@ -1,4 +1,4 @@ -(defproject metosin/reitit "0.1.1" +(defproject metosin/reitit "0.1.2-SNAPSHOT" :description "Snappy data-driven router for Clojure(Script)" :url "https://github.com/metosin/reitit" :license {:name "Eclipse Public License" diff --git a/project.clj b/project.clj index c4a82e6c..bbe85707 100644 --- a/project.clj +++ b/project.clj @@ -1,4 +1,4 @@ -(defproject metosin/reitit-parent "0.1.1" +(defproject metosin/reitit-parent "0.1.2-SNAPSHOT" :description "Snappy data-driven router for Clojure(Script)" :url "https://github.com/metosin/reitit" :license {:name "Eclipse Public License" @@ -9,13 +9,13 @@ :source-uri "https://github.com/metosin/reitit/{version}/{filepath}#L{line}" :metadata {:doc/format :markdown}} - :managed-dependencies [[metosin/reitit "0.1.1"] - [metosin/reitit-core "0.1.1"] - [metosin/reitit-ring "0.1.1"] - [metosin/reitit-spec "0.1.1"] - [metosin/reitit-schema "0.1.1"] - [metosin/reitit-swagger "0.1.1"] - [metosin/reitit-swagger-ui "0.1.1"] + :managed-dependencies [[metosin/reitit "0.1.2-SNAPSHOT"] + [metosin/reitit-core "0.1.2-SNAPSHOT"] + [metosin/reitit-ring "0.1.2-SNAPSHOT"] + [metosin/reitit-spec "0.1.2-SNAPSHOT"] + [metosin/reitit-schema "0.1.2-SNAPSHOT"] + [metosin/reitit-swagger "0.1.2-SNAPSHOT"] + [metosin/reitit-swagger-ui "0.1.2-SNAPSHOT"] [meta-merge "1.0.0"] [ring/ring-core "1.6.3"] From 4a4cd5ae9e13ae1a54d2b11d09f96dbab45f4dd8 Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Tue, 5 Jun 2018 00:03:00 +0300 Subject: [PATCH 12/17] response/redirect --- modules/reitit-ring/src/reitit/ring.cljc | 2 +- test/cljc/reitit/ring_test.cljc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/reitit-ring/src/reitit/ring.cljc b/modules/reitit-ring/src/reitit/ring.cljc index 3577ed63..fb8fe900 100644 --- a/modules/reitit-ring/src/reitit/ring.cljc +++ b/modules/reitit-ring/src/reitit/ring.cljc @@ -107,7 +107,7 @@ (loop [[file & files] index-files] (if file (if (resource-response (join-paths path file)) - {:status 302 :headers {"Location" (join-paths uri file)}} + (response/redirect (join-paths uri file)) (recur files)))))) handler (if path (fn [request] diff --git a/test/cljc/reitit/ring_test.cljc b/test/cljc/reitit/ring_test.cljc index 200cce36..85697271 100644 --- a/test/cljc/reitit/ring_test.cljc +++ b/test/cljc/reitit/ring_test.cljc @@ -268,7 +268,7 @@ #?(:clj (deftest resource-handler-test - (let [redirect (fn [uri] {:status 302 :headers {"Location" uri}}) + (let [redirect (fn [uri] {:status 302, :body "", :headers {"Location" uri}}) request (fn [uri] {:uri uri, :request-method :get})] (testing "inside a router" From a8a96c0e859517c5c0a4f17f8e991a0c303e6a82 Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Tue, 5 Jun 2018 00:08:31 +0300 Subject: [PATCH 13/17] Update CHANGELOG --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e1274034..a0d10979 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,9 @@ (is (= [] (r/routes (r/router [nil [nil] [[nil nil nil]]])))) (is (= [] (r/routes (r/router ["/ping" [nil "/pong"]]))))) ``` +### `reitit-ring` + +* Use HTTP redirect (302) with index-files in `reitit.ring/create-resource-handler`. ### `reitit-schema` @@ -29,6 +32,8 @@ ### `reitit-swagger-ui` +* Use HTTP redirect (302) with index-files in `reitit.swagger-ui/create-swagger-ui-handler`. + * updated dependencies: ```clj From 0cafb9639d082ac77fca303a5d8b6c4c5390158d Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Tue, 5 Jun 2018 08:49:30 +0300 Subject: [PATCH 14/17] . --- test/cljc/reitit/core_test.cljc | 6 ------ test/cljc/reitit/ring_test.cljc | 3 +-- test/cljc/reitit/spec_test.cljc | 2 +- 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/test/cljc/reitit/core_test.cljc b/test/cljc/reitit/core_test.cljc index f702f9bd..f8233888 100644 --- a/test/cljc/reitit/core_test.cljc +++ b/test/cljc/reitit/core_test.cljc @@ -246,9 +246,3 @@ [["/a"] ["/a"]])))) (testing "can be configured to ignore" (is (not (nil? (r/router [["/a"] ["/a"]] {:conflicts (constantly nil)}))))))) - -(testing "nil routes are stripped" - (is (= [] (r/routes (r/router nil)))) - (is (= [] (r/routes (r/router [nil ["/ping"]])))) - (is (= [] (r/routes (r/router [nil [nil] [[nil nil nil]]])))) - (is (= [] (r/routes (r/router ["/ping" [nil "/pong"]]))))) diff --git a/test/cljc/reitit/ring_test.cljc b/test/cljc/reitit/ring_test.cljc index 85697271..5fb6d3d1 100644 --- a/test/cljc/reitit/ring_test.cljc +++ b/test/cljc/reitit/ring_test.cljc @@ -3,8 +3,7 @@ [clojure.set :as set] [reitit.middleware :as middleware] [reitit.ring :as ring] - [reitit.core :as r] - [clojure.string :as str]) + [reitit.core :as r]) #?(:clj (:import (clojure.lang ExceptionInfo)))) diff --git a/test/cljc/reitit/spec_test.cljc b/test/cljc/reitit/spec_test.cljc index 6dafb3ba..880328e5 100644 --- a/test/cljc/reitit/spec_test.cljc +++ b/test/cljc/reitit/spec_test.cljc @@ -66,7 +66,7 @@ {:conflicts (fn [_])} {:router r/linear-router}) - #_(are [opts] + (are [opts] (is (thrown-with-msg? ExceptionInfo #"Call to #'reitit.core/router did not conform to spec" From 8d58cbc71f58519a8134d6cdbaa3d78b5fef7708 Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Tue, 5 Jun 2018 08:55:44 +0300 Subject: [PATCH 15/17] Fix example --- doc/ring/swagger.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/ring/swagger.md b/doc/ring/swagger.md index 3d282a65..cc6dadc6 100644 --- a/doc/ring/swagger.md +++ b/doc/ring/swagger.md @@ -183,7 +183,7 @@ Whole example project is in [`/examples/ring-swagger`](https://github.com/metosi "application/transit+json"}}}}) (ring/routes (swagger-ui/create-swagger-ui-handler - {:path "", :url "/api/swagger.json"}) + {:path "/", :url "/api/swagger.json"}) (ring/create-default-handler)))) (defn start [] From b2c0b2fdfaead2ef6e6df9b31b7db36097bcd429 Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Tue, 5 Jun 2018 09:39:39 +0300 Subject: [PATCH 16/17] confirm to ring spec, fixes #83 --- CHANGELOG.md | 3 +++ modules/reitit-ring/src/reitit/ring.cljc | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a0d10979..b0c351df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,9 @@ ### `reitit-ring` * Use HTTP redirect (302) with index-files in `reitit.ring/create-resource-handler`. +* `reitit.ring/create-default-handler` now conforms to [RING Spec](https://github.com/ring-clojure/ring/blob/master/SPEC), Fixes [#83](https://github.com/metosin/reitit/issues/83) + +https://github.com/metosin/reitit/issues/83 ### `reitit-schema` diff --git a/modules/reitit-ring/src/reitit/ring.cljc b/modules/reitit-ring/src/reitit/ring.cljc index fb8fe900..1c03e4f0 100644 --- a/modules/reitit-ring/src/reitit/ring.cljc +++ b/modules/reitit-ring/src/reitit/ring.cljc @@ -46,9 +46,9 @@ | `:not-acceptable` | 406, handler returned `nil`" ([] (create-default-handler - {:not-found (constantly {:status 404, :body ""}) - :method-not-allowed (constantly {:status 405, :body ""}) - :not-acceptable (constantly {:status 406, :body ""})})) + {:not-found (constantly {:status 404, :body "", :headers {}}) + :method-not-allowed (constantly {:status 405, :body "", :headers {}}) + :not-acceptable (constantly {:status 406, :body "", :headers {}})})) ([{:keys [not-found method-not-allowed not-acceptable]}] (fn ([request] From f2d3d0a125e785fe3f4add1fb51317e9fd316533 Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Wed, 6 Jun 2018 10:33:58 +0300 Subject: [PATCH 17/17] if -> when --- modules/reitit-core/src/reitit/core.cljc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/reitit-core/src/reitit/core.cljc b/modules/reitit-core/src/reitit/core.cljc index eea9ab7a..b3785447 100644 --- a/modules/reitit-core/src/reitit/core.cljc +++ b/modules/reitit-core/src/reitit/core.cljc @@ -39,7 +39,7 @@ (walk-one [pacc macc routes] (if (vector? (first routes)) (walk-many pacc macc routes) - (if (string? (first routes)) + (when (string? (first routes)) (let [[path & [maybe-arg :as args]] routes [data childs] (if (or (vector? maybe-arg) (nil? maybe-arg)) [{} args]