0
# PAC Proxy Agent
1
2
PAC Proxy Agent provides an HTTP Agent implementation that retrieves and uses PAC (Proxy Auto-Configuration) files to determine the appropriate proxy server for HTTP and HTTPS connections. It integrates seamlessly with Node.js built-in HTTP and HTTPS modules, automatically resolving whether to use HTTP, HTTPS, or SOCKS proxies, or establish direct connections based on PAC file rules.
3
4
## Package Information
5
6
- **Package Name**: pac-proxy-agent
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install pac-proxy-agent`
10
- **Node.js Requirement**: >= 14
11
12
## Core Imports
13
14
```typescript
15
import { PacProxyAgent, type PacProxyAgentOptions } from "pac-proxy-agent";
16
```
17
18
For CommonJS:
19
20
```javascript
21
const { PacProxyAgent } = require("pac-proxy-agent");
22
```
23
24
## Basic Usage
25
26
```typescript
27
import * as http from 'http';
28
import { PacProxyAgent } from 'pac-proxy-agent';
29
30
// Create agent with PAC file URL
31
const agent = new PacProxyAgent('pac+https://example.com/proxy.pac');
32
33
// Use with http.get
34
http.get('http://nodejs.org/api/', { agent }, (res) => {
35
console.log('Response headers:', res.headers);
36
res.pipe(process.stdout);
37
});
38
39
// Use with https requests
40
import * as https from 'https';
41
const httpsAgent = new PacProxyAgent('pac+https://example.com/proxy.pac');
42
https.get('https://api.example.com/data', { agent: httpsAgent }, (res) => {
43
// Handle response
44
});
45
```
46
47
## Architecture
48
49
PAC Proxy Agent is built around several key components:
50
51
- **PAC File Loading**: Supports multiple protocols (data, file, ftp, http, https) for PAC file retrieval
52
- **JavaScript Execution**: Uses QuickJS for secure PAC file JavaScript execution
53
- **Proxy Resolution**: Dynamically determines proxy configuration for each request
54
- **Fallback Chain**: Supports multiple proxies with automatic fallback on failure
55
- **Agent Delegation**: Integrates with specific proxy agent implementations (HTTP, HTTPS, SOCKS)
56
57
## Capabilities
58
59
### PAC Proxy Agent Class
60
61
The main proxy agent class that handles PAC file resolution and proxy connection management.
62
63
```typescript { .api }
64
/**
65
* PAC Proxy Agent implementation that loads PAC files and resolves proxy settings
66
* Supports various PAC file protocols: data, file, ftp, http, https
67
*/
68
class PacProxyAgent<Uri extends string> extends Agent {
69
/** Supported PAC protocols */
70
static readonly protocols: Array<'pac+data' | 'pac+file' | 'pac+ftp' | 'pac+http' | 'pac+https'>;
71
72
/** PAC file URI (with pac+ prefix stripped) */
73
uri: URL;
74
75
/** Configuration options */
76
opts: PacProxyAgentOptions<Uri>;
77
78
/** Cached PAC file stream (undefined if not loaded) */
79
cache?: Readable;
80
81
/** Cached PAC resolver function (undefined if not loaded) */
82
resolver?: FindProxyForURL;
83
84
/** SHA1 hash of current PAC file content for change detection */
85
resolverHash: string;
86
87
/** Promise for resolver loading (undefined when not loading) */
88
resolverPromise?: Promise<FindProxyForURL>;
89
90
/**
91
* Creates a new PAC Proxy Agent
92
* @param uri - PAC file URI with protocol prefix (pac+http://..., pac+file://..., etc.)
93
* @param opts - Configuration options
94
*/
95
constructor(uri: Uri | URL, opts?: PacProxyAgentOptions<Uri>);
96
97
/**
98
* Loads the PAC proxy file and returns a resolver function
99
* Caches the resolver and reuses it if the PAC file content hasn't changed
100
* @returns Promise resolving to FindProxyForURL function
101
*/
102
getResolver(): Promise<FindProxyForURL>;
103
104
/**
105
* Establishes connection through appropriate proxy based on PAC resolution
106
* Called automatically by Node.js HTTP client when making requests
107
* @param req - HTTP client request
108
* @param opts - Connection options including host, port, secureEndpoint
109
* @returns Promise resolving to Agent or Socket for the connection
110
*/
111
connect(req: http.ClientRequest, opts: AgentConnectOpts): Promise<http.Agent | net.Socket>;
112
}
113
```
114
115
### Configuration Options
116
117
Comprehensive options interface combining settings from multiple proxy agent types.
118
119
```typescript { .api }
120
/**
121
* Configuration options for PacProxyAgent
122
* Combines options from http.Agent, PAC resolver, and various proxy agents
123
*/
124
interface PacProxyAgentOptions<T> extends
125
http.AgentOptions,
126
PacResolverOptions,
127
GetUriOptions<Protocol<T>>,
128
HttpProxyAgentOptions<''>,
129
HttpsProxyAgentOptions<''>,
130
SocksProxyAgentOptions {
131
132
/**
133
* Whether to fall back to direct connection if all proxies fail
134
* When true, adds 'DIRECT' to the end of proxy list
135
* @default false
136
*/
137
fallbackToDirect?: boolean;
138
}
139
```
140
141
### PAC File Support
142
143
The agent supports loading PAC files from multiple sources with automatic protocol detection.
144
145
**Supported Protocols:**
146
147
- `pac+data:` - Embedded data URI containing PAC file content
148
- `pac+file:` - Local file system path to PAC file
149
- `pac+ftp:` - FTP server hosting PAC file
150
- `pac+http:` - HTTP endpoint serving PAC file
151
- `pac+https:` - HTTPS endpoint serving PAC file
152
153
**Usage Examples:**
154
155
```typescript
156
// Data URI with embedded PAC file
157
const dataAgent = new PacProxyAgent('pac+data:,function FindProxyForURL(){return "PROXY proxy.example.com:8080";}');
158
159
// Local PAC file
160
const fileAgent = new PacProxyAgent('pac+file:///etc/proxy.pac');
161
162
// Remote PAC file over HTTPS
163
const httpsAgent = new PacProxyAgent('pac+https://config.company.com/proxy.pac');
164
165
// With custom options
166
const customAgent = new PacProxyAgent('pac+https://config.company.com/proxy.pac', {
167
fallbackToDirect: true,
168
timeout: 5000,
169
rejectUnauthorized: false // for self-signed certificates
170
});
171
```
172
173
### Proxy Type Support
174
175
Based on PAC file resolution, the agent automatically selects the appropriate proxy implementation.
176
177
**Supported Proxy Types:**
178
179
- `DIRECT` - Direct connection to destination (no proxy)
180
- `PROXY` / `HTTP` - HTTP proxy connection
181
- `HTTPS` - HTTPS proxy connection
182
- `SOCKS` / `SOCKS5` - SOCKS5 proxy connection
183
- `SOCKS4` - SOCKS4 proxy connection
184
185
**Proxy Resolution Flow:**
186
187
```typescript
188
// PAC file example that returns multiple proxy options
189
function FindProxyForURL(url, host) {
190
if (host === "internal.company.com") {
191
return "DIRECT";
192
}
193
return "PROXY proxy1.company.com:8080; PROXY proxy2.company.com:8080; DIRECT";
194
}
195
```
196
197
The agent will try each proxy in sequence until one succeeds or all fail.
198
199
### Event Handling
200
201
The agent emits events on the HTTP request object to provide visibility into proxy selection.
202
203
```typescript { .api }
204
/**
205
* Proxy events emitted on the HTTP request object
206
*/
207
interface ProxyEvent {
208
/** The proxy string being attempted (e.g., "PROXY proxy.example.com:8080") */
209
proxy: string;
210
/** The socket connection (present on successful connection) */
211
socket?: net.Socket;
212
/** Error that occurred (present on connection failure) */
213
error?: Error;
214
}
215
```
216
217
**Event Usage Example:**
218
219
```typescript
220
import { PacProxyAgent } from 'pac-proxy-agent';
221
import * as http from 'http';
222
223
const agent = new PacProxyAgent('pac+https://config.company.com/proxy.pac');
224
225
const req = http.get('http://api.example.com/data', { agent }, (res) => {
226
console.log('Request succeeded');
227
});
228
229
// Listen for proxy selection events
230
req.on('proxy', ({ proxy, socket, error }) => {
231
if (error) {
232
console.log(`Proxy ${proxy} failed:`, error.message);
233
} else {
234
console.log(`Using proxy: ${proxy}`);
235
}
236
});
237
```
238
239
### Error Handling
240
241
The agent handles various error scenarios gracefully with built-in fallback mechanisms.
242
243
**Common Error Scenarios:**
244
245
- **PAC file loading failures** - Network errors, file not found, invalid URLs
246
- **PAC file parsing errors** - Invalid JavaScript syntax in PAC file
247
- **Proxy connection failures** - Proxy server unreachable, authentication required
248
- **All proxies failed** - When no proxy in the list can establish connection
249
250
**Error Handling Example:**
251
252
```typescript
253
import { PacProxyAgent } from 'pac-proxy-agent';
254
import * as http from 'http';
255
256
const agent = new PacProxyAgent('pac+https://config.company.com/proxy.pac', {
257
fallbackToDirect: true // Enable direct connection fallback
258
});
259
260
try {
261
const req = http.get('http://api.example.com/data', { agent }, (res) => {
262
console.log('Success:', res.statusCode);
263
});
264
265
req.on('error', (error) => {
266
console.error('Request failed:', error.message);
267
});
268
269
req.on('proxy', ({ proxy, error }) => {
270
if (error) {
271
console.log(`Proxy ${proxy} failed, trying next...`);
272
}
273
});
274
} catch (error) {
275
console.error('Agent setup failed:', error.message);
276
}
277
```
278
279
## Types
280
281
### Core Types
282
283
```typescript { .api }
284
/**
285
* Readable stream from Node.js stream module
286
* Used for PAC file content caching
287
*/
288
interface Readable {
289
// Node.js Readable stream interface (from 'stream' module)
290
}
291
292
/**
293
* FindProxyForURL function signature from PAC file
294
* Standard PAC function that determines proxy configuration for a given URL
295
*/
296
type FindProxyForURL = (url: string, host: string) => string | Promise<string>;
297
298
/**
299
* Agent connection options passed to connect method
300
* From 'agent-base' package - contains connection details like host, port, and security settings
301
*/
302
interface AgentConnectOpts {
303
/** Target hostname */
304
host: string;
305
/** Target port number */
306
port: number;
307
/** Whether this is an HTTPS connection */
308
secureEndpoint: boolean;
309
/** Additional connection options */
310
[key: string]: any;
311
}
312
313
/**
314
* Protocol extraction utility type
315
* Extracts the protocol portion from PAC URI strings
316
*/
317
type Protocol<T> = T extends `pac+${infer P}:${infer _}`
318
? P
319
: T extends `${infer P}:${infer _}`
320
? P
321
: never;
322
```
323
324
### Re-exported Dependencies
325
326
The package integrates with several proxy agent libraries. While these types are not directly exported, they're used in the options interface:
327
328
- `PacResolverOptions` - from 'pac-resolver' package
329
- `GetUriOptions` - from 'get-uri' package
330
- `HttpProxyAgentOptions` - from 'http-proxy-agent' package
331
- `HttpsProxyAgentOptions` - from 'https-proxy-agent' package
332
- `SocksProxyAgentOptions` - from 'socks-proxy-agent' package