-
Notifications
You must be signed in to change notification settings - Fork 338
/
sni_client.clj
71 lines (58 loc) · 2.45 KB
/
sni_client.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
(ns org.httpkit.sni-client
"Provides an SNI-capable SSL configurer and client, Ref. #335.
In a separate namespace from `org.httpkit.client` so that
http-kit can retain backwards-compatibility with JVM < 8."
(:require [org.httpkit.client])
(:import
[java.net URI]
[javax.net.ssl SNIHostName SSLEngine SSLParameters]))
(defn- parse-java-version
"Ref. https://stackoverflow.com/a/2591122"
[^String s]
(let [dot-idx (.indexOf s ".") ; e.g. "1.6.0_23"
dash-idx (.indexOf s "-")] ; e.g. "16-ea"
(cond
(.startsWith s "1.") ; e.g. "1.6.0_23"
(Integer/parseInt (.substring s 2 3))
(pos? dot-idx)
(Integer/parseInt (.substring s 0 dot-idx))
(pos? dash-idx)
(Integer/parseInt (.substring s 0 dash-idx))
:else
(Integer/parseInt s))))
(comment
(parse-java-version "1.6.0_23") ; 6
(parse-java-version "1.8.0_302") ; 8
(parse-java-version "9.0.1") ; 9
(parse-java-version "11.0.12") ; 11
(parse-java-version "16-ea") ; 16
(parse-java-version "17") ; 17
)
(def ^:private java-version_
(delay (parse-java-version (str (System/getProperty "java.version")))))
(comment @java-version_)
(defn ssl-configurer
"SNI-capable SSL configurer.
May be used as an argument to `org.httpkit.client/make-client`:
(make-client :ssl-configurer (ssl-configurer))"
([ssl-engine uri] (ssl-configurer {} ssl-engine uri))
([{:keys [hostname-verification? sni?] :as opts
:or {;; TODO Better option/s than hacky version check?
hostname-verification? (>= @java-version_ 11)
sni? true}}
^SSLEngine ssl-engine ^URI uri]
(let [^SSLParameters ssl-params (.getSSLParameters ssl-engine)]
(when hostname-verification? (.setEndpointIdentificationAlgorithm ssl-params "HTTPS"))
(when sni? (.setServerNames ssl-params
[(SNIHostName. (.getHost uri))]))
;; TODO Better option/s than hacky version check?
(when (and (>= @java-version_ 11) (not (.getUseClientMode ssl-engine)))
(.setUseClientMode ssl-engine true))
(doto ssl-engine
(.setSSLParameters ssl-params)))))
(defonce
^{:doc "Like `org.httpkit.client/default-client`, but provides SNI support using `ssl-configurer`. NB Hostname verification currently requires Java version >= 11."}
default-client
(delay
(org.httpkit.client/make-client
{:ssl-configurer ssl-configurer})))