Skip to content
This repository has been archived by the owner on Feb 28, 2024. It is now read-only.

Commit

Permalink
Add a full-route key to the request map
Browse files Browse the repository at this point in the history
This provides access to the full route that contains the common prefix.
The full-route info is added to the ':compojure/full-route' key in the
request map.

Co-authored-by: Liam Chen <[email protected]>
Co-authored-by: Claire Alvis <[email protected]>
  • Loading branch information
liamchzh and calvis committed Apr 27, 2022
1 parent d8f39af commit 9e1744a
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 16 deletions.
44 changes: 32 additions & 12 deletions src/compojure/core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,17 @@
(defn- wrap-route-info [handler route-info]
(fn
([request]
(handler (assoc request :compojure/route route-info)))
(let [full-route (str (:compojure/context request) (second route-info))]
(handler (assoc request
:compojure/route route-info
:compojure/full-route full-route))))
([request respond raise]
(handler (assoc request :compojure/route route-info) respond raise))))
(let [full-route (str (:compojure/context request) (second route-info))]
(handler (assoc request
:compojure/route route-info
:compojure/full-route full-route)
respond
raise)))))

(defn- wrap-route-matches [handler method path]
(fn
Expand Down Expand Up @@ -257,27 +265,39 @@
path (:path-info request uri)
context (or (:context request) "")
subpath (:__path-info params)
params (dissoc params :__path-info)]
params (dissoc params :__path-info)
context-route (:context-route (meta route))]
(-> request
(assoc-route-params (decode-route-params params))
(assoc :path-info (if (= subpath "") "/" subpath)
:context (remove-suffix uri subpath))))))
:context (remove-suffix uri subpath))
(update :compojure/context (fn [ctx] (str ctx context-route)))))))

(defn- context-route [route]
(let [re-context {:__path-info #"|/.*"}]
(cond
(string? route)
(clout/route-compile (str route ":__path-info") re-context)
(with-meta (clout/route-compile (str route ":__path-info") re-context)
{:context-route route})
(and (vector? route) (literal? route))
(clout/route-compile
(str (first route) ":__path-info")
(merge (apply hash-map (rest route)) re-context))
(with-meta (clout/route-compile
(str (first route) ":__path-info")
(merge (apply hash-map (rest route)) re-context))
{:context-route (first route)})
(vector? route)
`(clout/route-compile
(str ~(first route) ":__path-info")
~(merge (apply hash-map (rest route)) re-context))
`(let [route# ~(first route)]
(with-meta
(clout/route-compile
(str route# ":__path-info")
~(merge (apply hash-map (rest route)) re-context))
{:context-route route#}))
:else
`(clout/route-compile (str ~route ":__path-info") ~re-context))))
`(let [route# ~route]
(with-meta
(clout/route-compile (str route# ":__path-info") ~re-context)
(if (string? route#)
{:context-route route#}
{}))))))

(defn ^:no-doc make-context [route make-handler]
(letfn [(handler
Expand Down
30 changes: 26 additions & 4 deletions test/compojure/core_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
(assoc :params {:y "bar"}))]
((GET "/:x" [x :as r]
(is (= x "foo"))
(is (= (dissoc r :params :route-params :compojure/route)
(is (= (dissoc r :params :route-params :compojure/route :compojure/full-route)
(dissoc req :params)))
nil)
req)))
Expand Down Expand Up @@ -212,7 +212,7 @@
(let [handler (GET "/ip/:ip" [ip] ip)
cxt-handler (context "/ip/:ip" [ip] (GET "/" [] ip))
in-cxt-handler (context "/ip" [] (GET "/:ip" [ip] ip))
request (mock/request :get "/ip/0%3A0%3A0%3A0%3A0%3A0%3A0%3A1%250") ]
request (mock/request :get "/ip/0%3A0%3A0%3A0%3A0%3A0%3A0%3A1%250")]
(is (= (-> request handler :body) "0:0:0:0:0:0:0:1%0"))
(is (= (-> request cxt-handler :body) "0:0:0:0:0:0:0:1%0"))
(is (= (-> request in-cxt-handler :body) "0:0:0:0:0:0:0:1%0"))))
Expand All @@ -221,7 +221,7 @@
(let [handler (GET "/emote/:emote" [emote] emote)
cxt-handler (context "/emote/:emote" [emote] (GET "/" [] emote))
in-cxt-handler (context "/emote" [] (GET "/:emote" [emote] emote))
request (mock/request :get "/emote/%5C%3F%2F") ]
request (mock/request :get "/emote/%5C%3F%2F")]
(is (= (-> request handler :body) "\\?/"))
(is (= (-> request cxt-handler :body) "\\?/"))
(is (= (-> request in-cxt-handler :body) "\\?/"))))
Expand Down Expand Up @@ -323,7 +323,29 @@
request (route (mock/request :post "/foo/1" {}))]
(testing "ANY request has matched route information"
(is (= (request :compojure/route)
[:any "/foo/:id"])))))
[:any "/foo/:id"]))
(is (= (request :compojure/full-route)
"/foo/:id"))))

(let [route (context "/foo/:foo-id" [_] (GET "/bar/:bar-id" req req))
request (route (mock/request :get "/foo/1/bar/2"))]
(testing "request has matched route information with path prefix"
(is (= (request :compojure/route)
[:get "/bar/:bar-id"]))
(is (= (request :compojure/context)
"/foo/:foo-id"))
(is (= (request :compojure/full-route)
"/foo/:foo-id/bar/:bar-id"))))

(let [route (context "/foo/:foo-id" [_]
(context "/bar/:bar-id" [_]
(GET "/baz/:baz-id" req req)))
request (route (mock/request :get "/foo/1/bar/2/baz/3"))]
(testing "request has matched route information with multiple path prefix"
(is (= (request :compojure/context)
"/foo/:foo-id/bar/:bar-id"))
(is (= (request :compojure/full-route)
"/foo/:foo-id/bar/:bar-id/baz/:baz-id")))))

(deftest route-async-test
(testing "single route"
Expand Down

0 comments on commit 9e1744a

Please sign in to comment.