From a7a883cc16a9390f5f79d62e2c0e3b1b83f25efd Mon Sep 17 00:00:00 2001 From: James Reeves Date: Sat, 24 Mar 2012 11:59:18 +0000 Subject: [PATCH] form-decode decodes into strings or maps --- ring-core/src/ring/util/codec.clj | 27 ++++++++++++++------------- ring-core/test/ring/util/test/codec.clj | 17 ++++++++++------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/ring-core/src/ring/util/codec.clj b/ring-core/src/ring/util/codec.clj index ace7bb9..cb65281 100644 --- a/ring-core/src/ring/util/codec.clj +++ b/ring-core/src/ring/util/codec.clj @@ -90,16 +90,17 @@ (form-encode* (str x) encoding))) (defn form-decode - "Parse parameters from a string into a map." - ([^String param-string] - (form-decode param-string "UTF-8")) - ([^String param-string encoding] - (reduce - (fn [param-map encoded-param] - (if-let [[_ key val] (re-matches #"([^=]+)=(.*)" encoded-param)] - (assoc+ param-map - (url-decode key encoding) - (url-decode (or val "") encoding)) - param-map)) - {} - (str/split param-string #"&")))) + "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. + If the encoded value is a map of parameters, a map is returned." + [^String encoded & [encoding]] + (letfn [(decode [s] (URLDecoder/decode s (or encoding "UTF-8")))] + (if-not (.contains encoded "=") + (decode encoded) + (reduce + (fn [m param] + (if-let [[k v] (str/split param #"=" 2)] + (assoc+ m (decode k) (decode v)) + m)) + {} + (str/split encoded #"&"))))) diff --git a/ring-core/test/ring/util/test/codec.clj b/ring-core/test/ring/util/test/codec.clj index c8ef0ac..7fd0c40 100644 --- a/ring-core/test/ring/util/test/codec.clj +++ b/ring-core/test/ring/util/test/codec.clj @@ -44,10 +44,13 @@ {"a" "b c"} "a=b+c") (is (= (form-encode {"a" "foo/bar"} "UTF-16") "a=foo%FE%FF%00%2Fbar")))) -(deftest form-encoding - (let [encoded-params "p%2F1=v%2F1&p%2F2=v%2F21&p%2F2=v%2F22"] - (is (= (form-decode encoded-params) - (-> encoded-params - form-decode - form-encode - form-decode))))) +(deftest test-form-decode + (are [x y] (= (form-decode x) y) + "foo" "foo" + "a=b" {"a" "b"} + "a=b&c=d" {"a" "b" "c" "d"} + "foo+bar" "foo bar" + "a=b+c" {"a" "b c"} + "a=b%2Fc" {"a" "b/c"}) + (is (= (form-decode "a=foo%FE%FF%00%2Fbar" "UTF-16") + {"a" "foo/bar"})))