validate-domain-alive.ts 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import { readFileByLine } from './lib/fetch-text-by-line';
  2. import { processLine } from './lib/process-line';
  3. import { SOURCE_DIR } from './constants/dir';
  4. import path from 'node:path';
  5. import { newQueue } from '@henrygd/queue';
  6. import { isDomainAlive, keyedAsyncMutexWithQueue } from './lib/is-domain-alive';
  7. import { fdir as Fdir } from 'fdir';
  8. const queue = newQueue(24);
  9. const deadDomains: string[] = [];
  10. function onDomain(args: [string, boolean]) {
  11. if (!args[1]) {
  12. deadDomains.push(args[0]);
  13. }
  14. }
  15. (async () => {
  16. const domainSets = await new Fdir()
  17. .withFullPaths()
  18. .crawl(SOURCE_DIR + path.sep + 'domainset')
  19. .withPromise();
  20. const domainRules = await new Fdir()
  21. .withFullPaths()
  22. .crawl(SOURCE_DIR + path.sep + 'non_ip')
  23. .withPromise();
  24. await Promise.all([
  25. ...domainSets.map(runAgainstDomainset),
  26. ...domainRules.map(runAgainstRuleset)
  27. ]);
  28. console.log();
  29. console.log();
  30. console.log(JSON.stringify(deadDomains));
  31. })();
  32. export async function runAgainstRuleset(filepath: string) {
  33. const extname = path.extname(filepath);
  34. if (extname !== '.conf') {
  35. console.log('[skip]', filepath);
  36. return;
  37. }
  38. const promises: Array<Promise<void>> = [];
  39. for await (const l of readFileByLine(filepath)) {
  40. const line = processLine(l);
  41. if (!line) continue;
  42. const [type, domain] = line.split(',');
  43. switch (type) {
  44. case 'DOMAIN-SUFFIX':
  45. case 'DOMAIN': {
  46. promises.push(
  47. queue.add(() => keyedAsyncMutexWithQueue(domain, () => isDomainAlive(domain, type === 'DOMAIN-SUFFIX')))
  48. .then(onDomain)
  49. );
  50. break;
  51. }
  52. // no default
  53. }
  54. }
  55. await Promise.all(promises);
  56. console.log('[done]', filepath);
  57. }
  58. export async function runAgainstDomainset(filepath: string) {
  59. const extname = path.extname(filepath);
  60. if (extname !== '.conf') {
  61. console.log('[skip]', filepath);
  62. return;
  63. }
  64. const promises: Array<Promise<void>> = [];
  65. for await (const l of readFileByLine(filepath)) {
  66. const line = processLine(l);
  67. if (!line) continue;
  68. promises.push(
  69. queue.add(() => keyedAsyncMutexWithQueue(line, () => isDomainAlive(line, line[0] === '.')))
  70. .then(onDomain)
  71. );
  72. }
  73. await Promise.all(promises);
  74. console.log('[done]', filepath);
  75. }