From 58e5860c43a13273ed3c5b1833cddad9d4a3010e Mon Sep 17 00:00:00 2001 From: Giacomo Ritucci Date: Wed, 11 Jan 2012 00:45:05 +0100 Subject: [PATCH 1/4] move parse-params to ring.util.codec, renamed as form-decode --- ring-core/src/ring/middleware/multipart_params.clj | 2 +- ring-core/src/ring/middleware/params.clj | 31 +++------------------- ring-core/src/ring/util/codec.clj | 27 ++++++++++++++++++- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/ring-core/src/ring/middleware/multipart_params.clj b/ring-core/src/ring/middleware/multipart_params.clj index 828852f..257347c 100644 --- a/ring-core/src/ring/middleware/multipart_params.clj +++ b/ring-core/src/ring/middleware/multipart_params.clj @@ -1,6 +1,6 @@ (ns ring.middleware.multipart-params "Parse multipart upload into params." - (:use [ring.middleware.params :only (assoc-param)]) + (:use [ring.util.codec :only (assoc-param)]) (:import [org.apache.commons.fileupload.util Streams] [org.apache.commons.fileupload RequestContext diff --git a/ring-core/src/ring/middleware/params.clj b/ring-core/src/ring/middleware/params.clj index be3f98f..60b79f7 100644 --- a/ring-core/src/ring/middleware/params.clj +++ b/ring-core/src/ring/middleware/params.clj @@ -1,38 +1,13 @@ (ns ring.middleware.params "Parse form and query params." - (:require [ring.util.codec :as codec] - [clojure.string :as string])) - -(defn assoc-param - "Associate a key with a value. If the key already exists in the map, - create a vector of values." - [map key val] - (assoc map key - (if-let [cur (map key)] - (if (vector? cur) - (conj cur val) - [cur val]) - val))) - -(defn- parse-params - "Parse parameters from a string into a map." - [^String param-string encoding] - (reduce - (fn [param-map encoded-param] - (if-let [[_ key val] (re-matches #"([^=]+)=(.*)" encoded-param)] - (assoc-param param-map - (codec/url-decode key encoding) - (codec/url-decode (or val "") encoding)) - param-map)) - {} - (string/split param-string #"&"))) + (:require [ring.util.codec :as codec])) (defn- assoc-query-params "Parse and assoc parameters from the query string with the request." [request encoding] (merge-with merge request (if-let [query-string (:query-string request)] - (let [params (parse-params query-string encoding)] + (let [params (codec/form-decode query-string encoding)] {:query-params params, :params params}) {:query-params {}, :params {}}))) @@ -47,7 +22,7 @@ [request encoding] (merge-with merge request (if-let [body (and (urlencoded-form? request) (:body request))] - (let [params (parse-params (slurp body :encoding encoding) encoding)] + (let [params (codec/form-decode (slurp body :encoding encoding) encoding)] {:form-params params, :params params}) {:form-params {}, :params {}}))) diff --git a/ring-core/src/ring/util/codec.clj b/ring-core/src/ring/util/codec.clj index 8cdd568..9f257fe 100644 --- a/ring-core/src/ring/util/codec.clj +++ b/ring-core/src/ring/util/codec.clj @@ -2,7 +2,8 @@ "Encoding and decoding utilities." (:import java.io.File (java.net URLEncoder URLDecoder) - org.apache.commons.codec.binary.Base64)) + org.apache.commons.codec.binary.Base64) + (:require [clojure.string :as string])) (defn url-encode "Returns the form-url-encoded version of the given string, using either a @@ -27,3 +28,27 @@ "Decode a base64 encoded string into an array of bytes." [^String encoded] (Base64/decodeBase64 (.getBytes encoded))) + +(defn assoc-param + "Associate a key with a value. If the key already exists in the map, + create a vector of values." + [map key val] + (assoc map key + (if-let [cur (map key)] + (if (vector? cur) + (conj cur val) + [cur val]) + val))) + +(defn form-decode + "Parse parameters from a string into a map." + [^String param-string encoding] + (reduce + (fn [param-map encoded-param] + (if-let [[_ key val] (re-matches #"([^=]+)=(.*)" encoded-param)] + (assoc-param param-map + (url-decode key encoding) + (url-decode (or val "") encoding)) + param-map)) + {} + (string/split param-string #"&"))) From 638c1e3dc9bcb192881ccfdeb4a3f1794ba333c1 Mon Sep 17 00:00:00 2001 From: Giacomo Ritucci Date: Sun, 15 Jan 2012 01:48:03 +0100 Subject: [PATCH 2/4] form-encode implemented --- ring-core/src/ring/util/codec.clj | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/ring-core/src/ring/util/codec.clj b/ring-core/src/ring/util/codec.clj index 9f257fe..08668f6 100644 --- a/ring-core/src/ring/util/codec.clj +++ b/ring-core/src/ring/util/codec.clj @@ -52,3 +52,23 @@ param-map)) {} (string/split param-string #"&"))) + +(defn form-encode + "Encode parameters from a map into a string." + ([param-map] + (form-encode param-map "UTF-8")) + ([param-map encoding] + (form-encode (keys param-map) + (vals param-map) + encoding)) + ([params values encoding] + (string/join #"&" + (map (fn [param value] + (if (vector? value) + (form-encode (repeat (count value) param) + value + encoding) + (str (url-encode param) + "=" + (url-encode value)))) + params values)))) From e2d030da554e7db68128b73deedc79c38bd5275f Mon Sep 17 00:00:00 2001 From: Giacomo Ritucci Date: Sun, 15 Jan 2012 01:48:28 +0100 Subject: [PATCH 3/4] form-decode: encoding defaults to "UTF-8" --- ring-core/src/ring/util/codec.clj | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/ring-core/src/ring/util/codec.clj b/ring-core/src/ring/util/codec.clj index 08668f6..c2f29be 100644 --- a/ring-core/src/ring/util/codec.clj +++ b/ring-core/src/ring/util/codec.clj @@ -42,16 +42,18 @@ (defn form-decode "Parse parameters from a string into a map." - [^String param-string encoding] - (reduce - (fn [param-map encoded-param] - (if-let [[_ key val] (re-matches #"([^=]+)=(.*)" encoded-param)] - (assoc-param param-map - (url-decode key encoding) - (url-decode (or val "") encoding)) - param-map)) - {} - (string/split param-string #"&"))) + ([^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 param-map + (url-decode key encoding) + (url-decode (or val "") encoding)) + param-map)) + {} + (string/split param-string #"&")))) (defn form-encode "Encode parameters from a map into a string." From 4bd7933babad86d7f00530858e9e3287c6305320 Mon Sep 17 00:00:00 2001 From: Giacomo Ritucci Date: Sun, 15 Jan 2012 02:39:59 +0100 Subject: [PATCH 4/4] test for form-encode and form-decode --- ring-core/test/ring/util/test/codec.clj | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ring-core/test/ring/util/test/codec.clj b/ring-core/test/ring/util/test/codec.clj index d05d219..f99b051 100644 --- a/ring-core/test/ring/util/test/codec.clj +++ b/ring-core/test/ring/util/test/codec.clj @@ -17,3 +17,11 @@ (deftest test-base64-encoding (let [str-bytes (.getBytes "foo?/+" "UTF-8")] (is (Arrays/equals str-bytes (base64-decode (base64-encode str-bytes)))))) + +(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)))))