diff --git a/README.md b/README.md index b364d0a..5f181c1 100644 --- a/README.md +++ b/README.md @@ -39,8 +39,8 @@ function FindProxyForURL(url, host) } ``` -Start server with `PROXY` variable +Start server with `PAC_PROXY` variable ```sh -PROXY=pac+file://proxy.pac +PAC_PROXY=file://$(pwd)/proxy.pac node . ``` diff --git a/package.json b/package.json index fd4e4c0..b78deda 100644 --- a/package.json +++ b/package.json @@ -30,8 +30,8 @@ "koa-static": "^5.0.0", "mime": "^4.0.4", "nostr-tools": "^2.7.2", + "pac-proxy-agent": "^7.0.2", "proxy-agent": "^6.4.0", - "proxy-from-env": "^1.1.0", "websocket-polyfill": "^1.0.0", "ws": "^8.18.0", "xbytes": "^1.9.1" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5af7ce5..2c0e9cd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -47,12 +47,12 @@ importers: nostr-tools: specifier: ^2.7.2 version: 2.7.2(typescript@5.6.2) + pac-proxy-agent: + specifier: ^7.0.2 + version: 7.0.2 proxy-agent: specifier: ^6.4.0 version: 6.4.0 - proxy-from-env: - specifier: ^1.1.0 - version: 1.1.0 websocket-polyfill: specifier: 1.0.0 version: 1.0.0 diff --git a/src/env.ts b/src/env.ts index 9f6e3ed..3c0fa45 100644 --- a/src/env.ts +++ b/src/env.ts @@ -13,4 +13,18 @@ const MAX_FILE_SIZE = process.env.MAX_FILE_SIZE ? xbytes.parseSize(process.env.M const NGINX_CACHE_DIR = process.env.NGINX_CACHE_DIR; const CACHE_PATH = process.env.CACHE_PATH; -export { SUBSCRIPTION_RELAYS, LOOKUP_RELAYS, BLOSSOM_SERVERS, MAX_FILE_SIZE, NGINX_CACHE_DIR, CACHE_PATH }; +const PAC_PROXY = process.env.PAC_PROXY; +const TOR_PROXY = process.env.TOR_PROXY; +const I2P_PROXY = process.env.I2P_PROXY; + +export { + SUBSCRIPTION_RELAYS, + LOOKUP_RELAYS, + BLOSSOM_SERVERS, + MAX_FILE_SIZE, + NGINX_CACHE_DIR, + CACHE_PATH, + PAC_PROXY, + TOR_PROXY, + I2P_PROXY, +}; diff --git a/src/proxy.ts b/src/proxy.ts index 34fc05d..ce3e6cf 100644 --- a/src/proxy.ts +++ b/src/proxy.ts @@ -1,13 +1,57 @@ import { ProxyAgent } from "proxy-agent"; -import { getProxyForUrl } from "proxy-from-env"; +import { PacProxyAgent } from "pac-proxy-agent"; +import { I2P_PROXY, PAC_PROXY, TOR_PROXY } from "./env.js"; -const agent = new ProxyAgent({ keepAlive: true }); +function buildPacURI() { + const statements: string[] = []; -if (getProxyForUrl("http://example.onion")) { - console.log("Tor connections enabled"); + if (I2P_PROXY) { + statements.push( + ` +if (shExpMatch(host, "*.i2p")) +{ +return "SOCKS5 ${I2P_PROXY}"; } -if (getProxyForUrl("http://example.i2p")) { - console.log("I2P connections enabled"); +`.trim(), + ); + } + + if (TOR_PROXY) { + statements.push( + ` +if (shExpMatch(host, "*.onion")) +{ +return "SOCKS5 ${TOR_PROXY}"; } +`.trim(), + ); + } + + statements.push('return "DIRECT";'); + + const PACFile = ` +// SPDX-License-Identifier: CC0-1.0 + +function FindProxyForURL(url, host) +{ +${statements.join("\n")} +} +`.trim(); + + return "pac+data:application/x-ns-proxy-autoconfig;base64," + btoa(PACFile); +} +function buildProxy() { + if (PAC_PROXY) { + console.log(`Using PAC proxy file`); + return new PacProxyAgent(PAC_PROXY); + } else if (TOR_PROXY || I2P_PROXY) { + if (TOR_PROXY) console.log("Tor connection enabled"); + if (I2P_PROXY) console.log("I2P connection enabled"); + + return new PacProxyAgent(buildPacURI()); + } else return new ProxyAgent({ keepAlive: true }); +} + +const agent = buildProxy(); export default agent;