Skip to content

Kaciras/fetch-socks

Repository files navigation

fetch-socks

npm package Test codecov type-coverage

Socks proxy for Node builtin (also undici) fetch.

npm install fetch-socks

Usage Examples

Fetch http://example.com through socks5://[::1]:1080.

import { socksDispatcher } from "fetch-socks";

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.

import { socksDispatcher } from "fetch-socks";

const dispatcher = socksDispatcher({ /* ... */});

global[Symbol.for("undici.globalDispatcher.1")] = dispatcher;

TypeScript example, fetch through proxy chain with two SOCKS proxies.

import { fetch } from "undici";
import { socksDispatcher, SocksProxies } from "fetch-socks";

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.

import { Client, Agent } from "undici";
import { socksConnector } from "fetch-socks";

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 });

API

socksConnector(proxies, connectOptions?)

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 here

socksDispatcher(proxies, options?)

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.
import { socksConnector, socksDispatcher } from "fetch-socks";
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) });