-
Notifications
You must be signed in to change notification settings - Fork 12
/
absolute_redirects.clj
49 lines (42 loc) · 1.69 KB
/
absolute_redirects.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
(ns ring.middleware.absolute-redirects
"Middleware for replacing relative redirects with absolute redirects. Useful
for clients that do not yet implement RFC 7231 (RFC 2616 does not allow
relative redirects)."
(:require [ring.util.request :as req])
(:import [java.net URL MalformedURLException]))
(defn- redirect? [response]
(#{201 301 302 303 307} (:status response)))
(defn- get-header-key [response ^String header-name]
(->> response :headers keys
(filter #(.equalsIgnoreCase header-name %))
first))
(defn- update-header [response header f & args]
(if-let [header (get-header-key response header)]
(apply update-in response [:headers header] f args)
response))
(defn- url? [^String s]
(try (URL. s) true
(catch MalformedURLException _ false)))
(defn- absolute-url [location request]
(if (url? location)
location
(let [url (URL. (req/request-url request))]
(str (URL. url location)))))
(defn absolute-redirects-response
"Convert a response that redirects to a relative URLs into a response that
redirects to an absolute URL. See: wrap-absolute-redirects."
[response request]
(if (redirect? response)
(update-header response "location" absolute-url request)
response))
(defn wrap-absolute-redirects
"Middleware that converts redirects to relative URLs into redirects to
absolute URLs. While many browsers can handle relative URLs in the Location
header, RFC 2616 states that the Location header must contain an absolute
URL."
[handler]
(fn
([request]
(absolute-redirects-response (handler request) request))
([request respond raise]
(handler request #(respond (absolute-redirects-response % request)) raise))))