From 3993c02c65091f2f2149b917ff66ce48c7fc19a5 Mon Sep 17 00:00:00 2001 From: Rekryt Date: Fri, 20 Dec 2024 12:49:14 +0300 Subject: [PATCH] feat: add net PAC format --- README.en.md | 27 +++++----- README.md | 27 +++++----- src/App/Controller/PacController.php | 74 ++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 26 deletions(-) create mode 100644 src/App/Controller/PacController.php diff --git a/README.en.md b/README.en.md index 4a4a60c..8746b74 100644 --- a/README.en.md +++ b/README.en.md @@ -18,19 +18,20 @@ Demo URL: [https://iplist.opencck.org](https://iplist.opencck.org) - **whois, ipcalc (Linux utilities)** # Formats of Output -| format | description | -|----------|-----------------------| -| json | JSON format | -| text | Newline-separated | -| comma | Comma-separated | -| mikrotik | MikroTik Script | -| switchy | SwitchyOmega RuleList | -| nfset | Dnsmasq nfset | -| ipset | Dnsmasq ipset | -| clashx | ClashX | -| kvas | Keenetic KVAS | -| bat | Keenetic Routes .bat | -| amnezia | Amnezia filter list | +| format | description | +|----------|-------------------------------| +| json | JSON format | +| text | Newline-separated | +| comma | Comma-separated | +| mikrotik | MikroTik Script | +| switchy | SwitchyOmega RuleList | +| nfset | Dnsmasq nfset | +| ipset | Dnsmasq ipset | +| clashx | ClashX | +| kvas | Keenetic KVAS | +| bat | Keenetic Routes .bat | +| amnezia | Amnezia filter list | +| pac | Proxy Auto-Configuration file | ## Configuration diff --git a/README.md b/README.md index f622532..bc6f25e 100644 --- a/README.md +++ b/README.md @@ -22,19 +22,20 @@ Demo URL: [https://iplist.opencck.org](https://iplist.opencck.org) - whois, ipcalc (linux) # Форматы выгрузки -| формат | описание | -|----------|--------------------------| -| json | JSON формат | -| text | Разделение новой строкой | -| comma | Разделение запятыми | -| mikrotik | MikroTik Script | -| switchy | SwitchyOmega RuleList | -| nfset | Dnsmasq nfset | -| ipset | Dnsmasq ipset | -| clashx | ClashX | -| kvas | Keenetic KVAS | -| bat | Keenetic Routes .bat | -| amnezia | Amnezia filter list | +| формат | описание | +|----------|-------------------------------| +| json | JSON формат | +| text | Разделение новой строкой | +| comma | Разделение запятыми | +| mikrotik | MikroTik Script | +| switchy | SwitchyOmega RuleList | +| nfset | Dnsmasq nfset | +| ipset | Dnsmasq ipset | +| clashx | ClashX | +| kvas | Keenetic KVAS | +| bat | Keenetic Routes .bat | +| amnezia | Amnezia filter list | +| pac | Proxy Auto-Configuration file | ## Настройки Конфигурационные файлы хранятся в `config/<группа>/<портал>.json`. Каждый JSON файл представляет собой конфигурацию для конкретного портала, задавая домены для мониторинга и источники начальных данных по IP и CIDR. diff --git a/src/App/Controller/PacController.php b/src/App/Controller/PacController.php new file mode 100644 index 0000000..061c4fe --- /dev/null +++ b/src/App/Controller/PacController.php @@ -0,0 +1,74 @@ +setHeaders(['content-type' => 'text/javascript']); + + $sites = SiteFactory::normalizeArray($this->request->getQueryParameters()['site'] ?? []); + $data = $this->request->getQueryParameter('data') ?? ''; + $template = $this->request->getQueryParameter('template') ?? 'PROXY 127.0.0.1:2080; DIRECT'; + if (!in_array($data, ['domains', 'cidr4'])) { + return "# Error: The 'data' GET parameter is must be 'domains' or 'cidr4'"; + } + + $items = []; + if (count($sites)) { + foreach ($sites as $site) { + $items = array_merge($items, $this->getSites()[$site]->$data); + } + } else { + foreach ($this->getSites() as $siteEntity) { + $items = array_merge($items, $siteEntity->$data); + } + } + + $response = ['const items = [']; + $response[] = implode( + ",\n", + $data == 'cidr4' + ? array_map(function (string $item) { + $parts = explode('/', $item); + $mask = IP4Helper::formatShortIpMask($parts[1] ?? ''); + return '["' . $parts[0] . '","' . $mask . '"]'; + }, SiteFactory::normalizeArray($items, true)) + : array_map(fn(string $item) => '"' . $item . '"', SiteFactory::normalizeArray($items)) + ); + $response[] = '];'; + + if ($data == 'cidr4') { + $response = array_merge($response, [ + 'function FindProxyForURL(url, host) {', + ' for (cidr of items) {', + ' if (isInNet(host, cidr[0], cidr[1])) {', + ' return "' . $template . '";', + ' }', + ' }', + '', + ' return "DIRECT";', + '}', + ]); + } else { + $response = array_merge($response, [ + 'function FindProxyForURL(url, host) {', + ' for (domain of items) {', + ' if (host === domain || shExpMatch(host, "*." + domain)) {', + ' return "' . $template . '";', + ' }', + ' }', + '', + ' return "DIRECT";', + '}', + ]); + } + + return implode("\n", $response); + } +}