Skip to content

Commit 96edd85

Browse files
committed
Add websocket-keepalive middleware
1 parent a4f3670 commit 96edd85

File tree

4 files changed

+40
-6
lines changed

4 files changed

+40
-6
lines changed

README.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ The following configuration keys are supported:
152152

153153
- `:store` - The Ring session store to use for storing sessions.
154154

155-
- `:static`
155+
- `:static` -
156156
A map of options to configure how to find static content.
157157

158158
- `:files` -
@@ -168,6 +168,15 @@ The following configuration keys are supported:
168168
and the rest of the map is passed as options. May also be a
169169
collection of the above.
170170

171+
- `:websocket`
172+
A map of options to configure websocket behavior.
173+
174+
- `:keepalive` -
175+
If true, periodically pings the client to keep the connection
176+
alive via the [websocket keepalive][16] middleware. A map of
177+
options may also be passed to set the `:period` of the keepalive in
178+
milliseconds.
179+
171180

172181
[1]: https://ring-clojure.github.io/ring/ring.middleware.multipart-params.html
173182
[2]: https://ring-clojure.github.io/ring/ring.middleware.nested-params.html
@@ -184,6 +193,7 @@ The following configuration keys are supported:
184193
[13]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection
185194
[14]: https://ring-clojure.github.io/ring/ring.middleware.file.html
186195
[15]: https://ring-clojure.github.io/ring/ring.middleware.resource.html
196+
[16]: https://ring-clojure.github.io/ring-websocket-middleware/ring.websocket.keepalive.html
187197

188198
## License
189199

project.clj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
[ring/ring-core "1.13.0"]
88
[ring/ring-ssl "0.4.0"]
99
[ring/ring-headers "0.4.0"]
10-
[ring/ring-anti-forgery "1.4.0"]]
10+
[ring/ring-anti-forgery "1.4.0"]
11+
[org.ring-clojure/ring-websocket-middleware "0.2.1"]]
1112
:aliases
1213
{"test-all" ["with-profile" "default:+1.10:+1.11:+1.12" "test"]}
1314
:profiles

src/ring/middleware/defaults.clj

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
[ring.middleware.default-charset :refer [wrap-default-charset]]
1818
[ring.middleware.absolute-redirects :refer [wrap-absolute-redirects]]
1919
[ring.middleware.ssl :refer [wrap-ssl-redirect wrap-hsts wrap-forwarded-scheme]]
20-
[ring.middleware.proxy-headers :refer [wrap-forwarded-remote-addr]]))
20+
[ring.middleware.proxy-headers :refer [wrap-forwarded-remote-addr]]
21+
[ring.websocket.keepalive :refer [wrap-websocket-keepalive]]))
2122

2223
(def default-session-store (cookie-store))
2324

@@ -54,7 +55,8 @@
5455
:responses {:not-modified-responses true
5556
:absolute-redirects false
5657
:content-types true
57-
:default-charset "utf-8"}})
58+
:default-charset "utf-8"}
59+
:websocket {:keepalive true}})
5860

5961
(def secure-site-defaults
6062
"A default configuration for a browser-accessible website that's accessed
@@ -103,6 +105,7 @@
103105
secure-site-defaults"
104106
[handler config]
105107
(-> handler
108+
(wrap wrap-websocket-keepalive (get-in config [:websocket :keepalive] false))
106109
(wrap wrap-anti-forgery (get-in config [:security :anti-forgery] false))
107110
(wrap wrap-flash (get-in config [:session :flash] false))
108111
(wrap wrap-session (:session config false))

test/ring/middleware/defaults_test.clj

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
(:require [clojure.test :refer :all]
33
[ring.middleware.defaults :refer :all]
44
[ring.util.response :refer [response content-type not-found]]
5-
[ring.mock.request :refer [request header]]))
5+
[ring.mock.request :refer [request header]]
6+
[ring.websocket :as ws]
7+
[ring.websocket.protocols :as wsp]))
68

79
(deftest test-wrap-defaults
810
(testing "api defaults"
@@ -248,4 +250,22 @@
248250
(wrap-defaults site-defaults))]
249251
(is (= 403 (:status (handler (request :post "/")))))
250252
(is (= 200 (:status (handler (-> (request :post "/")
251-
(header "X-Ring-Anti-Forgery" "1")))))))))
253+
(header "X-Ring-Anti-Forgery" "1"))))))))
254+
255+
(testing "websocket pings"
256+
(let [ping-count (atom 0)
257+
socket (reify wsp/Socket
258+
(-open? [_] true)
259+
(-send [_ _])
260+
(-ping [_ _] (swap! ping-count inc))
261+
(-pong [_ _])
262+
(-close [_ _ _]))
263+
response {::ws/listener {}}
264+
handler (wrap-defaults (constantly response)
265+
{:websocket {:keepalive {:period 10}}})
266+
listener (::ws/listener (handler {}))]
267+
(wsp/on-open listener socket)
268+
(Thread/sleep 41)
269+
(wsp/on-close listener socket 1000 "")
270+
(Thread/sleep 20)
271+
(is (= 4 @ping-count)))))

0 commit comments

Comments
 (0)