-
Notifications
You must be signed in to change notification settings - Fork 32
/
websocket.clj
76 lines (67 loc) · 2.52 KB
/
websocket.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
(ns puppetlabs.pcp.broker.websocket
(:require [clojure.tools.logging :as log]
[puppetlabs.trapperkeeper.services.websocket-session :as websocket-session]
[puppetlabs.kitchensink.core :as ks]
[puppetlabs.pcp.client :as pcp-client])
(:import (puppetlabs.pcp.client Client)
(java.net InetSocketAddress InetAddress)
(org.eclipse.jetty.websocket.api WebSocketAdapter)))
(def Websocket
"Schema for a websocket session"
Object)
(extend-protocol websocket-session/WebSocketProtocol
Client
(send! [c msg] (pcp-client/send! c msg))
(close! [c code msg] (pcp-client/close c))
(remote-addr [c] (-> c :websocket-client (.getOpenSessions) first (.getRemoteAddress)))
(ssl? [c] true)
(peer-certs [c] nil)
(request-path [c] "/server")
(idle-timeout! [c timeout] nil)
(connected? [c] (pcp-client/connected? c)))
(defprotocol WebsocketInterface
"Operations on an underlying Websocket connection"
(ws->common-name [ws]
"Returns the common name of an endpoint using SSL"))
(extend-protocol WebsocketInterface
WebSocketAdapter
(ws->common-name [ws]
(try
(when-let [cert (first (websocket-session/peer-certs ws))]
(puppetlabs.ssl-utils.core/get-cn-from-x509-certificate cert))
(catch Exception _
nil)))
Client
(ws->common-name [c]
(let [uri (-> c :websocket-client (.getOpenSessions) first (.getUpgradeRequest) (.getRequestURI))]
(.getAuthority uri))))
(defn ws->remote-address
"Get the IP address (or hostname if the IP address is not resolved) and port
out of the InetSocketAddress object."
[ws]
(try
(if-let [^InetSocketAddress socket-address (websocket-session/remote-addr ws)]
(let [^InetAddress inet-address (.getAddress socket-address)]
(str (if (nil? inet-address)
(.getHostName socket-address)
(.getHostAddress inet-address))
\:
(.getPort socket-address)))
"")
(catch Exception e
(log/trace e "Failure trying to get remote address")
"")))
(defn ws->client-path
[ws]
(let [path (websocket-session/request-path ws)]
(if (or (empty? path) (= "/" path))
"/agent"
path)))
(defn ws->client-type
[ws]
(subs (ws->client-path ws) 1))
(defn ws->uri
"Construct a URI based on properties of the websocket session. Defaults to
`agent` client type if none can be discerned."
[ws]
(str "pcp://" (ws->common-name ws) (ws->client-path ws)))