From b8b442b5985e38e1948c632b10c3f8cfe571134f Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Sat, 9 May 2020 17:18:17 +0300 Subject: [PATCH 01/12] Fix #394 --- CHANGELOG.md | 4 ++++ modules/reitit-ring/src/reitit/ring.cljc | 2 +- test/cljc/reitit/ring_test.cljc | 21 +++++++++++++++------ 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6de9d4ba..8606ebe9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,10 @@ is called the first time, so that `rfe/push-state` and such can be called [metosin/malli "0.0.1-20200404.091302-14"] is available but we use "0.0.1-20200305.102752-13" ``` +### `reitit-ring` + +* `reitit.ring/routes` strips away `nil` routes, fixes [#394](https://github.com/metosin/reitit/issues/394) + ## 0.4.2 (2020-01-17) ### `reitit` diff --git a/modules/reitit-ring/src/reitit/ring.cljc b/modules/reitit-ring/src/reitit/ring.cljc index 463e911e..f919b40c 100644 --- a/modules/reitit-ring/src/reitit/ring.cljc +++ b/modules/reitit-ring/src/reitit/ring.cljc @@ -108,7 +108,7 @@ (defn routes "Create a ring handler by combining several handlers into one." [& handlers] - (let [single-arity (apply some-fn handlers)] + (let [single-arity (apply some-fn (keep identity handlers))] (fn ([request] (single-arity request)) diff --git a/test/cljc/reitit/ring_test.cljc b/test/cljc/reitit/ring_test.cljc index 1c40defd..8710f178 100644 --- a/test/cljc/reitit/ring_test.cljc +++ b/test/cljc/reitit/ring_test.cljc @@ -24,6 +24,15 @@ ([request respond _] (respond (handler request)))) +(deftest routes-test + (testing "nils are removed" + (is (= 123 + ((ring/routes + (constantly nil) + nil + (constantly 123)) + ::irrelevant))))) + (deftest ring-router-test (testing "all paths should have a handler" @@ -161,8 +170,8 @@ (deftest default-handler-test (let [response {:status 200, :body "ok"} router (ring/router - [["/ping" {:get (constantly response)}] - ["/pong" (constantly nil)]]) + [["/ping" {:get (constantly response)}] + ["/pong" (constantly nil)]]) app (ring/ring-handler router)] (testing "match" @@ -188,9 +197,9 @@ (testing "with custom http responses" (let [app (ring/ring-handler router (ring/create-default-handler - {:not-found (constantly {:status -404}) - :method-not-allowed (constantly {:status -405}) - :not-acceptable (constantly {:status -406})}))] + {:not-found (constantly {:status -404}) + :method-not-allowed (constantly {:status -405}) + :not-acceptable (constantly {:status -406})}))] (testing "route doesn't match" (is (= -404 (:status (app {:request-method :get, :uri "/"}))))) (testing "method doesn't match" @@ -200,7 +209,7 @@ (testing "with some custom http responses" (let [app (ring/ring-handler router (ring/create-default-handler - {:not-found (constantly {:status -404})}))] + {:not-found (constantly {:status -404})}))] (testing "route doesn't match" (is (= 405 (:status (app {:request-method :post, :uri "/ping"})))))))))) From 711c1fea8fc3ba1f532ceface440405f5c534b43 Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Sat, 9 May 2020 18:21:03 +0300 Subject: [PATCH 02/12] Latest Sieppari & polish CHANGELOG --- CHANGELOG.md | 15 +++++++-------- project.clj | 2 +- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8606ebe9..b05c34a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,20 +14,19 @@ We use [Break Versioning][breakver]. The version numbers follow a `. Date: Sat, 9 May 2020 18:22:57 +0300 Subject: [PATCH 03/12] Add create-file-handler, fixes #395 --- CHANGELOG.md | 1 + modules/reitit-ring/src/reitit/ring.cljc | 97 +++++--- test/cljc/reitit/ring_test.cljc | 271 ++++++++++++----------- 3 files changed, 200 insertions(+), 169 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b05c34a9..bad25715 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ is called the first time, so that `rfe/push-state` and such can be called ### `reitit-ring` * `reitit.ring/routes` strips away `nil` routes, fixes [#394](https://github.com/metosin/reitit/issues/394) +* `reitit.ring/create-file-handler` to serve files from classpah, fixes [#395](https://github.com/metosin/reitit/issues/395) ## 0.4.2 (2020-01-17) diff --git a/modules/reitit-ring/src/reitit/ring.cljc b/modules/reitit-ring/src/reitit/ring.cljc index f919b40c..a9cd7d40 100644 --- a/modules/reitit-ring/src/reitit/ring.cljc +++ b/modules/reitit-ring/src/reitit/ring.cljc @@ -189,6 +189,48 @@ ;; TODO: ring.middleware.not-modified/wrap-not-modified ;; TODO: ring.middleware.head/wrap-head ;; TODO: handle etags + (defn -create-file-or-resource-handler + [response-fn {:keys [parameter root path loader allow-symlinks? index-files paths not-found-handler] + :or {parameter (keyword "") + root "public" + index-files ["index.html"] + paths (constantly nil) + not-found-handler (constantly {:status 404, :body "", :headers {}})}}] + (let [options {:root root + :loader loader + :index-files? false + :allow-symlinks? allow-symlinks?} + path-size (count path) + create (fn [handler] + (fn + ([request] (handler request)) + ([request respond _] (respond (handler request))))) + join-paths (fn [& paths] + (str/replace (str/replace (str/join "/" paths) #"([/]+)" "/") #"/$" "")) + response (fn [path] + (if-let [response (or (paths (join-paths "/" path)) + (response-fn path options))] + (response/content-type response (mime-type/ext-mime-type path)))) + path-or-index-response (fn [path uri] + (or (response path) + (loop [[file & files] index-files] + (if file + (if (response (join-paths path file)) + (response/redirect (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 [uri (:uri request) + path (-> request :path-params parameter)] + (or (path-or-index-response path uri) + (not-found-handler request)))))] + (create handler)))) + +#?(:clj (defn create-resource-handler "A ring handler for serving classpath resources, configured via options: @@ -202,42 +244,25 @@ | :not-found-handler | optional handler function to use if the requested resource is missing (404 Not Found)" ([] (create-resource-handler nil)) - ([{:keys [parameter root path loader allow-symlinks? index-files paths not-found-handler] - :or {parameter (keyword "") - root "public" - index-files ["index.html"] - paths (constantly nil) - not-found-handler (constantly {:status 404, :body "", :headers {}})}}] - (let [options {:root root, :loader loader, :allow-symlinks? allow-symlinks?} - path-size (count path) - create (fn [handler] - (fn - ([request] (handler request)) - ([request respond _] (respond (handler request))))) - join-paths (fn [& paths] - (str/replace (str/replace (str/join "/" paths) #"([/]+)" "/") #"/$" "")) - resource-response (fn [path] - (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 - (if (resource-response (join-paths path file)) - (response/redirect (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 [uri (:uri request) - path (-> request :path-params parameter)] - (or (path-or-index-response path uri) - (not-found-handler request)))))] - (create handler))))) + ([opts] + (-create-file-or-resource-handler response/resource-response opts)))) + +#?(:clj + (defn create-file-handler + "A ring handler for serving file resources, configured via options: + + | key | description | + | -------------------|-------------| + | :parameter | optional name of the wildcard parameter, defaults to unnamed keyword `:` + | :root | optional resource root, defaults to `\"public\"` + | :path | optional path to mount the handler to. Works only if mounted outside of a router. + | :loader | optional class loader to resolve the resources + | :index-files | optional vector of index-files to look in a resource directory, defaults to `[\"index.html\"]` + | :not-found-handler | optional handler function to use if the requested resource is missing (404 Not Found)" + ([] + (create-file-handler nil)) + ([opts] + (-create-file-or-resource-handler response/file-response opts)))) (defn create-enrich-request [inject-match? inject-router?] (cond diff --git a/test/cljc/reitit/ring_test.cljc b/test/cljc/reitit/ring_test.cljc index 8710f178..8cc1fb2b 100644 --- a/test/cljc/reitit/ring_test.cljc +++ b/test/cljc/reitit/ring_test.cljc @@ -454,158 +454,163 @@ (app request))))))) #?(:clj - (deftest resource-handler-test + (deftest file-resource-handler-test (let [redirect (fn [uri] {:status 302, :body "", :headers {"Location" uri}}) request (fn [uri] {:uri uri, :request-method :get})] - (testing "inside a router" - (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)))))) + (doseq [[name create] [["resource-handler" ring/create-resource-handler] + ["file-handler" #(ring/create-file-handler (assoc % :root "dev-resources/public"))]]] - (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 (str "for " name) + (testing "inside a router" - (testing "not found" - (let [response (app (request "/not-found"))] - (is (= 404 (:status response))))) + (testing "from root" + (let [app (ring/ring-handler + (ring/router + ["/*" (create nil)]) + (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 "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 "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 "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 "not found" + (let [response (app (request "/not-found"))] + (is (= 404 (:status 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 "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 "not found" - (let [response (app (request "/not-found"))] - (is (= 404 (:status response))))) + (testing "from path" + (let [app (ring/ring-handler + (ring/router + ["/files/*" (create nil)]) + (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 "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 "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 "outside a router" + (testing "not found" + (let [response (app (request "/not-found"))] + (is (= 404 (:status response))))) - (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 "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 "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 "outside a router" - (testing "not found" - (let [response (app (request "/not-found"))] - (is (= 404 (:status response))))) + (testing "from root" + (let [app (ring/ring-handler + (ring/router []) + (ring/routes + (create {: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 "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 "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 "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 "not found" + (let [response (app (request "/not-found"))] + (is (= 404 (:status 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 "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 "not found" - (let [response (app (request "/not-found"))] - (is (= 404 (:status response))))) + (testing "from path" + (let [app (ring/ring-handler + (ring/router []) + (ring/routes + (create {: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 "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 "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))))))))))))))) (deftest router-available-in-default-branch (testing "1-arity" From aa19d9af4691163bf5c2235fc837ff237fec2e5a Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Sat, 9 May 2020 18:27:52 +0300 Subject: [PATCH 04/12] Update dependenices --- CHANGELOG.md | 7 ++++++ project.clj | 60 ++++++++++++++++++++++++++-------------------------- 2 files changed, 37 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bad25715..38aeee76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,13 @@ We use [Break Versioning][breakver]. The version numbers follow a `. Date: Sat, 9 May 2020 18:28:03 +0300 Subject: [PATCH 05/12] Fix reflection warning --- modules/reitit-pedestal/src/reitit/pedestal.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/reitit-pedestal/src/reitit/pedestal.clj b/modules/reitit-pedestal/src/reitit/pedestal.clj index fcca5a46..7d53cd06 100644 --- a/modules/reitit-pedestal/src/reitit/pedestal.clj +++ b/modules/reitit-pedestal/src/reitit/pedestal.clj @@ -11,7 +11,7 @@ (defn- arities [f] (->> (class f) .getDeclaredMethods - (filter #(= "invoke" (.getName %))) + (filter (fn [^Method m] (= "invoke" (.getName m)))) (map #(alength (.getParameterTypes ^Method %))) (set))) From c8ed40e30e0f34d7e7244b939982171f726eb6e4 Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Sat, 9 May 2020 18:31:49 +0300 Subject: [PATCH 06/12] Update CHANGELOG --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 38aeee76..932b6776 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,15 @@ We use [Break Versioning][breakver]. The version numbers follow a `. Date: Sat, 9 May 2020 18:35:40 +0300 Subject: [PATCH 07/12] Sieppari changes --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 932b6776..b2e7b0ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,14 @@ is called the first time, so that `rfe/push-state` and such can be called * `reitit.ring/routes` strips away `nil` routes, fixes [#394](https://github.com/metosin/reitit/issues/394) * `reitit.ring/create-file-handler` to serve files from classpah, fixes [#395](https://github.com/metosin/reitit/issues/395) +### `reitit-sieppari` + +* changes from Sieppari: + * fixed performance regression bugs, order of magnitude faster dispatching + * **BREAKING**: Out-of-the-box support for `core.async` and `manifold` are dropped, to use them, one needs to explicitely require the following side-effecting namespaces: + * `sieppari.async.core-async` for core.async + * `sieppari.async.manifold` for manifold + ## 0.4.2 (2020-01-17) ### `reitit` From e9792892d01d38747a9452de20afbfcf9ce743fe Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Sat, 9 May 2020 18:37:05 +0300 Subject: [PATCH 08/12] spec-tools changes --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b2e7b0ff..3f8d8726 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,10 @@ is called the first time, so that `rfe/push-state` and such can be called * `reitit.ring/routes` strips away `nil` routes, fixes [#394](https://github.com/metosin/reitit/issues/394) * `reitit.ring/create-file-handler` to serve files from classpah, fixes [#395](https://github.com/metosin/reitit/issues/395) +### `reitit-spec` + +* lots of bug fixes, see [spec-tools changelog](https://github.com/metosin/spec-tools/blob/master/CHANGELOG.md#0102-2020-05-05) + ### `reitit-sieppari` * changes from Sieppari: From 728fc854bf6cbeec80024916406532eb599d2a63 Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Tue, 12 May 2020 08:32:40 +0300 Subject: [PATCH 09/12] spell-spec & fix-typo --- CHANGELOG.md | 3 ++- project.clj | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f8d8726..6b2d3e75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ We use [Break Versioning][breakver]. The version numbers follow a `. Date: Tue, 12 May 2020 08:37:08 +0300 Subject: [PATCH 10/12] new swagger-ui --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b2d3e75..e8bcde8f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -61,6 +61,17 @@ is called the first time, so that `rfe/push-state` and such can be called * `sieppari.async.core-async` for core.async * `sieppari.async.manifold` for manifold +### `reitit-swagger` + +* default to the new swagger-ui (3.25.0), to get old back add a dependency to: + +```clj +[metosin/ring-swagger-ui "2.2.10"] +``` + +### `reitit-sieppari` + + ## 0.4.2 (2020-01-17) ### `reitit` From d36c47d7b100a5ada71070e379455a36d872f588 Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Tue, 12 May 2020 21:21:39 +0300 Subject: [PATCH 11/12] :reitit.ring/default-options-endpoint & :reitit.http/default-options-endpoint --- CHANGELOG.md | 9 +++++++++ doc/ring/ring.md | 10 +++++----- modules/reitit-http/src/reitit/http.cljc | 22 +++++++++++++--------- modules/reitit-ring/src/reitit/ring.cljc | 4 ++-- test/clj/reitit/http_test.clj | 9 +++++++-- 5 files changed, 36 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e8bcde8f..0157549e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,15 @@ is called the first time, so that `rfe/push-state` and such can be called * `reitit.ring/routes` strips away `nil` routes, fixes [#394](https://github.com/metosin/reitit/issues/394) * `reitit.ring/create-file-handler` to serve files from filesystem, fixes [#395](https://github.com/metosin/reitit/issues/395) +* **BREAKING**: router option `:reitit.ring/default-options-handler` is deprecated + * fails with router creation time error + * use `:reitit.ring/default-options-endpoint` instead, takes an expandable route data instead just of a handler. + +### `reitit-http` + +* **BREAKING**: router option `:reitit.http/default-options-handler` is deprecated + * fails with router creation time error + * use `:reitit.http/default-options-endpoint` instead, takes an expandable route data instead just of a handler. ### `reitit-spec` diff --git a/doc/ring/ring.md b/doc/ring/ring.md index 2bb622aa..cd9d1e79 100644 --- a/doc/ring/ring.md +++ b/doc/ring/ring.md @@ -14,11 +14,11 @@ Read more about the [Ring Concepts](https://github.com/ring-clojure/ring/wiki/Co It accepts the following options: -| key | description | -| ---------------------------------------|-------------| -| `:reitit.middleware/transform` | Function of `[Middleware] => [Middleware]` to transform the expanded Middleware (default: identity). -| `:reitit.middleware/registry` | Map of `keyword => IntoMiddleware` to replace keyword references into Middleware -| `:reitit.ring/default-options-handler` | Default handler for `:options` method in endpoints (default: default-options-handler) +| key | description | +| ----------------------------------------|-------------| +| `:reitit.middleware/transform` | Function of `[Middleware] => [Middleware]` to transform the expanded Middleware (default: identity). +| `:reitit.middleware/registry` | Map of `keyword => IntoMiddleware` to replace keyword references into Middleware +| `:reitit.ring/default-options-endpoint` | Default endpoint for `:options` method (default: default-options-endpoint) Example router: diff --git a/modules/reitit-http/src/reitit/http.cljc b/modules/reitit-http/src/reitit/http.cljc index afd39a80..fa4c26fc 100644 --- a/modules/reitit-http/src/reitit/http.cljc +++ b/modules/reitit-http/src/reitit/http.cljc @@ -1,6 +1,7 @@ (ns reitit.http (:require [meta-merge.core :refer [meta-merge]] [reitit.interceptor :as interceptor] + [reitit.exception :as ex] [reitit.ring :as ring] [reitit.core :as r])) @@ -13,11 +14,11 @@ (update acc method expand opts) acc)) data ring/http-methods)]) -(defn compile-result [[path data] {::keys [default-options-handler] :as opts}] +(defn compile-result [[path data] {:keys [::default-options-endpoint expand] :as opts}] (let [[top childs] (ring/group-keys data) childs (cond-> childs - (and (not (:options childs)) (not (:handler top)) default-options-handler) - (assoc :options {:no-doc true, :handler default-options-handler})) + (and (not (:options childs)) (not (:handler top)) default-options-endpoint) + (assoc :options (expand default-options-endpoint opts))) compile (fn [[path data] opts scope] (interceptor/compile-result [path data] opts scope)) ->endpoint (fn [p d m s] @@ -47,11 +48,11 @@ support for http-methods and Interceptors. See documentation on [[reitit.core/router]] for available options. In addition, the following options are available: - | key | description - | ---------------------------------------|------------- - | `:reitit.interceptor/transform` | Function or vector of functions of type `[Interceptor] => [Interceptor]` to transform the expanded Interceptors (default: identity) - | `:reitit.interceptor/registry` | Map of `keyword => IntoInterceptor` to replace keyword references into Interceptors - | `:reitit.http/default-options-handler` | Default handler for `:options` method in endpoints (default: reitit.ring/default-options-handler) + | key | description + | ----------------------------------------|------------- + | `:reitit.interceptor/transform` | Function or vector of functions of type `[Interceptor] => [Interceptor]` to transform the expanded Interceptors (default: identity) + | `:reitit.interceptor/registry` | Map of `keyword => IntoInterceptor` to replace keyword references into Interceptors + | `:reitit.http/default-options-endpoint` | Default endpoint for `:options` method in endpoints (default: reitit.ring/default-options-endpoint) Example: @@ -66,7 +67,10 @@ ([data opts] (let [opts (merge {:coerce coerce-handler :compile compile-result - ::default-options-handler ring/default-options-handler} opts)] + ::default-options-endpoint ring/default-options-endpoint} opts)] + (when (contains? opts ::default-options-handler) + (ex/fail! (str "Option :reitit.http/default-options-handler is deprecated." + " Use :reitit.http/default-options-endpoint instead."))) (r/router data opts)))) (defn routing-interceptor diff --git a/modules/reitit-ring/src/reitit/ring.cljc b/modules/reitit-ring/src/reitit/ring.cljc index a9cd7d40..5345ad43 100644 --- a/modules/reitit-ring/src/reitit/ring.cljc +++ b/modules/reitit-ring/src/reitit/ring.cljc @@ -1,12 +1,12 @@ (ns reitit.ring (:require [meta-merge.core :refer [meta-merge]] [reitit.middleware :as middleware] + [reitit.exception :as ex] [reitit.core :as r] [reitit.impl :as impl] #?@(:clj [[ring.util.mime-type :as mime-type] [ring.util.response :as response]]) - [clojure.string :as str] - [reitit.exception :as ex])) + [clojure.string :as str])) (declare get-match) (declare get-router) diff --git a/test/clj/reitit/http_test.clj b/test/clj/reitit/http_test.clj index 4235b9ce..8c2c5ba4 100644 --- a/test/clj/reitit/http_test.clj +++ b/test/clj/reitit/http_test.clj @@ -6,7 +6,8 @@ [reitit.interceptor.sieppari :as sieppari] [reitit.http :as http] [reitit.ring :as ring] - [reitit.core :as r])) + [reitit.core :as r]) + (:import (clojure.lang ExceptionInfo))) (defn interceptor [name] {:enter (fn [ctx] (update-in ctx [:request ::i] (fnil conj []) name))}) @@ -169,6 +170,10 @@ (testing "handler rejects" (is (= -406 (:status (app {:request-method :get, :uri "/pong"})))))))))) +(deftest default-options-handler-test + (testing "Assertion fails when using deprecated options-handler" + (is (thrown? ExceptionInfo (ring/router [] {::ring/default-options-handler (fn [_])}))))) + (deftest default-options-handler-test (let [response {:status 200, :body "ok"}] @@ -199,7 +204,7 @@ [["/get" {:get (constantly response)}] ["/options" {:options (constantly response)}] ["/any" (constantly response)]] - {::http/default-options-handler nil}) + {::http/default-options-endpoint nil}) {:executor sieppari/executor})] (testing "endpoint with a non-options handler" From 94daa9b136ca23ee50fbe52f0ef64c770c3ccdd7 Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Tue, 12 May 2020 21:23:18 +0300 Subject: [PATCH 12/12] . --- CHANGELOG.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0157549e..c8003383 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -78,9 +78,6 @@ is called the first time, so that `rfe/push-state` and such can be called [metosin/ring-swagger-ui "2.2.10"] ``` -### `reitit-sieppari` - - ## 0.4.2 (2020-01-17) ### `reitit`