Skip to content

Commit

Permalink
Route matching for the Sinatra PUT/DELETE form _method trick used by …
Browse files Browse the repository at this point in the history
…form-to.

Signed-off-by: James Reeves <jreeves@weavejester.com>
  • Loading branch information
lrenn authored and weavejester committed Apr 23, 2009
1 parent 0f77580 commit 1c15ab0
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 4 deletions.
4 changes: 2 additions & 2 deletions src/compojure/html/form_helpers.clj
Original file line number Diff line number Diff line change
Expand Up @@ -125,12 +125,12 @@
e.g. (form-to [:put \"/post\"]
...)"
[[method action] & body]
(let [method-str (. (name method) toUpperCase)]
(let [method-str (upcase-name method)]
(into []
(concat
(if (includes? [:get :post] method)
[:form {:method method-str :action action}]
[:form {:method "POST" :action action}
[:form {:method "POST" :action action}
(hidden-field "_method" method-str)])
body))))

Expand Down
17 changes: 15 additions & 2 deletions src/compojure/http/routes.clj
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,25 @@
(subvec matches 1)
[]))))

(defn match-method
(defn match-route-method
"True if the method from the route matches the method from the request."
[route-method request-method]
(or (nil? route-method)
(= route-method request-method)))

(defn match-form-method
"True if the route-method matches a posted forms _method parameter."
[route-method request]
(and (= (request :request-method) :post)
(= (:_method (get-form-params request))
(upcase-name route-method))))

(defn match-method
"True if this request matches the route-method."
[route-method request]
(or (match-route-method route-method (request :request-method))
(match-form-method route-method request)))

(defn request-url
"Return the complete URL for the request."
[request]
Expand Down Expand Up @@ -158,7 +171,7 @@
`(compile-matcher ~path))]
`(fn [request#]
(and
(match-method ~method (request# :request-method))
(match-method ~method request#)
(match-uri ~matcher (get-matcher-uri ~path request#))))))

;; Functions and macros for generating routing functions. A routing function
Expand Down
5 changes: 5 additions & 0 deletions src/compojure/str_utils.clj
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,8 @@
"Generate a random UUID."
[]
(str (UUID/randomUUID)))

(defn upcase-name
"Upcase a symbol or keyword's name."
[sym]
(. (name sym) toUpperCase))
14 changes: 14 additions & 0 deletions test/compojure/http/routes.clj
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,20 @@
request {:request-method :get, :uri "/foo"}]
(is (nil? (route request)))))

(deftest route-match-form-method
(let [route (DELETE "/foo" "body")
request {:request-method :post,
:uri "/foo",
:content-type "application/x-www-form-urlencoded"
:form-params {:_method "DELETE"}}]
(is (= (:status (route request) 200)))))

(deftest route-not-match-form-method
(let [route (DELETE "/foo" "body")
request {:request-method :post,
:uri "/foo" }]
(is (nil? (route request)))))

(deftest route-keywords
(let [route (GET "/:foo"
(is (= (:route-params request) {:foo "bar"}))
Expand Down

0 comments on commit 1c15ab0

Please sign in to comment.