Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/kaciras/pac-maker
Proxy Auto-Configuration (PAC) file generator & loader, support proxy Node's `fetch` with PAC.
https://github.com/kaciras/pac-maker
fetch gfwlist pac proxy
Last synced: 5 days ago
JSON representation
Proxy Auto-Configuration (PAC) file generator & loader, support proxy Node's `fetch` with PAC.
- Host: GitHub
- URL: https://github.com/kaciras/pac-maker
- Owner: Kaciras
- License: mit
- Created: 2021-05-12T14:23:54.000Z (over 3 years ago)
- Default Branch: master
- Last Pushed: 2024-09-14T12:18:06.000Z (4 months ago)
- Last Synced: 2024-09-14T22:35:22.958Z (4 months ago)
- Topics: fetch, gfwlist, pac, proxy
- Language: TypeScript
- Homepage:
- Size: 4.75 MB
- Stars: 20
- Watchers: 4
- Forks: 6
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# pac-maker
[![npm package](https://img.shields.io/npm/v/pac-maker.svg?style=flat-square)](https://npmjs.com/package/pac-maker)
![node-current](https://img.shields.io/node/v/pac-maker?style=flat-square)
[![Test](https://img.shields.io/github/actions/workflow/status/Kaciras/pac-maker/test.yml?style=flat-square)](https://github.com/Kaciras/pac-maker/actions/workflows/test.yml)
[![codecov](https://img.shields.io/codecov/c/github/Kaciras/pac-maker?style=flat-square)](https://codecov.io/gh/Kaciras/pac-maker)[Proxy Auto Configuration (PAC)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Proxy_servers_and_tunneling/Proxy_Auto-Configuration_PAC_file)
file generator & maintenance tool.Features:
* [Generate PAC files from various hostname sources](#generate-pac-files).
* [Load a PAC file in Node](#loadpac).
* [Serve the PAC with http and watch for source change](#serve).
* [Show what hosts in your browser history will be proxied by the PAC](#analyze).
* [Proxy Node's `fetch` with PAC](#pacdispatcher)# Usage
## PAC files
Pre-generated PAC files at `/dist` can be used to bypass GFW:
* [blacklist.pac](https://raw.githubusercontent.com/Kaciras/pac-maker/master/dist/blacklist.pac) forward GFW blocked hostnames to the proxy server, other hostnames will connect directly.
* [whitelist.pac](https://raw.githubusercontent.com/Kaciras/pac-maker/master/dist/whitelist.pac) forward all but China hostnames to the proxy server.By default, the proxy is `SOCKS5 localhost:2080`, you can change the value to your proxy server address.
Performance:
| file | Load time (ms) | Memory usage (MB) | FindProxyForURL (μs/op) |
|--------------------------------------------------------|----------------|-------------------|-------------------------|
| blacklist.pac | 3.53 | 0.65 | 0.74 |
| whitelist.pac | 35.72 | 6.06 | 1.77 |
| [gfwlist2pac](https://github.com/petronny/gfwlist2pac) | 4.22 | 0.20 | 3355.43 |## Install
This package is pure ESM, it cannot be `require()`'d from CommonJS.
```shell
npm install pac-maker
```## Generate PAC files
pac-maker loads config file from working directory, default is `pac.config.js`, it can be specified by `--config=`
.config file should export a configuration object:
```javascript
import { builtinList, gfwlist, ofArray } from "pac-maker";export default {
/**
* Location of the generated PAC file, default is "proxy.pac".
*/
path: "proxy.pac",/**
* Fallback route when no rule matching in `sources`, default is "DIRECT".
*/
fallback: "DIRECT",/**
* Proxy source map, the key is a proxy sorting, value is an array of HostnameSource.
* pac-maker will get hostnames from all sources and route them to the corresponding key.
*/
sources: {
"SOCKS5 localhost:2080": [
gfwlist(),
builtinList("default"),
builtinList("forbidden"),
ofArray(["google.com"]),
],
},
};
```There are some built-in sources in pac-maker:
* `gfwlist` Fetch hostnames from [gfwlist](https://github.com/gfwlist/gfwlist).
* `hostnameFile` Read hostnames from a file, for hostname file example, see
the [list](https://github.com/Kaciras/pac-maker/tree/master/list) directory.* `builtinList` Read hostnames from a file in the [list](https://github.com/Kaciras/pac-maker/tree/master/list)
directory.* `ofArray` Just use an array of hostnames.
## CLI commands
### `generate`
Generate a PAC file:
```shell
pac-maker generate [--config=] [--watch]
```* `--watch` After the initial build, pac-maker will continue to watch for updates in any of the sources.
### `analyze`
Find what hosts will be proxied by the PAC in browser history, support Chrome, Firefox, and Edge:
```shell
pac-maker analyze [--config=] [--json=]
```* `--json` Save matched rules to this file, default is `matches.json`.
### `bench`
Benchmark PAC files, show load time, memory usage, and `FindProxyForURL` performance.
```shell
pac-maker bench [morefiles...] [--host=example.com] [--loadCount=] [--workCount=]
```* `--host` The `host` parameter passed to `FindProxyForURL`, default is "www.google.com".
* `--iterations` Time or the number of load iterations to platform, default is "1s".### `serve`
Serve the PAC file with http, and update when source have changes:
```shell
pac-maker serve [--config=] [--host=] [--port=]
```* `--host` By default, the server will accept connections from all addresses, It is possible to listen to just one
selected interface using the `host` parameter.* `--port` The port number that http server to listened on, default is `7568`.
## JavaScript API
pac-maker exports some useful functions that allows you to play with PAC inside your own JavaScript program.
### `PACDispatcher`
The [undici](https://github.com/nodejs/undici) dispatcher that dispatch requests based on rule described by the PAC.
It is designed to be used with the built-in `fetch` function. To proxy the requests with the `http` module, we recommend to use [node-pac-proxy-agent](https://github.com/TooTallNate/node-pac-proxy-agent).
```javascript
import { readFileSync } from "fs";
import { PACDispatcher } from "pac-maker";const pac = readFileSync("proxy.pac", "utf8");
const dispatcher = new PACDispatcher(pac);const response = await fetch("https://example.com", { dispatcher });
```### `buildPAC`
Create a PAC script from rules, use the built-in template `template/default.js`.
The function takes two parameters, first is a rules object which key is
a [proxy string](https://developer.mozilla.org/en-US/docs/Web/HTTP/Proxy_servers_and_tunneling/Proxy_Auto-Configuration_PAC_file#return_value_format)
, and value is a hostname array. the second parameter will be returned from `FindProxyForURL` if no hostname matched,
default is `DIRECT`.```javascript
import { writeFileSync } from "fs";
import { buildPAC } from "pac-maker";const rules = {
"HTTP 192.168.0.1:80": ["foo.com", "bar.com"],
"SOCKS5 localhost:1080": ["example.com"],
};writeFileSync("proxy.pac", buildPAC(rules));
```### `loadPAC`
Load and execute a PAC script, return an object includes all global variables defined in the PAC.
```javascript
import { readFileSync } from "fs";
import { loadPAC } from "pac-maker";const pac = loadPAC(readFileSync("proxy.pac", "utf8"));
console.log(pac.FindProxyForURL("", "example.com"));
```### `parseProxies`
Parse the return value of `FindProxyForURL()`.
```javascript
import { parseProxies } from "pac-maker";console.log(parseProxies("HTTP localhost:80; DIRECT"));
```output:
```
[
{ protocol: "HTTP", host: "localhost:80", port: 80, hostname: "localhost" },
{ protocol: "DIRECT", host: "", port: NaN, hostname: "" }
]
```### `HostBlockVerifier`
A tool to check which hostnames are blocked by your ISP.
This class is only support HTTP protocol, it cannot be used for hosts running non-HTTP services.
```javascript
import { HostBlockVerifier } from "pac-maker";const hosts = ["google.com", "github.com" /* ... */];
const verifier = new HostBlockVerifier("SOCKS5 localhost:1080");
(await verifier.verifyAll(hosts)).print();
```Test a single hostname and return block type:
```javascript
const reason = await verifier.verify("google.com");
if (reason === "DNS") {
console.log("DNS cache pollution");
} else if (reason === "TCP") {
console.log("TCP blocking");
} else if (reason === "Unavailable") {
console.log("Site may be down");
} else {
console.log("The host is not blocked");
}
```### `commands`
All commands supported by `pac-maker` can also be called in JavaScript code.
```javascript
import { commands } from "pac-maker";
import config from "./pac.config.js";commands.serve({ host: "localhost", port: 12345 }, config);
```## Run Tests
To run unit tests, you need to enable experimental vm modules.
```shell
NODE_OPTIONS=--experimental-vm-modules
pnpm test
```