Skip to content

Commit bb0ef86

Browse files
committed
Add middleware for x-forwarded-proto header
1 parent 19baf42 commit bb0ef86

2 files changed

Lines changed: 41 additions & 0 deletions

File tree

src/ring/middleware/proxy_headers.clj

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,25 @@
2020
(handler (forwarded-remote-addr-request request)))
2121
([request respond raise]
2222
(handler (forwarded-remote-addr-request request) respond raise))))
23+
24+
(def ^:private valid-scheme? #{"http" "https" "ws" "wss"})
25+
26+
(defn forwarded-scheme-request
27+
"Change the :scheme key of the request map to the last value present in the
28+
X-Forwarded-Proto header. See: wrap-forwarded-scheme."
29+
[request]
30+
(let [forwarded-proto (get-in request [:headers "x-forwarded-proto"])
31+
scheme (some-> forwarded-proto str/lower-case str/trim)]
32+
(if (and scheme (valid-scheme? forwarded-proto))
33+
(assoc request :scheme (keyword scheme))
34+
request)))
35+
36+
(defn wrap-forwarded-scheme
37+
"Middleware that changes the :scheme of the request map to the last value
38+
present in the X-Forwarded-Proto header."
39+
[handler]
40+
(fn
41+
([request]
42+
(handler (forwarded-scheme-request request)))
43+
([request respond raise]
44+
(handler (forwarded-scheme-request request) respond raise))))

test/ring/middleware/proxy_headers_test.clj

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,22 @@
4545
(handler req resp ex)
4646
(is (not (realized? ex)))
4747
(is (= (:body @resp) "1.2.3.4"))))))
48+
49+
(deftest test-wrap-forwarded-proto
50+
(let [handler (wrap-forwarded-scheme (comp response :scheme))]
51+
(testing "without x-forwarded-proto"
52+
(let [req (request :get "/")
53+
resp (handler req)]
54+
(is (= (:body resp) :http))))
55+
56+
(testing "with x-forwarded-proto"
57+
(let [req (-> (request :get "/")
58+
(header "x-forwarded-proto" "https"))
59+
resp (handler req)]
60+
(is (= (:body resp) :https))))
61+
62+
(testing "unknown schemes are ignored"
63+
(let [req (-> (request :get "/")
64+
(header "x-forwarded-proto" "ftp"))
65+
resp (handler req)]
66+
(is (= (:body resp) :http))))))

0 commit comments

Comments
 (0)