A [Dispatcher][] implementation that routes requests through a SOCKS5
proxy server. It tunnels both HTTP and HTTPS traffic over the proxy, supports
optional username/password authentication, and pools connections per origin so
that subsequent requests to the same host reuse the established tunnel.
DNS resolution is delegated to the proxy: target host names are sent to the proxy as domain names rather than being resolved locally. For HTTPS targets the TLS session is negotiated end-to-end through the tunnel, so the proxy only sees encrypted bytes.
Import it from 'undici':
import { Socks5ProxyAgent } from 'undici'Constructing the agent emits a one-time ExperimentalWarning, reflecting the
experimental status of SOCKS5 support.
class Socks5ProxyAgent extends DispatcherRoutes dispatched requests through a SOCKS5 proxy. Register an instance as the
global dispatcher with [setGlobalDispatcher()][], or pass it per request via
the dispatcher option.
new Socks5ProxyAgent(proxyUrl, options?): voidsocks5:
or
socks:
protocol. Credentials may be embedded in the URL userinfo (for
example
socks5://user:pass@host:1080
).<Object><PoolOptions>
; the pool options are
applied to the per-origin pools created behind the tunnel.<Object>{}
.<string>proxyUrl
.
Default:
the URL username, if any.<string>proxyUrl
.
Default:
the URL password, if any.<Function>proxyTls
.<BuildOptions>servername
defaults to the proxy host name.<BuildOptions>ca
,
cert
,
key
,
rejectUnauthorized
, and
servername
.
servername
defaults to the target
host name.Throws an InvalidArgumentError if proxyUrl is missing or does not use the
socks5: or socks: protocol.
import { Socks5ProxyAgent } from 'undici'
// Without authentication.
const agent = new Socks5ProxyAgent('socks5://localhost:1080')
// With credentials in the URL.
const authAgent = new Socks5ProxyAgent('socks5://user:pass@localhost:1080')
// With credentials and pool options.
const configuredAgent = new Socks5ProxyAgent('socks5://localhost:1080', {
username: 'user',
password: 'pass',
connections: 10
})Using the agent as the global dispatcher:
import { setGlobalDispatcher, request, Socks5ProxyAgent } from 'undici'
const agent = new Socks5ProxyAgent('socks5://localhost:1080')
setGlobalDispatcher(agent)
const { statusCode, body } = await request('http://localhost:3000/foo')
console.log('response received', statusCode)
for await (const data of body) {
console.log('data', data.toString('utf8'))
}Using the agent per request:
import { request, Socks5ProxyAgent } from 'undici'
const agent = new Socks5ProxyAgent('socks5://localhost:1080')
const { statusCode, body } = await request('http://localhost:3000/foo', {
dispatcher: agent
})
console.log('response received', statusCode)HTTPS targets are tunnelled and encrypted end-to-end:
import { request, Socks5ProxyAgent } from 'undici'
const agent = new Socks5ProxyAgent('socks5://localhost:1080')
const { statusCode, body } = await request('https://api.example.com/data', {
dispatcher: agent
})
console.log('Response status:', statusCode)
console.log('Response data:', await body.json())socks5ProxyAgent.close(): Promise<void>Gracefully closes the agent, waiting for all underlying pools and their connections to drain and close before resolving.
import { setGlobalDispatcher, Socks5ProxyAgent } from 'undici'
const agent = new Socks5ProxyAgent('socks5://localhost:1080')
setGlobalDispatcher(agent)
// ... make requests ...
await agent.close()socks5ProxyAgent.destroy(err?): Promise<void><Error>Forcibly destroys the agent and all underlying connections immediately, without waiting for in-flight requests to complete.
import { Socks5ProxyAgent } from 'undici'
const agent = new Socks5ProxyAgent('socks5://localhost:1080')
await agent.destroy()socks5ProxyAgent.dispatch(options, handlers): boolean<DispatchOptions><DispatchHandler><boolean>false
if the dispatcher is busy and the request should be
retried later, otherwise
true
.Routes a request through the SOCKS5 tunnel. The agent maintains a [Pool][] per
target origin; the first request to a given origin establishes the tunnel and
upgrades to TLS when the target is HTTPS, and later requests reuse the pool.
This is the lower-level entry point implementing
Dispatcher.dispatch(options, handlers). Prefer
[socks5ProxyAgent.request()][] for most use cases.
socks5ProxyAgent.request(options, callback?): Promise | void<DispatchOptions><Function><Promise>
|
<void>callback
is
omitted.Performs a request through the SOCKS5 proxy. Inherited from
[Dispatcher.request(options[, callback])][]; see that method for the full set
of options and the shape of the resolved response.
import { fetch, Socks5ProxyAgent } from 'undici'
const agent = new Socks5ProxyAgent('socks5://localhost:1080')
const response = await fetch('http://localhost:3000/api/users', {
dispatcher: agent
})
console.log('Response status:', response.status)
console.log('Response data:', await response.text())SOCKS5 proxy activity can be traced with the undici:socks5-proxy debug scope:
NODE_DEBUG=undici:socks5-proxy node script.jsThis logs the SOCKS5 handshake, authentication, and tunnel establishment steps.
[Dispatcher.request(options[, callback])]: Dispatcher.md#dispatcherrequestoptions-callback
[Dispatcher]: Dispatcher.md#class-dispatcher
[Pool]: Pool.md#class-pool
[setGlobalDispatcher()]: Dispatcher.md#setglobaldispatcherdispatcher
[socks5ProxyAgent.request()]: #socks5proxyagentrequestoptions-callback