Permalink
Browse files

Merge pull request #49 from rjack/parse-params-exposed

Refactor parameter parsing
  • Loading branch information...
2 parents d094e7d + 4bd7933 commit 84446f63afe1ddf35b9f959b1baf49cd5c0012b7 @weavejester weavejester committed Mar 22, 2012
@@ -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
@@ -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 {}})))
@@ -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,49 @@
"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]
+ (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."
+ ([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))))
@@ -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)))))

0 comments on commit 84446f6

Please sign in to comment.