Permalink
Browse files

Fixed wrap-cookies with form-decode-str function

Cookies still need to be www-form-urlencoded using the URLEncoder
and URLDecoder classes to maintain backward compatibility.
1 parent a7a883c commit 5b81dceaef808028ded2db8478f08805fad1f367 @weavejester weavejester committed Mar 24, 2012
View
4 ring-core/src/ring/middleware/cookies.clj
@@ -50,7 +50,7 @@
[cookies] [cookies]
(remove nil? (remove nil?
(for [[name value] cookies] (for [[name value] cookies]
- (if-let [value (codec/url-decode value)] + (if-let [value (codec/form-decode-str value)]
(if (.startsWith ^String value "\"") (if (.startsWith ^String value "\"")
[name (read-string value)] [name (read-string value)]
[name value]))))) [name value])))))
@@ -88,7 +88,7 @@
(defn- write-value (defn- write-value
"Write the main cookie value." "Write the main cookie value."
[key value] [key value]
- (str (name key) "=" (codec/url-encode value))) + (codec/form-encode {key value}))
(defn- valid-attr? (defn- valid-attr?
"Is the attribute valid?" "Is the attribute valid?"
View
8 ring-core/src/ring/middleware/params.clj
@@ -2,12 +2,16 @@
"Parse form and query params." "Parse form and query params."
(:require [ring.util.codec :as codec])) (:require [ring.util.codec :as codec]))
+(defn- parse-params [params encoding]
+ (let [params (codec/form-decode params encoding)]
+ (if (map? params) params {})))
+
(defn- assoc-query-params (defn- assoc-query-params
"Parse and assoc parameters from the query string with the request." "Parse and assoc parameters from the query string with the request."
[request encoding] [request encoding]
(merge-with merge request (merge-with merge request
(if-let [query-string (:query-string request)] (if-let [query-string (:query-string request)]
- (let [params (codec/form-decode query-string encoding)] + (let [params (parse-params query-string encoding)]
{:query-params params, :params params}) {:query-params params, :params params})
{:query-params {}, :params {}}))) {:query-params {}, :params {}})))
@@ -22,7 +26,7 @@
[request encoding] [request encoding]
(merge-with merge request (merge-with merge request
(if-let [body (and (urlencoded-form? request) (:body request))] (if-let [body (and (urlencoded-form? request) (:body request))]
- (let [params (codec/form-decode (slurp body :encoding encoding) encoding)] + (let [params (parse-params (slurp body :encoding encoding) encoding)]
{:form-params params, :params params}) {:form-params params, :params params})
{:form-params {}, :params {}}))) {:form-params {}, :params {}})))
View
45 ring-core/src/ring/util/codec.clj
@@ -63,20 +63,13 @@
(defprotocol FormEncodeable (defprotocol FormEncodeable
(form-encode* [x encoding])) (form-encode* [x encoding]))
-(defn form-encode
- "Encode the supplied value into www-form-urlencoded format, often used in
- URL query strings and POST request bodies, using the specified encoding.
- If the encoding is not specified, it defaults to UTF-8"
- [x & [encoding]]
- (form-encode* x (or encoding "UTF-8")))
-
(extend-protocol FormEncodeable (extend-protocol FormEncodeable
String String
(form-encode* [unencoded encoding] (form-encode* [unencoded encoding]
(URLEncoder/encode unencoded encoding)) (URLEncoder/encode unencoded encoding))
Map Map
(form-encode* [params encoding] (form-encode* [params encoding]
- (letfn [(encode [x] (form-encode x encoding)) + (letfn [(encode [x] (form-encode* x encoding))
(encode-param [[k v]] (str (encode (name k)) "=" (encode v)))] (encode-param [[k v]] (str (encode (name k)) "=" (encode v)))]
(->> params (->> params
(mapcat (mapcat
@@ -89,18 +82,32 @@
(form-encode* [x encoding] (form-encode* [x encoding]
(form-encode* (str x) encoding))) (form-encode* (str x) encoding)))
+(defn form-encode
+ "Encode the supplied value into www-form-urlencoded format, often used in
+ URL query strings and POST request bodies, using the specified encoding.
+ If the encoding is not specified, it defaults to UTF-8"
+ [x & [encoding]]
+ (form-encode* x (or encoding "UTF-8")))
+
+(defn form-decode-str
+ "Decode the supplied www-form-urlencoded string using the specified encoding,
+ or UTF-8 by default."
+ [^String encoded & [encoding]]
+ (try
+ (URLDecoder/decode encoded (or encoding "UTF-8"))
+ (catch Exception _ nil)))
+
(defn form-decode (defn form-decode
"Decode the supplied www-form-urlencoded string using the specified encoding, "Decode the supplied www-form-urlencoded string using the specified encoding,
or UTF-8 by default. If the encoded value is a string, a string is returned. or UTF-8 by default. If the encoded value is a string, a string is returned.
If the encoded value is a map of parameters, a map is returned." If the encoded value is a map of parameters, a map is returned."
- [^String encoded & [encoding]] + [encoded & [encoding]]
- (letfn [(decode [s] (URLDecoder/decode s (or encoding "UTF-8")))] + (if-not (.contains encoded "=")
- (if-not (.contains encoded "=") + (form-decode-str encoded encoding)
- (decode encoded) + (reduce
- (reduce + (fn [m param]
- (fn [m param] + (if-let [[k v] (str/split param #"=" 2)]
- (if-let [[k v] (str/split param #"=" 2)] + (assoc+ m (form-decode-str k encoding) (form-decode-str v encoding))
- (assoc+ m (decode k) (decode v)) + m))
- m)) + {}
- {} + (str/split encoded #"&"))))
- (str/split encoded #"&")))))
View
4 ring-core/test/ring/util/test/codec.clj
@@ -44,6 +44,10 @@
{"a" "b c"} "a=b+c") {"a" "b c"} "a=b+c")
(is (= (form-encode {"a" "foo/bar"} "UTF-16") "a=foo%FE%FF%00%2Fbar")))) (is (= (form-encode {"a" "foo/bar"} "UTF-16") "a=foo%FE%FF%00%2Fbar"))))
+(deftest test-form-decode-str
+ (is (= (form-decode-str "foo=bar+baz") "foo=bar baz"))
+ (is (nil? (form-decode-str "%D"))))
+
(deftest test-form-decode (deftest test-form-decode
(are [x y] (= (form-decode x) y) (are [x y] (= (form-decode x) y)
"foo" "foo" "foo" "foo"

0 comments on commit 5b81dce

Please sign in to comment.