rssguard/resources/scripts/adblock/adblock-server.js

119 lines
3.6 KiB
JavaScript
Raw Normal View History

2021-05-03 14:14:55 +02:00
// Simple local HTTP server providing ad-blocking functionality via https://github.com/cliqz-oss/adblocker
//
// How to install:
// npm i -g @cliqz/adblocker
// npm i -g concat-stream
2021-05-07 06:56:21 +02:00
// npm i -g tldts-experimental
// npm i -g node-fetch
//
// How to run:
2021-05-03 14:14:55 +02:00
// NODE_PATH="C:\Users\<user>\AppData\Roaming\npm\node_modules" node ./adblock-server.js "<port>" "<filters-file-path>"
//
// How to use:
2021-05-03 14:14:55 +02:00
// curl -i -X POST --data '
// {
// "url": "http://gompoozu.net",
// "url_type": "main_frame",
// "filter": true,
// "cosmetic": true
// }' 'http://localhost:<port>'
const fs = require('fs');
2021-05-07 06:56:21 +02:00
const tldts = require('tldts-experimental');
const adblock = require('@cliqz/adblocker')
const http = require('http');
const concat = require('concat-stream');
const constants = require('node:http2');
const fetch = require("node-fetch");
2021-05-07 06:56:21 +02:00
const cluster = require('cluster');
2021-05-07 06:56:21 +02:00
const numCPUs = require('os').cpus().length;
2021-05-03 14:14:55 +02:00
const port = process.argv[2];
const filtersFile = process.argv[3];
const engine = adblock.FiltersEngine.parse(fs.readFileSync(filtersFile, 'utf-8'));
const hostname = '127.0.0.1';
2021-05-07 06:56:21 +02:00
if (cluster.isPrimary) {
console.log(`Primary ${process.pid} is running`);
2021-05-04 11:40:48 +02:00
2021-05-07 06:56:21 +02:00
// Fork workers.
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.log(`worker ${worker.process.pid} died`);
});
}
else {
const server = http.createServer((req, res) => {
try {
2021-05-04 11:40:48 +02:00
console.log(new Date());
2021-05-07 06:56:21 +02:00
const chunks = [];
req.on('data', chunk => chunks.push(chunk));
req.on('end', () => {
console.log(new Date());
2021-05-07 06:56:21 +02:00
try {
const jsonData = Buffer.concat(chunks);
const jsonStruct = JSON.parse(jsonData.toString());
2021-05-07 06:56:21 +02:00
const askUrl = jsonStruct['url'];
const askFilter = jsonStruct['filter'];
const askCosmetic = jsonStruct['cosmetic'];
const askUrlType = jsonStruct['url_type'];
const fullUrl = new URL(askUrl);
2021-05-07 06:56:21 +02:00
resultJson = {};
2021-05-07 06:56:21 +02:00
if (askFilter) {
const adblockMatch = engine.match(adblock.Request.fromRawDetails({
type: askUrlType,
url: askUrl,
}));
2021-05-07 06:56:21 +02:00
resultJson["filter"] = adblockMatch;
console.log(`adblocker: Filter is:\n${JSON.stringify(adblockMatch)}.`)
}
2021-05-07 06:56:21 +02:00
if (askCosmetic) {
const adblockCosmetic = engine.getCosmeticsFilters({
url: askUrl,
hostname: fullUrl.hostname,
2021-05-09 06:42:31 +02:00
domain: tldts.getDomain(fullUrl.hostname)
2021-05-07 06:56:21 +02:00
});
2021-05-03 14:14:55 +02:00
2021-05-07 06:56:21 +02:00
resultJson["cosmetic"] = adblockCosmetic;
console.log(`adblocker: Cosmetic is:\n${JSON.stringify(adblockCosmetic)}.`)
}
2021-05-04 11:40:48 +02:00
2021-05-07 06:56:21 +02:00
res.statusCode = 200;
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify(resultJson));
2021-05-07 06:56:21 +02:00
console.log(new Date());
}
catch (inner_error) {
console.error(`adblocker: ${inner_error}.`);
2021-05-07 06:56:21 +02:00
res.statusCode = 500;
res.setHeader('Content-Type', 'text/plain');
res.end(String(inner_error));
}
})
}
catch (error) {
console.error(`adblocker: ${inner_error}.`);
res.statusCode = 500;
res.setHeader('Content-Type', 'text/plain');
res.end(String(error));
}
});
server.listen(port, hostname, () => {
console.log(`adblocker: Server started at local port ${port}.`);
});
2021-05-09 06:42:31 +02:00
}