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.0HTTPS 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.
npm install https-proxy-agentimport { HttpsProxyAgent } from "https-proxy-agent";
import type { HttpsProxyAgentOptions, ConnectResponse } from "https-proxy-agent";For CommonJS:
const { HttpsProxyAgent } = require("https-proxy-agent");import * as https from 'https';
import { HttpsProxyAgent } from 'https-proxy-agent';
// Create agent with HTTP proxy
const agent = new HttpsProxyAgent('http://proxy.example.com:8080');
// Use with HTTPS requests
https.get('https://example.com', { agent }, (res) => {
console.log('Status:', res.statusCode);
res.pipe(process.stdout);
});
// With authentication
const authAgent = new HttpsProxyAgent('http://user:pass@proxy.example.com:8080');
// With custom headers
const customAgent = new HttpsProxyAgent('http://proxy.example.com:8080', {
headers: {
'User-Agent': 'MyApp/1.0'
}
});HTTPS Proxy Agent extends Node.js's Agent class from the agent-base package and implements the HTTP CONNECT method for proxy tunneling:
Main class that implements HTTP Agent functionality for proxy connections.
class HttpsProxyAgent<Uri extends string> extends Agent {
constructor(proxy: Uri | URL, opts?: HttpsProxyAgentOptions<Uri>);
static protocols: readonly ['http', 'https'];
readonly proxy: URL;
proxyHeaders: OutgoingHttpHeaders | (() => OutgoingHttpHeaders);
connectOpts: net.TcpNetConnectOpts & tls.ConnectionOptions;
connect(req: http.ClientRequest, opts: AgentConnectOpts): Promise<net.Socket>;
}Constructor Parameters:
proxy: String URL or URL object for the proxy server. Supports http:// and https:// protocolsopts: Optional configuration object with proxy headers and connection optionsProperties:
protocols: Static property indicating supported proxy protocols (['http', 'https'])proxy: The parsed proxy URLproxyHeaders: Headers to send with CONNECT requests (object or function)connectOpts: Connection options used when connecting to proxy serverMethods:
connect(): Internal method called by Node.js HTTP client to establish proxy connectionOptions interface for customizing HttpsProxyAgent behavior.
type HttpsProxyAgentOptions<T> = ConnectOpts<T> & http.AgentOptions & {
headers?: OutgoingHttpHeaders | (() => OutgoingHttpHeaders);
};
// Protocol-specific connection options based on proxy URL protocol
type ConnectOpts<T> = {
http: Omit<net.TcpNetConnectOpts, 'host' | 'port'>;
https: Omit<tls.ConnectionOptions, 'host' | 'port'>;
}[Protocol<T>];
// Extract protocol from proxy URL type
type Protocol<T> = T extends `${infer Protocol}:${infer _}` ? Protocol : never;Configuration Properties:
headers: Custom headers for proxy CONNECT requests (static object or function returning headers)http:// proxies: net.TcpNetConnectOpts options (excluding host/port)https:// proxies: tls.ConnectionOptions options (excluding host/port)http.Agent options for connection pooling and timeoutsSupporting types for proxy connections. Note that OutgoingHttpHeaders and AgentConnectOpts are imported from Node.js built-in modules.
// From Node.js 'http' module
interface OutgoingHttpHeaders {
[header: string]: number | string | string[] | undefined;
}
// From 'agent-base' package
interface AgentConnectOpts {
host: string;
port: number;
secureEndpoint: boolean;
servername?: string;
}
// Proxy CONNECT response structure
interface ConnectResponse {
statusCode: number;
statusText: string;
headers: IncomingHttpHeaders;
}
// From Node.js 'http' module
interface IncomingHttpHeaders {
[header: string]: string | string[] | undefined;
}import WebSocket from 'ws';
import { HttpsProxyAgent } from 'https-proxy-agent';
const agent = new HttpsProxyAgent('http://proxy.example.com:8080');
const socket = new WebSocket('wss://echo.websocket.org', { agent });
socket.on('open', () => {
console.log('WebSocket connected through proxy');
socket.send('Hello World');
});
socket.on('message', (data) => {
console.log('Received:', data.toString());
socket.close();
});import { HttpsProxyAgent } from 'https-proxy-agent';
let requestCount = 0;
const agent = new HttpsProxyAgent('http://proxy.example.com:8080', {
headers: () => ({
'X-Request-ID': `req-${++requestCount}`,
'X-Client-Name': 'MyApp'
})
});
// Each request will have incrementing request IDimport { HttpsProxyAgent } from 'https-proxy-agent';
const agent = new HttpsProxyAgent('https://proxy.example.com:8443', {
rejectUnauthorized: false, // Accept self-signed certificates
headers: {
'Proxy-Authorization': 'Bearer token123'
}
});import { HttpsProxyAgent } from 'https-proxy-agent';
const agent = new HttpsProxyAgent('http://proxy.example.com:8080', {
keepAlive: true,
keepAliveMsecs: 30000,
maxSockets: 10,
maxFreeSockets: 3
});
// Reuse connections for better performanceThe HttpsProxyAgent emits events during proxy connection establishment:
'proxyConnect': Emitted when proxy CONNECT handshake completes successfully
(connectResponse, clientRequest)connectResponse: Object with { statusCode: number, statusText: string, headers: IncomingHttpHeaders }clientRequest: The originating HTTP client requestHTTP ClientRequest objects emit proxy-related events:
'proxyConnect': Emitted on the request when proxy connection is established
(connectResponse)connectResponse: Same object structure as agent eventimport * as https from 'https';
import { HttpsProxyAgent } from 'https-proxy-agent';
const agent = new HttpsProxyAgent('http://proxy.example.com:8080');
agent.on('proxyConnect', (connectResponse, req) => {
console.log('Proxy connected:', connectResponse.statusCode);
console.log('Status text:', connectResponse.statusText);
});
const req = https.get('https://example.com', { agent }, (res) => {
// Handle response
});
req.on('proxyConnect', (connectResponse) => {
console.log('Request proxy connected:', connectResponse.statusCode);
});try {
const agent = new HttpsProxyAgent(''); // Throws error
} catch (error) {
console.error('Invalid proxy URL:', error.message);
}import * as https from 'https';
import { HttpsProxyAgent } from 'https-proxy-agent';
const agent = new HttpsProxyAgent('http://unreachable-proxy:8080');
const req = https.get('https://example.com', { agent }, (res) => {
// This won't be called if proxy connection fails
});
req.on('error', (error) => {
if (error.code === 'ECONNREFUSED') {
console.error('Proxy server unreachable');
} else if (error.code === 'ENOTFOUND') {
console.error('Proxy server not found');
} else {
console.error('Request error:', error.message);
}
});The agent automatically handles Basic authentication when credentials are included in the proxy URL:
// Authentication automatically handled
const agent = new HttpsProxyAgent('http://username:password@proxy.example.com:8080');
// Manual authentication headers
const agent2 = new HttpsProxyAgent('http://proxy.example.com:8080', {
headers: {
'Proxy-Authorization': 'Basic ' + Buffer.from('username:password').toString('base64')
}
});import { HttpsProxyAgent } from 'https-proxy-agent';
// Corporate proxy with authentication
const agent = new HttpsProxyAgent(process.env.HTTPS_PROXY || 'http://proxy.corp.com:8080', {
headers: {
'User-Agent': 'Corporate App v1.0'
}
});import { HttpsProxyAgent } from 'https-proxy-agent';
// Debug proxy for inspecting traffic
const debugAgent = new HttpsProxyAgent('http://localhost:8888', {
headers: () => ({
'X-Debug-Session': Date.now().toString()
})
});import { HttpsProxyAgent } from 'https-proxy-agent';
const proxies = [
'http://proxy1.example.com:8080',
'http://proxy2.example.com:8080',
'http://proxy3.example.com:8080'
];
let currentProxy = 0;
function getAgent() {
const proxyUrl = proxies[currentProxy++ % proxies.length];
return new HttpsProxyAgent(proxyUrl);
}
// Use different proxy for each request
const agent = getAgent();