0
# Proxy and Network Configuration
1
2
Comprehensive proxy support with automatic proxy detection, connection pooling, and network configuration options through @npmcli/agent.
3
4
## Capabilities
5
6
### Proxy Configuration
7
8
Configure HTTP, HTTPS, and SOCKS proxies with automatic environment variable detection.
9
10
```javascript { .api }
11
/**
12
* Proxy configuration options
13
*/
14
interface ProxyOptions {
15
proxy?: string | URL; // Proxy URL (http://, https://, socks://)
16
noProxy?: string | string[]; // Domains to bypass proxy for
17
}
18
19
/**
20
* Supported proxy protocols:
21
* - http://proxy.example.com:8080
22
* - https://proxy.example.com:8443
23
* - socks://proxy.example.com:1080
24
* - socks4://proxy.example.com:1080
25
* - socks5://proxy.example.com:1080
26
*/
27
```
28
29
**Usage Examples:**
30
31
```javascript
32
const fetch = require('make-fetch-happen');
33
34
// HTTP proxy
35
const response1 = await fetch('https://api.example.com/data', {
36
proxy: 'http://proxy.company.com:8080'
37
});
38
39
// HTTPS proxy with authentication
40
const response2 = await fetch('https://api.example.com/data', {
41
proxy: 'https://username:password@proxy.company.com:8443'
42
});
43
44
// SOCKS5 proxy
45
const response3 = await fetch('https://api.example.com/data', {
46
proxy: 'socks5://proxy.company.com:1080'
47
});
48
49
// Proxy with URL object
50
const proxyUrl = new URL('http://proxy.company.com:8080');
51
const response4 = await fetch('https://api.example.com/data', {
52
proxy: proxyUrl
53
});
54
```
55
56
### Environment Variable Support
57
58
Automatic proxy detection from standard environment variables:
59
60
```javascript { .api }
61
/**
62
* Environment variables (checked in order of precedence):
63
* - HTTP_PROXY: Proxy for HTTP requests
64
* - HTTPS_PROXY: Proxy for HTTPS requests
65
* - PROXY: Fallback proxy for all requests
66
* - NO_PROXY: Comma-separated list of domains to bypass proxy
67
*
68
* Variables are case-insensitive and support both upper and lowercase
69
*/
70
```
71
72
**Usage Examples:**
73
74
```bash
75
# Set environment variables
76
export HTTP_PROXY=http://proxy.company.com:8080
77
export HTTPS_PROXY=https://proxy.company.com:8443
78
export NO_PROXY=localhost,127.0.0.1,.company.com
79
80
# Or in package.json scripts
81
{
82
"scripts": {
83
"start": "HTTP_PROXY=http://proxy:8080 node app.js"
84
}
85
}
86
```
87
88
```javascript
89
// Proxy will be automatically detected from environment
90
const response = await fetch('https://api.example.com/data');
91
92
// Override environment with explicit proxy
93
const response2 = await fetch('https://api.example.com/data', {
94
proxy: 'http://different-proxy:8080'
95
});
96
97
// Disable proxy for this request
98
const response3 = await fetch('https://api.example.com/data', {
99
proxy: null
100
});
101
```
102
103
### No Proxy Configuration
104
105
Bypass proxy for specific domains or IP addresses:
106
107
```javascript { .api }
108
/**
109
* No proxy patterns support:
110
* - Exact domain matches: example.com
111
* - Subdomain matches: .example.com (matches any.sub.example.com)
112
* - IP addresses: 192.168.1.1
113
* - IP ranges: 192.168.1.0/24
114
* - Port specifications: example.com:8080
115
* - Wildcards: *.example.com
116
*/
117
```
118
119
**Usage Examples:**
120
121
```javascript
122
// Bypass proxy for specific domains
123
const response = await fetch('https://internal-api.company.com/data', {
124
proxy: 'http://proxy.company.com:8080',
125
noProxy: [
126
'localhost',
127
'127.0.0.1',
128
'.company.com',
129
'192.168.1.0/24'
130
]
131
});
132
133
// Single domain as string
134
const response2 = await fetch('https://localhost:3000/api', {
135
proxy: 'http://proxy.company.com:8080',
136
noProxy: 'localhost'
137
});
138
139
// Environment variable format (comma-separated)
140
const response3 = await fetch('https://api.example.com/data', {
141
proxy: 'http://proxy.company.com:8080',
142
noProxy: 'localhost,127.0.0.1,.company.com,*.internal.com'
143
});
144
```
145
146
### Connection Pooling
147
148
Configure connection pooling and socket management:
149
150
```javascript { .api }
151
/**
152
* Connection pooling options
153
*/
154
interface ConnectionOptions {
155
maxSockets?: number; // Maximum concurrent connections per host (default: 15)
156
localAddress?: string; // Local address to bind connections to
157
agent?: object; // Custom HTTP agent configuration
158
}
159
```
160
161
**Usage Examples:**
162
163
```javascript
164
// Limit concurrent connections
165
const response = await fetch('https://api.example.com/data', {
166
maxSockets: 10
167
});
168
169
// Bind to specific local interface
170
const response2 = await fetch('https://api.example.com/data', {
171
localAddress: '192.168.1.100'
172
});
173
174
// Global connection pool configuration
175
const apiFetch = fetch.defaults({
176
maxSockets: 25,
177
proxy: 'http://proxy.company.com:8080'
178
});
179
```
180
181
### Advanced Agent Configuration
182
183
Configure the underlying HTTP agent with detailed options:
184
185
```javascript { .api }
186
/**
187
* Agent configuration passed to @npmcli/agent
188
*/
189
interface AgentOptions {
190
agent?: {
191
http?: object; // HTTP agent options
192
https?: object; // HTTPS agent options
193
proxy?: object; // Proxy agent options
194
dns?: DNSOptions; // DNS configuration
195
timeout?: { // Timeout configuration
196
connection?: number; // Connection timeout
197
idle?: number; // Idle timeout
198
response?: number; // Response timeout
199
transfer?: number; // Transfer timeout
200
};
201
};
202
}
203
204
interface DNSOptions {
205
ttl?: number; // DNS cache TTL in milliseconds (default: 300000)
206
lookup?: Function; // Custom DNS lookup function
207
}
208
```
209
210
**Usage Examples:**
211
212
```javascript
213
// Custom agent configuration
214
const response = await fetch('https://api.example.com/data', {
215
agent: {
216
timeout: {
217
connection: 10000, // 10 second connection timeout
218
response: 30000, // 30 second response timeout
219
idle: 60000, // 60 second idle timeout
220
transfer: 120000 // 2 minute transfer timeout
221
},
222
dns: {
223
ttl: 60000, // 1 minute DNS cache
224
lookup: require('dns').lookup
225
}
226
}
227
});
228
229
// Custom HTTP agent options
230
const response2 = await fetch('https://api.example.com/data', {
231
agent: {
232
http: {
233
keepAlive: true,
234
keepAliveMsecs: 30000,
235
maxSockets: 20,
236
maxFreeSockets: 10
237
},
238
https: {
239
keepAlive: true,
240
rejectUnauthorized: true
241
}
242
}
243
});
244
```
245
246
### DNS Configuration
247
248
Configure DNS caching and lookup behavior:
249
250
```javascript { .api }
251
/**
252
* DNS configuration options
253
*/
254
interface DNSOptions {
255
ttl?: number; // DNS cache TTL in milliseconds
256
lookup?: Function; // Custom DNS lookup function
257
}
258
```
259
260
**Usage Examples:**
261
262
```javascript
263
// Custom DNS configuration
264
const response = await fetch('https://api.example.com/data', {
265
dns: {
266
ttl: 300000, // 5 minute DNS cache
267
lookup: (hostname, options, callback) => {
268
// Custom DNS resolution logic
269
console.log(`Resolving ${hostname}`);
270
require('dns').lookup(hostname, options, callback);
271
}
272
}
273
});
274
275
// Disable DNS caching
276
const response2 = await fetch('https://api.example.com/data', {
277
dns: {
278
ttl: 0 // No DNS caching
279
}
280
});
281
```
282
283
### Network Error Handling
284
285
Handle network-specific errors and timeouts:
286
287
```javascript { .api }
288
/**
289
* Network error codes from @npmcli/agent:
290
* - ECONNECTIONTIMEOUT: Connection timeout
291
* - EIDLETIMEOUT: Idle timeout
292
* - ERESPONSETIMEOUT: Response timeout
293
* - ETRANSFERTIMEOUT: Transfer timeout
294
* - EINVALIDPROXY: Invalid proxy configuration
295
* - EINVALIDRESPONSE: Invalid response from server
296
*/
297
```
298
299
**Usage Examples:**
300
301
```javascript
302
try {
303
const response = await fetch('https://slow-api.example.com/data', {
304
timeout: 30000,
305
agent: {
306
timeout: {
307
connection: 5000,
308
response: 10000
309
}
310
}
311
});
312
} catch (error) {
313
switch (error.code) {
314
case 'ECONNECTIONTIMEOUT':
315
console.log('Failed to establish connection within timeout');
316
break;
317
case 'ERESPONSETIMEOUT':
318
console.log('Server took too long to respond');
319
break;
320
case 'ETRANSFERTIMEOUT':
321
console.log('Data transfer took too long');
322
break;
323
case 'EINVALIDPROXY':
324
console.log('Proxy configuration is invalid');
325
break;
326
default:
327
console.log('Network error:', error.message);
328
}
329
}
330
```
331
332
### Corporate Network Patterns
333
334
Common patterns for corporate environments:
335
336
```javascript
337
// Corporate proxy configuration
338
const createCorporateFetch = () => {
339
return fetch.defaults({
340
proxy: process.env.CORPORATE_PROXY || 'http://proxy.company.com:8080',
341
noProxy: [
342
'localhost',
343
'127.0.0.1',
344
'.company.com',
345
'.internal',
346
'10.0.0.0/8',
347
'172.16.0.0/12',
348
'192.168.0.0/16'
349
],
350
maxSockets: 10,
351
timeout: 30000
352
});
353
};
354
355
// Development vs production proxy
356
const createEnvironmentFetch = (env) => {
357
const config = {
358
maxSockets: env === 'production' ? 25 : 10
359
};
360
361
if (env === 'development') {
362
config.proxy = 'http://localhost:8888'; // Development proxy
363
} else if (env === 'staging') {
364
config.proxy = 'http://staging-proxy.company.com:8080';
365
} else if (env === 'production') {
366
config.proxy = 'http://prod-proxy.company.com:8080';
367
}
368
369
return fetch.defaults(config);
370
};
371
372
// Proxy authentication with token refresh
373
const createAuthenticatedProxyFetch = () => {
374
let proxyAuth = null;
375
376
const refreshProxyAuth = async () => {
377
// Refresh proxy authentication token
378
const authResponse = await fetch('https://auth.company.com/proxy-token');
379
const { token } = await authResponse.json();
380
proxyAuth = `Bearer ${token}`;
381
};
382
383
return async (url, options = {}) => {
384
if (!proxyAuth) {
385
await refreshProxyAuth();
386
}
387
388
return fetch(url, {
389
...options,
390
proxy: `http://${proxyAuth}@proxy.company.com:8080`
391
});
392
};
393
};
394
```