build-cdn-download-conf.worker.ts 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. import path from 'node:path';
  2. import { readFileIntoProcessedArray, fetchRemoteTextByLine } from './lib/fetch-text-by-line';
  3. import { task } from './trace';
  4. import { SHARED_DESCRIPTION } from './constants/description';
  5. import { appendArrayInPlace } from 'foxts/append-array-in-place';
  6. import { SOURCE_DIR } from './constants/dir';
  7. import { DomainsetOutput } from './lib/rules/domainset';
  8. import { CRASHLYTICS_WHITELIST } from './constants/reject-data-source';
  9. import { HostnameTrie } from './lib/trie';
  10. import { $$fetch } from './lib/fetch-retry';
  11. import { fastUri } from 'fast-uri';
  12. const cdnDomainSetPromise = readFileIntoProcessedArray(path.join(SOURCE_DIR, 'domainset/cdn.conf'));
  13. const downloadDomainSetPromise = readFileIntoProcessedArray(path.join(SOURCE_DIR, 'domainset/download.conf'));
  14. const steamDomainSetPromise = readFileIntoProcessedArray(path.join(SOURCE_DIR, 'domainset/game-download.conf'));
  15. export const buildCdnDownloadConf = task(require.main === module, __filename)(async (span) => {
  16. const [
  17. S3OSSDomains,
  18. IPFSDomains,
  19. cdnDomainsList,
  20. downloadDomainSet,
  21. steamDomainSet
  22. ] = await Promise.all([
  23. span.traceChildAsync(
  24. 'download public suffix list for s3',
  25. async () => {
  26. const trie = new HostnameTrie();
  27. for await (const line of await fetchRemoteTextByLine('https://publicsuffix.org/list/public_suffix_list.dat', true)) {
  28. trie.add(line);
  29. }
  30. /**
  31. * Extract OSS domain from publicsuffix list
  32. */
  33. const S3OSSDomains: string[] = [];
  34. trie.find('.amazonaws.com').forEach((line: string) => {
  35. if (
  36. (line.startsWith('s3-') || line.startsWith('s3.'))
  37. && !line.includes('cn-')
  38. ) {
  39. S3OSSDomains.push('.' + line);
  40. }
  41. });
  42. trie.find('.scw.cloud').forEach((line: string) => {
  43. if (
  44. (line.startsWith('s3-') || line.startsWith('s3.'))
  45. // && !line.includes('cn-')
  46. ) {
  47. S3OSSDomains.push('.' + line);
  48. }
  49. });
  50. trie.find('sakurastorage.jp').forEach((line: string) => {
  51. if (
  52. (line.startsWith('s3-') || line.startsWith('s3.'))
  53. ) {
  54. S3OSSDomains.push('.' + line);
  55. }
  56. });
  57. return S3OSSDomains;
  58. }
  59. ),
  60. span.traceChildAsync(
  61. 'load public ipfs gateway list',
  62. async () => {
  63. const data = await (await $$fetch('https://cdn.jsdelivr.net/gh/ipfs/public-gateway-checker@main/gateways.json')).json();
  64. if (!Array.isArray(data)) {
  65. console.error('Invalid IPFS gateway list format');
  66. return [];
  67. }
  68. return data.reduce<string[]>((acc, gateway) => {
  69. if (typeof gateway !== 'string') {
  70. return acc;
  71. }
  72. const hn = fastUri.parse(gateway).host;
  73. if (hn) {
  74. acc.push(hn.trim());
  75. }
  76. return acc;
  77. }, []);
  78. }
  79. ),
  80. cdnDomainSetPromise,
  81. downloadDomainSetPromise,
  82. steamDomainSetPromise
  83. ]);
  84. // Move S3 domains to download domain set, since S3 files may be large
  85. appendArrayInPlace(downloadDomainSet, S3OSSDomains);
  86. appendArrayInPlace(downloadDomainSet, steamDomainSet);
  87. // we have whitelisted the crashlytics domain, and we also want to put it in CDN policy
  88. appendArrayInPlace(cdnDomainsList, CRASHLYTICS_WHITELIST);
  89. return Promise.all([
  90. new DomainsetOutput(span, 'cdn')
  91. .withTitle('Sukka\'s Ruleset - CDN Domains')
  92. .appendDescription(SHARED_DESCRIPTION)
  93. .appendDescription(
  94. '',
  95. 'This file contains object storage and static assets CDN domains.'
  96. )
  97. .addFromDomainset(cdnDomainsList)
  98. .bulkAddDomainSuffix(IPFSDomains)
  99. .write(),
  100. new DomainsetOutput(span, 'download')
  101. .withTitle('Sukka\'s Ruleset - Large Files Hosting Domains')
  102. .appendDescription(SHARED_DESCRIPTION)
  103. .appendDescription(
  104. '',
  105. 'This file contains domains for software updating & large file hosting.'
  106. )
  107. .addFromDomainset(downloadDomainSet)
  108. .write()
  109. ]);
  110. });