-
Notifications
You must be signed in to change notification settings - Fork 3
/
query_params.clj
62 lines (55 loc) · 2.3 KB
/
query_params.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
(ns clojure-commons.query-params
(:require [clj-http.util :as http-util]
[clojure.string :as string]))
(defn assoc-param
"Taken from ring.middleware.params. Needed because we need to write
a function that uses hidden functions.
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
"Taken from ring.middleware.params. Needed because we need to write a function that uses hidden
functions. We are using clj-http.util/url-decode since ring.util.codec/url-decode does not
properly decode '+' characters into spaces.
Parse parame+ters 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
(http-util/url-decode key encoding)
(http-util/url-decode (or val "") encoding))
param-map))
{}
(string/split param-string #"&")))
(defn assoc-query-params
"Taken from ring.middleware.params. Needed because we need to write
a function that uses hidden functions.
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)]
{:query-params params, :params params})
{:query-params {}, :params {}})))
(defn wrap-query-params
"Middleware to parse parameters from the query string (if it exists). It
does not touch the form body. Adds the following key to the request map.
:query-params - a map of parameters from the query string
Takes an optional configuration map. Recognized keys are:
:encoding - encoding to use for url-decoding."
[handler & [opts]]
(fn [request]
(let [encoding (or (:encoding opts)
(:character-encoding request)
"UTF-8")
request (if (:query-params request)
request
(assoc-query-params request encoding))]
(handler request))))