build-microsoft-cdn.ts 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  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. import { sortDomains } from './lib/stable-sort-domain';
  10. const PROBE_DOMAINS = ['.microsoft.com', '.windows.net', '.windows.com', '.windowsupdate.com', '.windowssearch.com', '.office.net'];
  11. const WHITELIST = [
  12. 'DOMAIN-SUFFIX,download.prss.microsoft.com',
  13. 'DOMAIN,res.cdn.office.net'
  14. ];
  15. const BLACKLIST = [
  16. 'www.microsoft.com',
  17. 'learn.microsoft.com',
  18. 'devblogs.microsoft.com',
  19. 'docs.microsoft.com',
  20. 'developer.microsoft.com',
  21. 'windowsupdate.com'
  22. ];
  23. export const getMicrosoftCdnRulesetPromise = createMemoizedPromise(async () => {
  24. // First trie is to find the microsoft domains that matches probe domains
  25. const trie = createTrie(null, true);
  26. for await (const line of await fetchRemoteTextByLine('https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/accelerated-domains.china.conf')) {
  27. const domain = extractDomainsFromFelixDnsmasq(line);
  28. if (domain) {
  29. trie.add(domain);
  30. }
  31. }
  32. const foundMicrosoftCdnDomains = PROBE_DOMAINS.flatMap(domain => trie.find(domain));
  33. // Second trie is to remove blacklisted domains
  34. const trie2 = createTrie(foundMicrosoftCdnDomains, true, true);
  35. BLACKLIST.forEach(trie2.whitelist);
  36. return sortDomains(trie2.dump())
  37. .map(d => `DOMAIN-SUFFIX,${d}`)
  38. .concat(WHITELIST);
  39. });
  40. export const buildMicrosoftCdn = task(import.meta.path, async (span) => {
  41. const description = [
  42. ...SHARED_DESCRIPTION,
  43. '',
  44. 'This file contains Microsoft\'s domains using their China mainland CDN servers.',
  45. '',
  46. 'Data from:',
  47. ' - https://github.com/felixonmars/dnsmasq-china-list'
  48. ];
  49. const res: string[] = await span.traceChildPromise('get microsoft cdn domains', getMicrosoftCdnRulesetPromise());
  50. return createRuleset(
  51. span,
  52. 'Sukka\'s Ruleset - Microsoft CDN',
  53. description,
  54. new Date(),
  55. res,
  56. 'ruleset',
  57. path.resolve(import.meta.dir, '../List/non_ip/microsoft_cdn.conf'),
  58. path.resolve(import.meta.dir, '../Clash/non_ip/microsoft_cdn.txt')
  59. );
  60. });
  61. if (import.meta.main) {
  62. buildMicrosoftCdn();
  63. }