A ProxyAgent routes every request through an HTTP, HTTPS, or SOCKS5 proxy
server. It implements the Agent API, so it can be used wherever a
dispatcher is accepted, for example with request or fetch, or
installed globally with setGlobalDispatcher.
For secure (https:) endpoints the proxy connection is established through an
HTTP CONNECT tunnel. SOCKS5 proxies (socks5: or socks: URIs) are handled
by delegating to a Socks5ProxyAgent.
import { ProxyAgent, setGlobalDispatcher } from 'undici'
const proxyAgent = new ProxyAgent('http://localhost:8000')
setGlobalDispatcher(proxyAgent)class ProxyAgent extends DispatcherProxyAgent keeps an internal Agent that creates per-origin dispatchers
on demand. The proxy connection is set up lazily when the first request to an
origin is dispatched, then reused for subsequent requests to the same origin.
new ProxyAgent(options): void<ProxyAgentOptions>
|
<string>
|
<URL>string
or
<URL>
is passed it is used as the proxy
uri
.
The options object extends
<AgentOptions>
(omitting
connect
).<string>options
is an
object. Parsed into a
<URL>
according to the
WHATWG URL Specification
.<string>proxy-authorization
header value sent to
the proxy on every request, for example
`Bearer ${apiKey}`
.<string>username:password
credential sent as a
Basic
proxy-authorization
header. Cannot be combined with
token
.<Object>CONNECT
request (or on every request for an untunneled HTTP proxy).
Default:
{}
.<BuildOptions><BuildOptions><Function><Dispatcher>
used to talk to the proxy
server itself.
Default:
(origin, opts) => new Pool(origin, opts)
.<URL><Object><Dispatcher><boolean>CONNECT
tunnel through the proxy
(after the TLS handshake to the proxy itself when the proxy URL is HTTPS).
If the target endpoint uses plain HTTP, Undici forwards the request to the
proxy using an HTTP/1.1 absolute-form request target (over TLS when the
proxy URL is HTTPS), as required by
RFC 9112 §3.2.2
.
This non-tunneled forwarding path does not negotiate HTTP/2 with the proxy.
Set
proxyTunnel
to
true
to force tunneling for plain HTTP requests as
well. Currently, there is no way to facilitate HTTP/1.1 IP tunneling as
described in
RFC 9484
.Throws an <InvalidArgumentError> when no proxy URI is provided, when clientFactory is not a function, or when both auth and token are supplied.
The proxy-authorization header is derived, in order of precedence, from
token, then auth, then the username and password embedded in the proxy
uri. Credentials in the URI are URL-decoded before being base64-encoded.
Unless <AgentOptions> connections is set to 0, the non-standard
proxy-connection: keep-alive header is added to the tunnel CONNECT
request. This includes the default case where connections is unset.
The auth option is deprecated; use token instead.
import { ProxyAgent } from 'undici'
// A string or URL is treated as the proxy uri.
const a = new ProxyAgent('http://localhost:8000')
const b = new ProxyAgent(new URL('http://localhost:8000'))
// An options object requires a `uri`.
const c = new ProxyAgent({ uri: 'http://localhost:8000' })
// With proxy TLS settings.
const d = new ProxyAgent({
uri: 'https://secure.proxy.server',
proxyTls: {
signal: AbortSignal.timeout(1000),
},
})import { setGlobalDispatcher, request, ProxyAgent } from 'undici'
const proxyAgent = new ProxyAgent('http://localhost:8000')
setGlobalDispatcher(proxyAgent)
const { statusCode, body } = await request('http://localhost:3000/foo')
console.log('response received', statusCode)
console.log('data', await body.text())import { ProxyAgent, request } from 'undici'
const proxyAgent = new ProxyAgent('http://localhost:8000')
const { statusCode, body } = await request('http://localhost:3000/foo', {
dispatcher: proxyAgent,
})
console.log('response received', statusCode)
console.log('data', await body.text())import { setGlobalDispatcher, request, ProxyAgent } from 'undici'
const proxyAgent = new ProxyAgent({
uri: 'http://localhost:8000',
token: `Basic ${Buffer.from('username:password').toString('base64')}`,
})
setGlobalDispatcher(proxyAgent)
const { statusCode } = await request('http://localhost:3000/foo')
console.log('response received', statusCode)proxyAgent.dispatch(options, handler): boolean<AgentDispatchOptions><DispatchOptions>
.<DispatchHandler><boolean>false
if the dispatcher is busy and the caller should
wait for the
'drain'
event before dispatching again.Dispatches the request through the proxy. Throws an <InvalidArgumentError> if
the request headers contain a proxy-authorization header, which must instead
be supplied through the constructor's token or auth option. A host header
is derived from options.origin when one is not already present. Implements
Dispatcher.dispatch().
proxyAgent.close
History
Untunneled HTTP-to-HTTP proxy connections match curl behavior.
proxyAgent.close(): Promise<void>Closes the proxy agent and waits for its internal agent and proxy client (when
present) to close before resolving. Implements Dispatcher.close().
import { ProxyAgent, setGlobalDispatcher } from 'undici'
const proxyAgent = new ProxyAgent('http://localhost:8000')
setGlobalDispatcher(proxyAgent)
await proxyAgent.close()proxyAgent.request(options, callback?): voidSee Dispatcher.request(). The request is routed through the proxy.
import { ProxyAgent, fetch } from 'undici'
const proxyAgent = new ProxyAgent('http://localhost:8000')
const response = await fetch('http://localhost:3000/foo', {
dispatcher: proxyAgent,
method: 'GET',
})
console.log('response status', response.status)
console.log('response data', await response.text())import { ProxyAgent, fetch } from 'undici'
const proxyAgent = new ProxyAgent('https://secure.proxy.server')
const response = await fetch('https://secure.endpoint.com/api/data', {
dispatcher: proxyAgent,
method: 'GET',
})
console.log('response status', response.status)
console.log('response data', await response.json())