Socks proxy for Node builtin `fetch` (fork with bw monitoring addition)
npm install fetch-socks-bw> Fork Notice: This is a fork of the excellent fetch-socks by Kaciras. All credit for the original implementation goes to the original author.
>
> This fork adds bandwidth monitoring capabilities as an experiment using AI-assisted development. While this is experimental "AI slop", I'm publishing it on npm as fetch-socks-bw because I need these features for production use. I chose not to contribute back to the original repository due to the experimental nature and AI-heavy development of these additions.

Socks proxy for Node builtin (also undici) fetch with bandwidth monitoring.
``shell`
npm install fetch-socks-bw
Fetch http://example.com through socks5://[::1]:1080.
`javascript
import { socksDispatcher } from "fetch-socks-bw";
const dispatcher = socksDispatcher({
type: 5,
host: "::1",
port: 1080,
//userId: "username",
//password: "password",
});
const response = await fetch("http://example.com", { dispatcher });
console.log(response.status);
console.log(await response.text());
`
Set the proxy globally.
`javascript
import { socksDispatcher } from "fetch-socks-bw";
const dispatcher = socksDispatcher({ / ... /});
global[Symbol.for("undici.globalDispatcher.1")] = dispatcher;
``
TypeScript example, fetch through proxy chain with two SOCKS proxies.
`typescript
import { fetch } from "undici";
import { socksDispatcher, SocksProxies } from "fetch-socks-bw";
const proxyConfig: SocksProxies = [{
type: 5,
host: "::1",
port: 1080,
}, {
type: 5,
host: "127.0.0.1",
port: 1081,
}];
const dispatcher = socksDispatcher(proxyConfig, {
connect: {
// set some TLS options
rejectUnauthorized: false,
},
});
const response = await fetch("https://example.com", { dispatcher });
`
create a socks connection over HTTP tunnel with socksConnector.
`javascript
import { Client, Agent } from "undici";
import { socksConnector } from "fetch-socks-bw";
const socksConnect = socksConnector({
type: 5,
host: "::1",
port: 1080,
});
async function connect(options, callback) {
// First establish a connection to the HTTP proxy server (localhost:80).
const client = new Client("http://localhost:80");
const { socket, statusCode } = await client.connect({
// Tell the server to connect to the next ([::1]:1080)
path: "[::1]:1080",
});
if (statusCode !== 200) {
callback(new Error("Proxy response !== 200 when HTTP Tunneling"));
} else {
// Perform socks handshake on the connection.
socksConnect({ ...options, httpSocket: socket }, callback);
}
}
const dispatcher = new Agent({ connect });
const response = await fetch("https://example.com", { dispatcher });
`
Track bandwidth usage through SOCKS proxies.
`javascript
import { socksDispatcher, getStatsForDomain, getAllStats, getGlobalStats, resetStats } from "fetch-socks-bw";
const dispatcher = socksDispatcher({
type: 5,
host: "::1",
port: 1080,
}, {
connect: { enableStats: true }
});
// Make some requests
await fetch("https://example.com", { dispatcher });
await fetch("https://api.github.com/users", { dispatcher });
await fetch("https://example.com/api", { dispatcher });
// Get stats for a specific domain
const exampleStats = getStatsForDomain("example.com");
console.log(exampleStats); // { sent: 442, received: 2048 }
// Get stats for all domains
const allStats = getAllStats();
console.log(allStats);
// {
// "example.com": { sent: 442, received: 2048 },
// "api.github.com": { sent: 203, received: 1337 }
// }
// Get global totals
const globalStats = getGlobalStats();
console.log(globalStats); // { sent: 645, received: 3385 }
// Reset all stats
resetStats();
console.log(getAllStats()); // {}
`
Create an Undici connector which establish the connection through socks proxies.
* proxies The proxy server to use or the list of proxy servers to chain. If you pass an empty array it will connect directly.connectOptions
* (optional) The options used to perform directly connect or TLS upgrade, see hereenableStats
* (optional) Enable bandwidth monitoring. Default: false
Create a Undici Agent with socks connector.
* proxies Same as socksConnector's.options
* (optional) Agent options. The connect property will be used to create socks connector.connect.enableStats
* (optional) Enable bandwidth monitoring. Default: false
`javascript
import { socksConnector, socksDispatcher } from "fetch-socks-bw";
import { Agent } from "undici";
const proxy = { type: 5, host: "::1", port: 1080 };
const connect = { / ... / };
const agentOptions = { / ... / };
socksDispatcher(proxy, { ...agentOptions, connect });
// Is equivalent to
new Agent({ ...agentOptions, connect: socksConnector(proxy, connect) });
`
Get byte statistics for a specific domain. Returns { sent: number, received: number } or undefined.
* domain The domain name to get statistics for.
Get byte statistics for all domains. Returns an object with domain names as keys and { sent, received } as values.
Get total bytes sent and received across all domains. Returns { sent: number, received: number }.
Clear all byte statistics.