An HTTP(s) proxy Agent implementation for HTTPS connections that tunnels requests through proxy servers using the CONNECT method
npx @tessl/cli install tessl/npm-https-proxy-agent@7.0.00
# HTTPS Proxy Agent
1
2
HTTPS Proxy Agent provides an HTTP Agent implementation that connects to specified HTTP or HTTPS proxy servers using the CONNECT method to establish direct TCP connections to destination servers through proxy intermediaries. It supports both HTTPS requests and WebSocket connections over proxies, making it suitable for applications that need to route secure connections through corporate or private proxy infrastructure.
3
4
## Package Information
5
6
- **Package Name**: https-proxy-agent
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install https-proxy-agent`
10
11
## Core Imports
12
13
```typescript
14
import { HttpsProxyAgent } from "https-proxy-agent";
15
import type { HttpsProxyAgentOptions, ConnectResponse } from "https-proxy-agent";
16
```
17
18
For CommonJS:
19
20
```javascript
21
const { HttpsProxyAgent } = require("https-proxy-agent");
22
```
23
24
## Basic Usage
25
26
```typescript
27
import * as https from 'https';
28
import { HttpsProxyAgent } from 'https-proxy-agent';
29
30
// Create agent with HTTP proxy
31
const agent = new HttpsProxyAgent('http://proxy.example.com:8080');
32
33
// Use with HTTPS requests
34
https.get('https://example.com', { agent }, (res) => {
35
console.log('Status:', res.statusCode);
36
res.pipe(process.stdout);
37
});
38
39
// With authentication
40
const authAgent = new HttpsProxyAgent('http://user:pass@proxy.example.com:8080');
41
42
// With custom headers
43
const customAgent = new HttpsProxyAgent('http://proxy.example.com:8080', {
44
headers: {
45
'User-Agent': 'MyApp/1.0'
46
}
47
});
48
```
49
50
## Architecture
51
52
HTTPS Proxy Agent extends Node.js's `Agent` class from the `agent-base` package and implements the HTTP CONNECT method for proxy tunneling:
53
54
- **Proxy Connection**: Establishes connection to proxy server using HTTP or HTTPS
55
- **CONNECT Tunnel**: Uses HTTP CONNECT method to request proxy server to establish TCP tunnel to destination
56
- **TLS Upgrade**: For HTTPS destinations, upgrades the tunneled connection to TLS after proxy handshake
57
- **Authentication**: Automatically handles Basic authentication when credentials are in proxy URL
58
- **Error Handling**: Provides detailed error information for connection failures and proxy authentication issues
59
60
## Capabilities
61
62
### HttpsProxyAgent Class
63
64
Main class that implements HTTP Agent functionality for proxy connections.
65
66
```typescript { .api }
67
class HttpsProxyAgent<Uri extends string> extends Agent {
68
constructor(proxy: Uri | URL, opts?: HttpsProxyAgentOptions<Uri>);
69
70
static protocols: readonly ['http', 'https'];
71
readonly proxy: URL;
72
proxyHeaders: OutgoingHttpHeaders | (() => OutgoingHttpHeaders);
73
connectOpts: net.TcpNetConnectOpts & tls.ConnectionOptions;
74
75
connect(req: http.ClientRequest, opts: AgentConnectOpts): Promise<net.Socket>;
76
}
77
```
78
79
**Constructor Parameters:**
80
81
- `proxy`: String URL or URL object for the proxy server. Supports `http://` and `https://` protocols
82
- `opts`: Optional configuration object with proxy headers and connection options
83
84
**Properties:**
85
86
- `protocols`: Static property indicating supported proxy protocols (`['http', 'https']`)
87
- `proxy`: The parsed proxy URL
88
- `proxyHeaders`: Headers to send with CONNECT requests (object or function)
89
- `connectOpts`: Connection options used when connecting to proxy server
90
91
**Methods:**
92
93
- `connect()`: Internal method called by Node.js HTTP client to establish proxy connection
94
95
### Configuration Options
96
97
Options interface for customizing HttpsProxyAgent behavior.
98
99
```typescript { .api }
100
type HttpsProxyAgentOptions<T> = ConnectOpts<T> & http.AgentOptions & {
101
headers?: OutgoingHttpHeaders | (() => OutgoingHttpHeaders);
102
};
103
104
// Protocol-specific connection options based on proxy URL protocol
105
type ConnectOpts<T> = {
106
http: Omit<net.TcpNetConnectOpts, 'host' | 'port'>;
107
https: Omit<tls.ConnectionOptions, 'host' | 'port'>;
108
}[Protocol<T>];
109
110
// Extract protocol from proxy URL type
111
type Protocol<T> = T extends `${infer Protocol}:${infer _}` ? Protocol : never;
112
```
113
114
**Configuration Properties:**
115
116
- `headers`: Custom headers for proxy CONNECT requests (static object or function returning headers)
117
- Protocol-specific connection options (determined by proxy URL protocol):
118
- For `http://` proxies: `net.TcpNetConnectOpts` options (excluding host/port)
119
- For `https://` proxies: `tls.ConnectionOptions` options (excluding host/port)
120
- Standard `http.Agent` options for connection pooling and timeouts
121
122
### Types
123
124
Supporting types for proxy connections. Note that `OutgoingHttpHeaders` and `AgentConnectOpts` are imported from Node.js built-in modules.
125
126
```typescript { .api }
127
// From Node.js 'http' module
128
interface OutgoingHttpHeaders {
129
[header: string]: number | string | string[] | undefined;
130
}
131
132
// From 'agent-base' package
133
interface AgentConnectOpts {
134
host: string;
135
port: number;
136
secureEndpoint: boolean;
137
servername?: string;
138
}
139
140
// Proxy CONNECT response structure
141
interface ConnectResponse {
142
statusCode: number;
143
statusText: string;
144
headers: IncomingHttpHeaders;
145
}
146
147
// From Node.js 'http' module
148
interface IncomingHttpHeaders {
149
[header: string]: string | string[] | undefined;
150
}
151
```
152
153
## Usage Examples
154
155
### WebSocket Connections
156
157
```typescript
158
import WebSocket from 'ws';
159
import { HttpsProxyAgent } from 'https-proxy-agent';
160
161
const agent = new HttpsProxyAgent('http://proxy.example.com:8080');
162
const socket = new WebSocket('wss://echo.websocket.org', { agent });
163
164
socket.on('open', () => {
165
console.log('WebSocket connected through proxy');
166
socket.send('Hello World');
167
});
168
169
socket.on('message', (data) => {
170
console.log('Received:', data.toString());
171
socket.close();
172
});
173
```
174
175
### Dynamic Headers
176
177
```typescript
178
import { HttpsProxyAgent } from 'https-proxy-agent';
179
180
let requestCount = 0;
181
182
const agent = new HttpsProxyAgent('http://proxy.example.com:8080', {
183
headers: () => ({
184
'X-Request-ID': `req-${++requestCount}`,
185
'X-Client-Name': 'MyApp'
186
})
187
});
188
189
// Each request will have incrementing request ID
190
```
191
192
### HTTPS Proxy with Self-Signed Certificate
193
194
```typescript
195
import { HttpsProxyAgent } from 'https-proxy-agent';
196
197
const agent = new HttpsProxyAgent('https://proxy.example.com:8443', {
198
rejectUnauthorized: false, // Accept self-signed certificates
199
headers: {
200
'Proxy-Authorization': 'Bearer token123'
201
}
202
});
203
```
204
205
### Connection Pooling
206
207
```typescript
208
import { HttpsProxyAgent } from 'https-proxy-agent';
209
210
const agent = new HttpsProxyAgent('http://proxy.example.com:8080', {
211
keepAlive: true,
212
keepAliveMsecs: 30000,
213
maxSockets: 10,
214
maxFreeSockets: 3
215
});
216
217
// Reuse connections for better performance
218
```
219
220
## Events
221
222
### Agent Events
223
224
The HttpsProxyAgent emits events during proxy connection establishment:
225
226
- `'proxyConnect'`: Emitted when proxy CONNECT handshake completes successfully
227
- Parameters: `(connectResponse, clientRequest)`
228
- `connectResponse`: Object with `{ statusCode: number, statusText: string, headers: IncomingHttpHeaders }`
229
- `clientRequest`: The originating HTTP client request
230
231
### Request Events
232
233
HTTP ClientRequest objects emit proxy-related events:
234
235
- `'proxyConnect'`: Emitted on the request when proxy connection is established
236
- Parameters: `(connectResponse)`
237
- `connectResponse`: Same object structure as agent event
238
239
```typescript
240
import * as https from 'https';
241
import { HttpsProxyAgent } from 'https-proxy-agent';
242
243
const agent = new HttpsProxyAgent('http://proxy.example.com:8080');
244
245
agent.on('proxyConnect', (connectResponse, req) => {
246
console.log('Proxy connected:', connectResponse.statusCode);
247
console.log('Status text:', connectResponse.statusText);
248
});
249
250
const req = https.get('https://example.com', { agent }, (res) => {
251
// Handle response
252
});
253
254
req.on('proxyConnect', (connectResponse) => {
255
console.log('Request proxy connected:', connectResponse.statusCode);
256
});
257
```
258
259
## Error Handling
260
261
### Constructor Errors
262
263
- **Invalid proxy URL**: Throws when provided proxy URL is invalid or empty
264
- **Protocol errors**: Throws for unsupported proxy protocols
265
266
```typescript
267
try {
268
const agent = new HttpsProxyAgent(''); // Throws error
269
} catch (error) {
270
console.error('Invalid proxy URL:', error.message);
271
}
272
```
273
274
### Connection Errors
275
276
- **Connection refused**: When proxy server is unreachable
277
- **Authentication failures**: When proxy returns non-200 status codes
278
- **Timeout errors**: When connection to proxy times out
279
- **TLS errors**: When HTTPS proxy has certificate issues
280
281
```typescript
282
import * as https from 'https';
283
import { HttpsProxyAgent } from 'https-proxy-agent';
284
285
const agent = new HttpsProxyAgent('http://unreachable-proxy:8080');
286
287
const req = https.get('https://example.com', { agent }, (res) => {
288
// This won't be called if proxy connection fails
289
});
290
291
req.on('error', (error) => {
292
if (error.code === 'ECONNREFUSED') {
293
console.error('Proxy server unreachable');
294
} else if (error.code === 'ENOTFOUND') {
295
console.error('Proxy server not found');
296
} else {
297
console.error('Request error:', error.message);
298
}
299
});
300
```
301
302
### Proxy Authentication
303
304
The agent automatically handles Basic authentication when credentials are included in the proxy URL:
305
306
```typescript
307
// Authentication automatically handled
308
const agent = new HttpsProxyAgent('http://username:password@proxy.example.com:8080');
309
310
// Manual authentication headers
311
const agent2 = new HttpsProxyAgent('http://proxy.example.com:8080', {
312
headers: {
313
'Proxy-Authorization': 'Basic ' + Buffer.from('username:password').toString('base64')
314
}
315
});
316
```
317
318
## Common Use Cases
319
320
### Corporate Proxies
321
322
```typescript
323
import { HttpsProxyAgent } from 'https-proxy-agent';
324
325
// Corporate proxy with authentication
326
const agent = new HttpsProxyAgent(process.env.HTTPS_PROXY || 'http://proxy.corp.com:8080', {
327
headers: {
328
'User-Agent': 'Corporate App v1.0'
329
}
330
});
331
```
332
333
### Development and Testing
334
335
```typescript
336
import { HttpsProxyAgent } from 'https-proxy-agent';
337
338
// Debug proxy for inspecting traffic
339
const debugAgent = new HttpsProxyAgent('http://localhost:8888', {
340
headers: () => ({
341
'X-Debug-Session': Date.now().toString()
342
})
343
});
344
```
345
346
### Load Balancing Through Multiple Proxies
347
348
```typescript
349
import { HttpsProxyAgent } from 'https-proxy-agent';
350
351
const proxies = [
352
'http://proxy1.example.com:8080',
353
'http://proxy2.example.com:8080',
354
'http://proxy3.example.com:8080'
355
];
356
357
let currentProxy = 0;
358
359
function getAgent() {
360
const proxyUrl = proxies[currentProxy++ % proxies.length];
361
return new HttpsProxyAgent(proxyUrl);
362
}
363
364
// Use different proxy for each request
365
const agent = getAgent();
366
```