/
request.clj
98 lines (87 loc) · 3.21 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
(ns ring.mock.request
"Functions to create mock request maps."
(:require [clojure.string :as string])
(:import java.util.Map
java.io.ByteArrayInputStream
[java.net URI URLEncoder]))
(defn- encode-params
"Turn a map of parameters into a urlencoded string."
[params]
(string/join "&"
(for [[k v] params]
(str (URLEncoder/encode (name k)) "="
(URLEncoder/encode (str v))))))
(defn- append-query
"Create a query string from a URI and a map of parameters."
[uri params]
(let [query (.getRawQuery uri)]
(if (or query params)
(string/join "&"
(remove string/blank?
[query (encode-params params)])))))
(defn header
"Add a HTTP header to the request map."
[request header value]
(let [header (string/lower-case (name header))]
(assoc-in request [:headers header] (str value))))
(defn content-type
"Set the content type of the request map."
[request mime-type]
(-> request
(assoc :content-type mime-type)
(header :content-type mime-type)))
(defn content-length
"Set the content length of the request map."
[request length]
(-> request
(assoc :content-length length)
(header :content-length length)))
(defn query-string
"Add a map of parameters to the query string of the request."
[request params]
(assoc request :query-string (encode-params params)))
(defmulti body
"Set the body of the request. The supplied body value can be a string or
a map of parameters to be url-encoded."
{:arglists '([request body-value])}
(fn [request x] (type x)))
(defmethod body String [request string]
(body request (.getBytes string)))
(defmethod body (class (byte-array 0)) [request bytes]
(-> request
(content-length (count bytes))
(assoc :body (ByteArrayInputStream. bytes))))
(defmethod body Map [request params]
(-> request
(content-type "application/x-www-form-urlencoded")
(body (encode-params params))))
(defn request
"Create a minimal valid request map from a HTTP method keyword, a string
containing a URI, and an optional map of parameters that will be added to
the query string of the URI. The URI can be relative or absolute. Relative
URIs are assumed to go to http://localhost."
([method uri]
(request method uri nil))
([method uri params]
(let [uri (URI. uri)
host (or (.getHost uri) "localhost")
port (if (not= (.getPort uri) -1) (.getPort uri))
scheme (.getScheme uri)
path (.getRawPath uri)
query (.getRawQuery uri)
req {:server-port (or port 80)
:server-name host
:remote-addr "localhost"
:uri (if (string/blank? path) "/" path)
:query-string query
:scheme (or (keyword scheme) :http)
:request-method method
:headers {"host" (if port
(str host ":" port)
host)}}]
(if params
(case method
:get (assoc req :query-string (append-query uri params))
:post (body req params)
req)
req))))