-
Notifications
You must be signed in to change notification settings - Fork 0
/
ring.clj
131 lines (102 loc) · 2.51 KB
/
ring.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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
;; https://github.com/ring-clojure/ring/blob/master/SPEC
(ns lambda.ring
(:require
[lambda.log :as log]
[lambda.codec :as codec]
[lambda.error :refer [error!]]
[clojure.java.io :as io]
[clojure.string :as str]))
(defn process-headers
[headers]
(persistent!
(reduce-kv
(fn [acc! k v]
(let [h (-> k name str/lower-case)]
(assoc! acc! h v)))
(transient {})
headers)))
(defn ->ring [event]
(let [{:keys [headers
isBase64Encoded
rawQueryString
queryStringParameters
requestContext
body]}
event
{:keys [http
requestId]}
requestContext
{:keys [method
path
protocol
sourceIp
userAgent]}
http
stream
(when body
(if isBase64Encoded
(-> body
codec/str->bytes
codec/b64-decode
io/input-stream)
(-> body
codec/str->bytes
io/input-stream)))
request-method
(some-> method str/lower-case keyword)
norm-headers
(process-headers headers)
request
{:remote-addr sourceIp
:uri path
:query-params queryStringParameters
:query-string rawQueryString
:request-method request-method
:protocol protocol
:user-agent userAgent
:headers norm-headers
:body stream}]
(with-meta request {:event event})))
(defprotocol IBody
(->body [this]))
(extend-protocol IBody
Object
(->body [this]
(error! "Cannot coerce %s to response body" this))
String
(->body [this]
[false this])
clojure.lang.ISeq
(->body [this]
(->body (with-out-str
(doseq [line this]
(print line)))))
java.io.File
(->body [this]
(->body (io/input-stream this)))
java.io.InputStream
(->body [this]
(let [array
(-> this
.readAllBytes)]
[true
(-> array
codec/b64-encode
codec/bytes->str)])))
(defn ring-> [response]
(let [{:keys [status
headers
body]}
response
[b64-encoded? string]
(->body body)]
{:statusCode status
:headers headers
:isBase64Encoded b64-encoded?
:body string}))
(defn wrap-ring-event [handler]
(fn [event]
(-> event
(->ring)
(handler)
(ring->))))