-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathring_proxy.clj
More file actions
56 lines (52 loc) · 2.24 KB
/
ring_proxy.clj
File metadata and controls
56 lines (52 loc) · 2.24 KB
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
(ns tailrecursion.ring-proxy
(:import
[java.net URI] )
(:require
[clj-http.client :refer [request]]
[clj-http.cookies :refer [wrap-cookies]]
[clojure.string :refer [join split]]
[ring.adapter.jetty :refer [run-jetty]]))
(defn prepare-cookies
"Removes the :domain and :secure keys and converts the :expires key (a Date)
to a string in the ring response map resp. Returns resp with cookies properly
munged."
[resp]
(let [prepare #(-> (update-in % [1 :expires] str)
(update-in [1] dissoc :domain :secure))]
(assoc resp :cookies (into {} (map prepare (:cookies resp))))))
(defn slurp-binary
"Reads len bytes from InputStream is and returns a byte array."
[^java.io.InputStream is len]
(with-open [rdr is]
(let [buf (byte-array len)]
(.read rdr buf)
buf)))
(defn wrap-proxy
"Proxies requests from proxied-path, a local URI, to the remote URI at
remote-base-uri, also a string."
[handler ^String proxied-path remote-base-uri & [http-opts]]
(wrap-cookies
(fn [req]
(if (.startsWith ^String (:uri req) proxied-path)
(let [rmt-full (URI. (str remote-base-uri "/"))
rmt-path (URI. (.getScheme rmt-full)
(.getAuthority rmt-full)
(.getPath rmt-full) nil nil)
lcl-path (URI. (subs (:uri req) (.length proxied-path)))
remote-uri (.resolve rmt-path lcl-path) ]
(-> (merge {:method (:request-method req)
:url (str remote-uri "?" (:query-string req))
:headers (dissoc (:headers req) "host" "content-length")
:body (if-let [len (get-in req [:headers "content-length"])]
(slurp-binary (:body req) (Integer/parseInt len)))
:follow-redirects true
:throw-exceptions false
:as :stream} http-opts)
request
prepare-cookies))
(handler req)))))
(defn run-proxy
[listen-path listen-port remote-uri http-opts]
(-> (constantly {:status 404 :headers {} :body "404 - not found"})
(wrap-proxy listen-path remote-uri http-opts)
(run-jetty {:port listen-port}) ))