cURL Adapter
The cURL adapter is Rezo’s most protocol-diverse adapter. At 3,355 lines, it wraps the curl command-line tool with full programmatic control over 200+ options. It supports HTTP versions from 1.0 through 3.0, 20+ authentication methods, multi-protocol transfers (FTP, SSH, SMTP, TFTP), DNS-over-HTTPS, and comprehensive TLS/SSL configuration.
import rezo from 'rezo/adapters/curl'; Import and Setup
import rezo, {
Rezo,
RezoError,
RezoHeaders,
RezoFormData,
RezoCookieJar
} from 'rezo/adapters/curl';
// Default instance
const { data } = await rezo.get('https://api.example.com/users');
// Custom instance with cURL-specific options
const client = new Rezo({
baseURL: 'https://api.example.com',
timeout: 30000
}); Capabilities Detection
Before executing requests, the adapter uses the CurlCapabilities singleton to detect the installed cURL version, supported features, and available protocols:
import { CurlCapabilities } from 'rezo/adapters/curl';
const caps = CurlCapabilities.getInstance();
await caps.initialize();
// Check if cURL is available and what it supports
console.log(caps.getVersion()); // "8.7.1"
console.log(caps.hasFeature('HTTP2')); // true
console.log(caps.hasFeature('HTTP3')); // true
console.log(caps.hasProtocol('ftps')); // true
console.log(caps.hasProtocol('sftp')); // true The capabilities check runs curl --version once and parses the output to determine available features and protocols. If cURL is not installed, the adapter throws a helpful error with platform-specific installation instructions (Homebrew on macOS, apt on Debian, dnf on Red Hat, pacman on Arch, etc.).
HTTP Protocol Versions
The cURL adapter supports all HTTP versions:
// HTTP/1.0
const { data } = await rezo.get('https://example.com', {
curl: { httpVersion: '1.0' }
});
// HTTP/1.1 (default)
const { data } = await rezo.get('https://example.com', {
curl: { httpVersion: '1.1' }
});
// HTTP/2
const { data } = await rezo.get('https://example.com', {
curl: { httpVersion: '2' }
});
// HTTP/2 with prior knowledge (skip upgrade)
const { data } = await rezo.get('https://example.com', {
curl: { httpVersion: '2-prior-knowledge' }
});
// HTTP/3 (QUIC)
const { data } = await rezo.get('https://example.com', {
curl: { httpVersion: '3' }
}); Authentication Methods
The adapter supports a wide range of authentication methods through cURL’s built-in auth handling:
Basic and Digest
// Basic authentication
const { data } = await rezo.get('https://api.example.com/protected', {
auth: {
type: 'basic',
username: 'admin',
password: 'secret'
}
});
// Digest authentication
const { data } = await rezo.get('https://api.example.com/protected', {
auth: {
type: 'digest',
username: 'admin',
password: 'secret'
}
}); NTLM
const { data } = await rezo.get('https://intranet.company.com/resource', {
auth: {
type: 'ntlm',
username: 'DOMAIN\user',
password: 'password'
}
}); Bearer Token
const { data } = await rezo.get('https://api.example.com/data', {
auth: {
type: 'bearer',
token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
}
}); AWS Signature V4
const { data } = await rezo.get('https://s3.amazonaws.com/my-bucket/file.txt', {
curl: {
awsSigv4: {
provider: 'aws',
region: 'us-east-1',
service: 's3'
}
},
auth: {
username: 'AKIAIOSFODNN7EXAMPLE',
password: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY'
}
}); Negotiate (Kerberos/SPNEGO)
const { data } = await rezo.get('https://internal-api.company.com', {
curl: {
negotiate: true,
delegation: 'always',
serviceName: 'HTTP'
}
}); Custom Auth Headers
const { data } = await rezo.get('https://api.example.com/data', {
auth: {
type: 'custom',
custom: {
'X-API-Key': 'my-api-key',
'X-Signature': 'hmac-sha256-signature'
}
}
}); TLS/SSL Configuration
Comprehensive TLS control for enterprise environments:
// Client certificate authentication
const { data } = await rezo.get('https://mtls-api.example.com/data', {
curl: {
tls: {
cert: '/path/to/client.pem',
key: '/path/to/client-key.pem',
cacert: '/path/to/ca-bundle.crt',
certType: 'PEM',
keyType: 'PEM'
}
}
});
// Specific TLS version
const { data } = await rezo.get('https://example.com', {
curl: {
tls: {
tlsVersion: 'tlsv1.3',
ciphers: 'TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256'
}
}
});
// Skip certificate verification (development only)
const { data } = await rezo.get('https://self-signed.example.com', {
rejectUnauthorized: false
}); Proxy TLS
Separate TLS configuration for the proxy connection:
const { data } = await rezo.get('https://example.com', {
proxy: 'https://proxy.company.com:8443',
curl: {
proxyTls: {
proxyCacert: '/path/to/proxy-ca.crt',
proxyCert: '/path/to/proxy-client.pem',
proxyKey: '/path/to/proxy-client-key.pem'
}
}
}); Proxy Support
All proxy types supported by cURL:
// HTTP proxy
const { data } = await rezo.get('https://example.com', {
proxy: { protocol: 'http', host: 'proxy.example.com', port: 8080 }
});
// HTTPS proxy
const { data } = await rezo.get('https://example.com', {
proxy: { protocol: 'https', host: 'proxy.example.com', port: 8443 }
});
// SOCKS5 proxy
const { data } = await rezo.get('https://example.com', {
proxy: { protocol: 'socks5', host: '127.0.0.1', port: 1080 }
});
// SOCKS5 with hostname resolution at proxy
const { data } = await rezo.get('https://example.com', {
proxy: { protocol: 'socks5h', host: '127.0.0.1', port: 1080 }
}); DNS Options
Custom DNS resolution, including DNS-over-HTTPS (DoH):
// DNS-over-HTTPS
const { data } = await rezo.get('https://example.com', {
curl: {
dns: {
dohUrl: 'https://cloudflare-dns.com/dns-query'
}
}
});
// Custom DNS servers
const { data } = await rezo.get('https://example.com', {
curl: {
dns: {
servers: '8.8.8.8,8.8.4.4'
}
}
});
// DNS interface binding
const { data } = await rezo.get('https://example.com', {
curl: {
dns: {
interface: 'eth0'
}
}
}); FTP Support
Full FTP/FTPS support with directory operations:
// Download a file via FTP
const { data } = await rezo.get('ftp://ftp.example.com/pub/file.txt', {
auth: { username: 'user', password: 'pass' },
curl: {
ftp: {
pasv: true, // passive mode
createDirs: true, // create remote directories
method: 'multicwd' // directory traversal method
}
}
});
// Upload a file via FTP
await rezo.put('ftp://ftp.example.com/uploads/report.csv', fileData, {
auth: { username: 'user', password: 'pass' },
curl: {
ftp: {
createDirs: true
}
}
}); SSH/SFTP Support
// SFTP download with key authentication
const { data } = await rezo.get('sftp://server.example.com/path/to/file.txt', {
curl: {
ssh: {
privateKey: '/home/user/.ssh/id_rsa',
publicKey: '/home/user/.ssh/id_rsa.pub',
knownHosts: '/home/user/.ssh/known_hosts'
}
}
});
// SCP transfer
const { data } = await rezo.get('scp://server.example.com/var/log/app.log', {
curl: {
ssh: {
privateKey: '/home/user/.ssh/id_ed25519',
compressedSsh: true
}
}
}); SMTP Support
Send emails directly through cURL:
await rezo.post('smtp://mail.example.com:587', emailBody, {
curl: {
smtp: {
mailFrom: 'sender@example.com',
mailRcpt: ['recipient@example.com', 'cc@example.com'],
auth: true
}
},
auth: {
username: 'sender@example.com',
password: 'app-password'
}
}); Progress Tracking
Upload and download progress via hooks:
const client = new Rezo({
hooks: {
onDownloadProgress: [({ loaded, total, percent }) => {
console.log(`Download: ${percent.toFixed(1)}%`);
}],
onUploadProgress: [({ loaded, total, percent }) => {
console.log(`Upload: ${percent.toFixed(1)}%`);
}]
}
});
await client.download('https://example.com/large-file.tar.gz', './file.tar.gz'); Timing Metrics
cURL provides detailed timing information for each request phase:
const response = await rezo.get('https://example.com', {
debug: true
});
// Available timing data from cURL's write-out:
// - DNS lookup time
// - TCP connect time
// - TLS handshake time
// - Time to first byte (TTFB)
// - Total transfer time
// - Redirect time Cookie Jar
The cURL adapter supports Rezo’s cookie jar:
const jar = new RezoCookieJar();
const client = new Rezo({ jar });
await client.post('https://example.com/login', {
username: 'admin',
password: 'secret'
});
// Subsequent requests include session cookies
const { data } = await client.get('https://example.com/dashboard'); Streaming
const response = await rezo.stream('https://example.com/live-feed');
for await (const chunk of response.data) {
process.stdout.write(chunk);
} Retry and Redirect
const { data } = await rezo.get('https://example.com/data', {
retry: { limit: 3, statusCodes: [502, 503] },
maxRedirects: 10
}); Response Caching
const client = new Rezo({
cache: { maxAge: 60000, maxEntries: 500 }
}); Builder and Executor Classes
Internally, the adapter is structured around two exported classes:
CurlCommandBuilder— Translates Rezo configuration into cURL command-line arguments. Handles the 200+ options, temp file management for request bodies and certificates, and argument escaping.CurlExecutor— Spawns thecurlchild process, parses stdout/stderr, extracts response headers and body, tracks progress, and maps cURL exit codes toRezoErrorinstances.
import { CurlCommandBuilder, CurlExecutor, CurlCapabilities } from 'rezo/adapters/curl';
// These are available for advanced use cases like:
// - Building cURL commands without executing them
// - Custom execution environments
// - Testing and mocking Debug Mode
const { data } = await rezo.get('https://api.example.com/users', {
debug: true
});
// [Rezo Debug] GET https://api.example.com/users
// [Rezo Debug] Request ID: req_abc123
// [Rezo Debug] cURL command: curl -X GET "https://api.example.com/users" ...
// [Rezo Debug] Response: 200 OK (234.12ms) When to Use This Adapter
The cURL adapter is the right choice when:
- You need protocols beyond HTTP (FTP, SFTP, SCP, SMTP, TFTP)
- You need HTTP/3 (QUIC) support
- You need advanced TLS options (specific ciphers, client certificates, proxy TLS)
- You want DNS-over-HTTPS
- You need NTLM or Kerberos/Negotiate authentication
- You need AWS Signature V4 signing without an SDK
- You are building a debugging or testing tool and want cURL-level control
- You want to leverage cURL features not available in Node.js’s http module
The tradeoff is that the cURL adapter spawns a child process for each request, which has higher overhead than the HTTP adapter or HTTP/2 adapter. For high-throughput scenarios, prefer the native Node.js adapters.