Skip to content

Commit b5efdf9

Browse files
author
Marco Munizaga
committed
Added support for socks proxies
1 parent 7d44c27 commit b5efdf9

File tree

2 files changed

+58
-3
lines changed

2 files changed

+58
-3
lines changed

Readme.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,26 @@ You can also specify the `proxy-ignore-hosts` parameter with a list of
390390
hosts where the proxy should be ignored. By default this list is
391391
`#{"localhost" "127.0.0.1"}`.
392392

393+
### SOCKS Proxies
394+
395+
A SOCKS proxy can be used by creating a proxied connection manager
396+
with `clj-http.conn-mgr/make-socks-proxied-conn-manager`. Then using
397+
that connection manager in the request.
398+
399+
For example if you wanted to connect to a local socks proxy on port `8081` you would:
400+
401+
```clojure
402+
(ns foo.bar
403+
(:require [clj-http.client :as client]
404+
[clj-http.conn-mgr :as conn-mgr]))
405+
406+
(client/get
407+
"https://google.com"
408+
{:connection-manager (conn-mgr/make-socks-proxied-conn-manager "localhost" 8081)})
409+
```
410+
411+
You can also store the proxied connection manager and reuse it later.
412+
393413
### Keystores and Trust-stores
394414

395415
When sending a request, you can specify your own keystore/trust-store

src/clj_http/conn_mgr.clj

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
(ns clj-http.conn-mgr
22
"Utility methods for Scheme registries and HTTP connection managers"
33
(:require [clojure.java.io :as io])
4-
(:import (java.security KeyStore)
4+
(:import (java.net Socket Proxy Proxy$Type InetSocketAddress)
5+
(java.security KeyStore)
56
(java.security.cert X509Certificate)
67
(javax.net.ssl SSLSession SSLSocket)
78
(org.apache.http.conn ClientConnectionManager)
89
(org.apache.http.conn.params ConnPerRouteBean)
9-
(org.apache.http.conn.ssl AllowAllHostnameVerifier SSLSocketFactory
10-
TrustStrategy X509HostnameVerifier)
10+
(org.apache.http.conn.ssl AllowAllHostnameVerifier SSLSocketFactory
11+
TrustStrategy X509HostnameVerifier
12+
SSLContexts)
1113
(org.apache.http.conn.scheme PlainSocketFactory
1214
SchemeRegistry Scheme)
1315
(org.apache.http.impl.conn BasicClientConnectionManager
@@ -42,6 +44,39 @@
4244
(^boolean verify [_ ^String _ ^SSLSession _]
4345
true))))
4446

47+
;; New Generic Socket Factories that can support socks proxy
48+
(defn SSLGenericSocketFactory
49+
"Given a function that returns a new socket, create an SSLSocketFactory the will use that socket"
50+
(^SSLSocketFactory [socket-factory]
51+
(proxy
52+
[SSLSocketFactory] [(SSLContexts/createDefault)]
53+
(connectSocket [socket remoteAddress localAddress params]
54+
(let [^SSLSocketFactory this this] ; avoid reflection
55+
(proxy-super connectSocket (socket-factory) remoteAddress localAddress params))))))
56+
57+
(defn PlainGenericSocketFactory
58+
"Given a Function that returns a new socket, create a PlainSocketFactory that will use that socket"
59+
(^PlainSocketFactory [socket-factory]
60+
(proxy
61+
[PlainSocketFactory] []
62+
(createSocket [params]
63+
(socket-factory)))))
64+
65+
(defn socks-proxied-socket
66+
"Create a Socket proxied through socks, using the given hostname and port"
67+
[^String hostname ^Integer port]
68+
(Socket. (Proxy. Proxy$Type/SOCKS (InetSocketAddress. hostname port))))
69+
70+
(defn make-socks-proxied-conn-manager
71+
"Given an optional hostname and a port, create a connection manager that's proxied using a SOCKS proxy"
72+
[^String hostname ^Integer port]
73+
(let [socket-factory #(socks-proxied-socket hostname port)
74+
reg (doto
75+
(SchemeRegistry.)
76+
(.register (Scheme. "https" 443 (SSLGenericSocketFactory socket-factory)))
77+
(.register (Scheme. "http" 80 (PlainGenericSocketFactory socket-factory))))]
78+
(PoolingClientConnectionManager. reg)))
79+
4580
(def insecure-scheme-registry
4681
(doto (SchemeRegistry.)
4782
(.register (Scheme. "http" 80 (PlainSocketFactory/getSocketFactory)))

0 commit comments

Comments
 (0)