build-microsoft-cdn.ts 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import path from 'path';
  2. import { task } from './trace';
  3. import { createRuleset } from './lib/create-file';
  4. import { fetchRemoteTextByLine } from './lib/fetch-text-by-line';
  5. import { createTrie } from './lib/trie';
  6. import { SHARED_DESCRIPTION } from './lib/constants';
  7. import { createMemoizedPromise } from './lib/memo-promise';
  8. import { extractDomainsFromFelixDnsmasq } from './lib/parse-dnsmasq';
  9. const PROBE_DOMAINS = ['.microsoft.com', '.windows.net', '.windows.com', '.windowsupdate.com', '.windowssearch.com', '.office.net'];
  10. const WHITELIST = [
  11. 'DOMAIN-SUFFIX,download.prss.microsoft.com',
  12. 'DOMAIN,res.cdn.office.net'
  13. ];
  14. const BLACKLIST = [
  15. 'www.microsoft.com',
  16. 'learn.microsoft.com',
  17. 'devblogs.microsoft.com',
  18. 'docs.microsoft.com',
  19. 'developer.microsoft.com',
  20. 'windowsupdate.com'
  21. ];
  22. export const getMicrosoftCdnRulesetPromise = createMemoizedPromise(async () => {
  23. // First trie is to find the microsoft domains that matches probe domains
  24. const trie = createTrie();
  25. for await (const line of await fetchRemoteTextByLine('https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/accelerated-domains.china.conf')) {
  26. const domain = extractDomainsFromFelixDnsmasq(line);
  27. if (domain) {
  28. trie.add(domain);
  29. }
  30. }
  31. const set = new Set(PROBE_DOMAINS.flatMap(domain => trie.find(domain)));
  32. // Second trie is to remove blacklisted domains
  33. const trie2 = createTrie(set);
  34. BLACKLIST.forEach(black => {
  35. trie2.substractSetInPlaceFromFound(black, set);
  36. });
  37. return Array.from(set).map(d => `DOMAIN-SUFFIX,${d}`).concat(WHITELIST);
  38. });
  39. export const buildMicrosoftCdn = task(import.meta.path, async (span) => {
  40. const description = [
  41. ...SHARED_DESCRIPTION,
  42. '',
  43. 'This file contains Microsoft\'s domains using their China mainland CDN servers.',
  44. '',
  45. 'Data from:',
  46. ' - https://github.com/felixonmars/dnsmasq-china-list'
  47. ];
  48. const promise = getMicrosoftCdnRulesetPromise();
  49. const peeked = Bun.peek(promise);
  50. const res: string[] = peeked === promise
  51. ? await span.traceChildPromise('get microsoft cdn domains', promise)
  52. : (peeked as string[]);
  53. return createRuleset(
  54. span,
  55. 'Sukka\'s Ruleset - Microsoft CDN',
  56. description,
  57. new Date(),
  58. res,
  59. 'ruleset',
  60. path.resolve(import.meta.dir, '../List/non_ip/microsoft_cdn.conf'),
  61. path.resolve(import.meta.dir, '../Clash/non_ip/microsoft_cdn.txt')
  62. );
  63. });
  64. if (import.meta.main) {
  65. buildMicrosoftCdn();
  66. }