-
Notifications
You must be signed in to change notification settings - Fork 259
/
request.clj
109 lines (95 loc) · 3.35 KB
/
request.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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
;; Copyright (c) James Reeves. All rights reserved.
;; The use and distribution terms for this software are covered by the Eclipse
;; Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) which
;; can be found in the file epl-v10.html at the root of this distribution. By
;; using this software in any fashion, you are agreeing to be bound by the
;; terms of this license. You must not remove this notice, or any other, from
;; this software.
(ns compojure.http.request
"Functions for pulling useful data out of a HTTP request map."
(:use compojure.control
compojure.encodings
compojure.map-utils
compojure.str-utils
clojure.contrib.duck-streams
clojure.contrib.str-utils)
(:import java.net.URLDecoder
java.io.InputStreamReader))
(defn- parse-params
"Parse parameters from a string into a map."
[param-string separator]
(reduce
(fn [param-map s]
(if-let [[_ key val] (re-matches #"([^=]+)=(.*)" s)]
(assoc-vec param-map
(keyword (urldecode key))
(urldecode (or val "")))
param-map))
{}
(remove blank?
(re-split separator param-string))))
(defn parse-query-params
"Parse parameters from the query string."
[request]
(if-let [query (request :query-string)]
(parse-params query #"&")))
(defn get-character-encoding
"Get the character encoding, or use the default from duck-streams."
[request]
(or (request :character-encoding) *default-encoding*))
(defn- slurp-body
"Slurp the request body into a string."
[request]
(let [encoding (get-character-encoding request)]
(if-let [body (request :body)]
(slurp* (InputStreamReader. body encoding)))))
(defn urlencoded-form?
"Does a request have a urlencoded form?"
[request]
(if-let [type (:content-type request)]
(.startsWith type "application/x-www-form-urlencoded")))
(defn parse-form-params
"Parse urlencoded form parameters from the request body."
[request]
(if (urlencoded-form? request)
(if-let [body (slurp-body request)]
(parse-params body #"&"))))
(defn- get-merged-params
"Get a map of all the parameters merged together."
[request]
(merge (:query-params request)
(:form-params request)
(:params request)))
(defn- assoc-func
"Associate the result of a (func request) with a key on the request map."
[request key func]
(if (contains? request key)
request
(assoc request key (or (func request) {}))))
(defn assoc-params
"Associate urlencoded parameters with a request. The following keys are added
to the request map: :query-params, :form-params and :params."
[request]
(-> request
(assoc-func :query-params parse-query-params)
(assoc-func :form-params parse-form-params)
(assoc-func :params get-merged-params)))
(defn with-request-params
"Decorator that adds urlencoded parameters to the request map."
[handler]
(fn [request]
(handler (assoc-params request))))
(defn parse-cookies
"Pull out a map of cookies from a request map."
[request]
(if-let [cookies (get-in request [:headers "cookie"])]
(parse-params cookies #";\s*")))
(defn assoc-cookies
"Associate cookies with a request map."
[request]
(assoc-func request :cookies parse-cookies))
(defn with-cookies
"Decorator that adds cookies to a request map."
[handler]
(fn [request]
(handler (assoc-cookies request))))