1# Connecting through a proxy
2
3Connecting through a proxy is possible by:
4
5- Using [AgentProxy](../api/ProxyAgent.md).
6- Configuring `Client` or `Pool` constructor.
7
8The proxy url should be passed to the `Client` or `Pool` constructor, while the upstream server url
9should be added to every request call in the `path`.
10For instance, if you need to send a request to the `/hello` route of your upstream server,
11the `path` should be `path: 'http://upstream.server:port/hello?foo=bar'`.
12
13If you proxy requires basic authentication, you can send it via the `proxy-authorization` header.
14
15### Connect without authentication
16
17```js
18import { Client } from 'undici'
19import { createServer } from 'http'
20import proxy from 'proxy'
21
22const server = await buildServer()
23const proxyServer = await buildProxy()
24
25const serverUrl = `http://localhost:${server.address().port}`
26const proxyUrl = `http://localhost:${proxyServer.address().port}`
27
28server.on('request', (req, res) => {
29  console.log(req.url) // '/hello?foo=bar'
30  res.setHeader('content-type', 'application/json')
31  res.end(JSON.stringify({ hello: 'world' }))
32})
33
34const client = new Client(proxyUrl)
35
36const response = await client.request({
37  method: 'GET',
38  path: serverUrl + '/hello?foo=bar'
39})
40
41response.body.setEncoding('utf8')
42let data = ''
43for await (const chunk of response.body) {
44  data += chunk
45}
46console.log(response.statusCode) // 200
47console.log(JSON.parse(data)) // { hello: 'world' }
48
49server.close()
50proxyServer.close()
51client.close()
52
53function buildServer () {
54  return new Promise((resolve, reject) => {
55    const server = createServer()
56    server.listen(0, () => resolve(server))
57  })
58}
59
60function buildProxy () {
61  return new Promise((resolve, reject) => {
62    const server = proxy(createServer())
63    server.listen(0, () => resolve(server))
64  })
65}
66```
67
68### Connect with authentication
69
70```js
71import { Client } from 'undici'
72import { createServer } from 'http'
73import proxy from 'proxy'
74
75const server = await buildServer()
76const proxyServer = await buildProxy()
77
78const serverUrl = `http://localhost:${server.address().port}`
79const proxyUrl = `http://localhost:${proxyServer.address().port}`
80
81proxyServer.authenticate = function (req, fn) {
82  fn(null, req.headers['proxy-authorization'] === `Basic ${Buffer.from('user:pass').toString('base64')}`)
83}
84
85server.on('request', (req, res) => {
86  console.log(req.url) // '/hello?foo=bar'
87  res.setHeader('content-type', 'application/json')
88  res.end(JSON.stringify({ hello: 'world' }))
89})
90
91const client = new Client(proxyUrl)
92
93const response = await client.request({
94  method: 'GET',
95  path: serverUrl + '/hello?foo=bar',
96  headers: {
97    'proxy-authorization': `Basic ${Buffer.from('user:pass').toString('base64')}`
98  }
99})
100
101response.body.setEncoding('utf8')
102let data = ''
103for await (const chunk of response.body) {
104  data += chunk
105}
106console.log(response.statusCode) // 200
107console.log(JSON.parse(data)) // { hello: 'world' }
108
109server.close()
110proxyServer.close()
111client.close()
112
113function buildServer () {
114  return new Promise((resolve, reject) => {
115    const server = createServer()
116    server.listen(0, () => resolve(server))
117  })
118}
119
120function buildProxy () {
121  return new Promise((resolve, reject) => {
122    const server = proxy(createServer())
123    server.listen(0, () => resolve(server))
124  })
125}
126```
127
128