mirror of
https://github.com/SukkaW/Surge.git
synced 2026-04-30 01:46:57 +08:00
Chore: fix domain alive check DoH [skip ci]
This commit is contained in:
@@ -7,7 +7,6 @@ import undici, {
|
|||||||
} from 'undici';
|
} from 'undici';
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
BodyInit,
|
|
||||||
Dispatcher,
|
Dispatcher,
|
||||||
Response,
|
Response,
|
||||||
RequestInit,
|
RequestInit,
|
||||||
@@ -168,25 +167,7 @@ export const defaultRequestInit = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function $$fetch(input: RequestInfo, init: RequestInit = defaultRequestInit) {
|
export async function $$fetch(url: RequestInfo, init: RequestInit = defaultRequestInit) {
|
||||||
// Workaround for https://github.com/nodejs/undici/issues/2155:
|
|
||||||
// If a Request object from a different undici instance (or Node.js globals) is passed,
|
|
||||||
// undici's internal instanceof check fails and it tries to parse "[object Request]" as a URL.
|
|
||||||
let url: RequestInfo = input;
|
|
||||||
if (typeof input === 'object' && 'url' in input) {
|
|
||||||
// Re-wrap as a proper undici Request so undici's instanceof checks pass.
|
|
||||||
// Headers follow WHATWG fetch spec: init.headers replaces input.headers if present,
|
|
||||||
// otherwise input.headers is used — a plain spread achieves exactly this.
|
|
||||||
url = new UndiciRequest(input.url, {
|
|
||||||
method: input.method,
|
|
||||||
body: input.body as BodyInit,
|
|
||||||
signal: input.signal,
|
|
||||||
headers: input.headers,
|
|
||||||
...init
|
|
||||||
});
|
|
||||||
init = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
init.dispatcher = agent;
|
init.dispatcher = agent;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -204,7 +185,7 @@ export async function $$fetch(input: RequestInfo, init: RequestInit = defaultReq
|
|||||||
if (isAbortErrorLike(err)) {
|
if (isAbortErrorLike(err)) {
|
||||||
console.log(picocolors.gray('[fetch abort]'), url);
|
console.log(picocolors.gray('[fetch abort]'), url);
|
||||||
} else {
|
} else {
|
||||||
console.log(picocolors.gray('[fetch fail]'), url, { name: (err as any).name }, err);
|
console.log(picocolors.gray('[fetch fail]'), url, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw err;
|
throw err;
|
||||||
@@ -213,6 +194,28 @@ export async function $$fetch(input: RequestInfo, init: RequestInit = defaultReq
|
|||||||
|
|
||||||
export { $$fetch as '~fetch' };
|
export { $$fetch as '~fetch' };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A fetch wrapper for DoH (DNS-over-HTTPS) usage where the input may be a
|
||||||
|
* `Request` object created by a different undici instance or Node.js globals.
|
||||||
|
* Without normalisation, undici's internal `instanceof Request` check fails and
|
||||||
|
* it tries to parse `[object Request]` as a URL.
|
||||||
|
* See https://github.com/nodejs/undici/issues/2155
|
||||||
|
*/
|
||||||
|
export async function fetchForDoH(input: RequestInfo, init?: RequestInit) {
|
||||||
|
if (typeof input === 'object' && 'url' in input) {
|
||||||
|
// Normalise the foreign Request into a proper undici Request, preserving all
|
||||||
|
// of its properties. init is passed separately so undici merges them itself,
|
||||||
|
// exactly as real fetch(request, init) would — no manual header handling needed.
|
||||||
|
input = new UndiciRequest(input.url, {
|
||||||
|
...input,
|
||||||
|
// force no-referrer to avoid about:client
|
||||||
|
referrerPolicy: 'no-referrer',
|
||||||
|
referrer: ''
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return $$fetch(input, init);
|
||||||
|
}
|
||||||
|
|
||||||
/** @deprecated -- undici.requests doesn't support gzip/br/deflate, and has difficulty w/ undidi cache */
|
/** @deprecated -- undici.requests doesn't support gzip/br/deflate, and has difficulty w/ undidi cache */
|
||||||
export async function requestWithLog(url: string, opt?: Parameters<typeof undici.request>[1]) {
|
export async function requestWithLog(url: string, opt?: Parameters<typeof undici.request>[1]) {
|
||||||
opt ??= {};
|
opt ??= {};
|
||||||
@@ -233,7 +236,7 @@ export async function requestWithLog(url: string, opt?: Parameters<typeof undici
|
|||||||
if (isAbortErrorLike(err)) {
|
if (isAbortErrorLike(err)) {
|
||||||
console.log(picocolors.gray('[fetch abort]'), url);
|
console.log(picocolors.gray('[fetch abort]'), url);
|
||||||
} else {
|
} else {
|
||||||
console.log(picocolors.gray('[fetch fail]'), url, { name: (err as any).name }, err);
|
console.log(picocolors.gray('[fetch fail]'), url, { name: err instanceof Error ? err.name : undefined }, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw err;
|
throw err;
|
||||||
|
|||||||
@@ -1,25 +1,25 @@
|
|||||||
import { createDomainAliveChecker, createRegisterableDomainAliveChecker } from 'domain-alive';
|
import { createDomainAliveChecker, createRegisterableDomainAliveChecker } from 'domain-alive';
|
||||||
import { $$fetch } from './fetch-retry';
|
import { $$fetch, fetchForDoH } from './fetch-retry';
|
||||||
|
|
||||||
const dnsServers = [
|
const dnsServers = [
|
||||||
'h2://8.8.8.8/dns-query', 'h2://8.8.4.4/dns-query',
|
'https://8.8.8.8/dns-query', 'https://8.8.4.4/dns-query',
|
||||||
'h2://1.0.0.1/dns-query', 'h2://1.1.1.1/dns-query',
|
'https://1.0.0.1/dns-query', 'https://1.1.1.1/dns-query',
|
||||||
'h2://162.159.36.1/dns-query', 'h2://162.159.46.1/dns-query',
|
'https://162.159.36.1/dns-query', 'https://162.159.46.1/dns-query',
|
||||||
'h2://dns.cloudflare.com/dns-query', // Cloudflare DoH that uses different IPs: 172.64.41.8,162.159.61.8
|
'https://dns.cloudflare.com/dns-query', // Cloudflare DoH that uses different IPs: 172.64.41.8,162.159.61.8
|
||||||
'h2://cloudflare-dns.com/dns-query', // Cloudflare DoH that uses different IPs: 104.16.249.249,104.16.248.249
|
'https://cloudflare-dns.com/dns-query', // Cloudflare DoH that uses different IPs: 104.16.249.249,104.16.248.249
|
||||||
'h2://mozilla.cloudflare-dns.com/dns-query', // Cloudflare DoH that uses different IPs: 162.159.61.4,172.64.41.4
|
'https://mozilla.cloudflare-dns.com/dns-query', // Cloudflare DoH that uses different IPs: 162.159.61.4,172.64.41.4
|
||||||
// one.one.one.one // Cloudflare DoH that uses 1.1.1.1 and 1.0.0.1
|
// one.one.one.one // Cloudflare DoH that uses 1.1.1.1 and 1.0.0.1
|
||||||
// 'https://101.101.101.101/dns-query', 'https://dns.twnic.tw/dns-query' // TWNIC, has DNS pollution, e.g. t66y.com
|
// 'https://101.101.101.101/dns-query', 'https://dns.twnic.tw/dns-query' // TWNIC, has DNS pollution, e.g. t66y.com
|
||||||
// 'https://dns.hinet.net/dns-query' // HiNet DoH, has DNS pollution, e.g. t66y.com
|
// 'https://dns.hinet.net/dns-query' // HiNet DoH, has DNS pollution, e.g. t66y.com
|
||||||
'h2://185.222.222.222/dns-query', 'h2://45.11.45.11/dns-query', // DNS.SB
|
'https://185.222.222.222/dns-query', 'https://45.11.45.11/dns-query', // DNS.SB
|
||||||
// 'https://doh.dns.sb/dns-query', // DNS.SB, Unicast PoPs w/ GeoDNS
|
// 'https://doh.dns.sb/dns-query', // DNS.SB, Unicast PoPs w/ GeoDNS
|
||||||
'h2://us-chi.doh.sb/dns-query', // DNS.SB Chicago PoP
|
'https://us-chi.doh.sb/dns-query', // DNS.SB Chicago PoP
|
||||||
'h2://us-nyc.doh.sb/dns-query', // DNS.SB New York City PoP
|
'https://us-nyc.doh.sb/dns-query', // DNS.SB New York City PoP
|
||||||
'h2://us-sjc.doh.sb/dns-query', // DNS.SB San Jose PoP
|
'https://us-sjc.doh.sb/dns-query', // DNS.SB San Jose PoP
|
||||||
// 'https://doh.sb/dns-query', // DNS.SB xTom Anycast IP
|
// 'https://doh.sb/dns-query', // DNS.SB xTom Anycast IP
|
||||||
// 'https://dns.sb/dns-query', // DNS.SB use same xTom Anycast IP as doh.sb
|
// 'https://dns.sb/dns-query', // DNS.SB use same xTom Anycast IP as doh.sb
|
||||||
// 'https://dns10.quad9.net/dns-query', // Quad9 unfiltered
|
// 'https://dns10.quad9.net/dns-query', // Quad9 unfiltered
|
||||||
'h2://9.9.9.10/dns-query', 'h2://149.112.112.10/dns-query', // Quad9 unfiltered
|
'https://9.9.9.10/dns-query', 'https://149.112.112.10/dns-query', // Quad9 unfiltered
|
||||||
|
|
||||||
// OpenDNS sandbox (unfiltered), doesn't support HTTP/2 properly
|
// OpenDNS sandbox (unfiltered), doesn't support HTTP/2 properly
|
||||||
// Error: Session closed without receiving a SETTINGS frame
|
// Error: Session closed without receiving a SETTINGS frame
|
||||||
@@ -28,28 +28,28 @@ const dnsServers = [
|
|||||||
// curl: (16) Error in the HTTP2 framing layer
|
// curl: (16) Error in the HTTP2 framing layer
|
||||||
'https://doh.sandbox.opendns.com/dns-query',
|
'https://doh.sandbox.opendns.com/dns-query',
|
||||||
|
|
||||||
'h2://unfiltered.adguard-dns.com/dns-query', // AdGuard unfiltered
|
'https://unfiltered.adguard-dns.com/dns-query', // AdGuard unfiltered
|
||||||
// 'https://v.recipes/dns-query', // Proxy Cloudflare, too many HTTP 503
|
// 'https://v.recipes/dns-query', // Proxy Cloudflare, too many HTTP 503
|
||||||
'h2://v.recipes/dns/dns.google/dns-query', // Proxy Google, claims to not limited by Google 1500 QPS limit
|
'https://v.recipes/dns/dns.google/dns-query', // Proxy Google, claims to not limited by Google 1500 QPS limit
|
||||||
'h2://freedns.controld.com/p0', // ControlD unfiltered
|
'https://freedns.controld.com/p0', // ControlD unfiltered
|
||||||
// 'h2://dns.bebasid.com/unfiltered', // BebasID, cause loads of RangeError: Attempt to access memory outside buffer bounds, possibly caused by timeout
|
// 'https://dns.bebasid.com/unfiltered', // BebasID, cause loads of RangeError: Attempt to access memory outside buffer bounds, possibly caused by timeout
|
||||||
// 'https://193.110.81.0/dns-query', // dns0.eu
|
// 'https://193.110.81.0/dns-query', // dns0.eu
|
||||||
// 'https://185.253.5.0/dns-query', // dns0.eu
|
// 'https://185.253.5.0/dns-query', // dns0.eu
|
||||||
// 'https://zero.dns0.eu/dns-query',
|
// 'https://zero.dns0.eu/dns-query',
|
||||||
'h2://dns.nextdns.io/dns-query',
|
'https://dns.nextdns.io/dns-query',
|
||||||
'h2://anycast.dns.nextdns.io/dns-query',
|
'https://anycast.dns.nextdns.io/dns-query',
|
||||||
'h2://wikimedia-dns.org/dns-query',
|
'https://wikimedia-dns.org/dns-query',
|
||||||
// 'https://ordns.he.net/dns-query',
|
// 'https://ordns.he.net/dns-query',
|
||||||
// 'https://dns.mullvad.net/dns-query', empty HTTP body a lot
|
// 'https://dns.mullvad.net/dns-query', empty HTTP body a lot
|
||||||
'h2://basic.rethinkdns.com/dns-query',
|
'https://basic.rethinkdns.com/dns-query',
|
||||||
'h2://dns.surfsharkdns.com/dns-query',
|
'https://dns.surfsharkdns.com/dns-query',
|
||||||
'h2://private.canadianshield.cira.ca/dns-query',
|
'https://private.canadianshield.cira.ca/dns-query',
|
||||||
// 'https://unfiltered.joindns4.eu/dns-query', // too many ECONNRESET on GitHub Actions
|
// 'https://unfiltered.joindns4.eu/dns-query', // too many ECONNRESET on GitHub Actions
|
||||||
'h2://public.dns.iij.jp/dns-query',
|
'https://public.dns.iij.jp/dns-query',
|
||||||
// 'https://common.dot.dns.yandex.net/dns-query', // too many ECONNRESET on GitHub Actions
|
// 'https://common.dot.dns.yandex.net/dns-query', // too many ECONNRESET on GitHub Actions
|
||||||
'h2://safeservedns.com/dns-query' // NameCheap DNS, supports DoT, DoH, UDP53
|
'https://safeservedns.com/dns-query' // NameCheap DNS, supports DoT, DoH, UDP53
|
||||||
// 'https://ada.openbld.net/dns-query', Contains filtering
|
// 'https://ada.openbld.net/dns-query', Contains filtering
|
||||||
// 'h2://dns.rabbitdns.org/dns-query' -- TO MANY HTTP 522
|
// 'https://dns.rabbitdns.org/dns-query' -- TO MANY HTTP 522
|
||||||
];
|
];
|
||||||
|
|
||||||
const resultCache = new Map();
|
const resultCache = new Map();
|
||||||
@@ -61,7 +61,8 @@ export async function getMethods() {
|
|||||||
const isRegisterableDomainAlive = createRegisterableDomainAliveChecker({
|
const isRegisterableDomainAlive = createRegisterableDomainAliveChecker({
|
||||||
dns: {
|
dns: {
|
||||||
dnsServers,
|
dnsServers,
|
||||||
maxAttempts: 6
|
maxAttempts: 6,
|
||||||
|
customFetchForDoH: fetchForDoH as typeof fetch
|
||||||
},
|
},
|
||||||
registerableDomainResultCache,
|
registerableDomainResultCache,
|
||||||
whois: {
|
whois: {
|
||||||
@@ -73,7 +74,7 @@ export async function getMethods() {
|
|||||||
dns: {
|
dns: {
|
||||||
dnsServers,
|
dnsServers,
|
||||||
maxAttempts: 6,
|
maxAttempts: 6,
|
||||||
customFetchForDoH: $$fetch as typeof fetch
|
customFetchForDoH: fetchForDoH as typeof fetch
|
||||||
},
|
},
|
||||||
registerableDomainResultCache,
|
registerableDomainResultCache,
|
||||||
resultCache,
|
resultCache,
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
"ci-info": "^4.4.0",
|
"ci-info": "^4.4.0",
|
||||||
"cli-progress": "^3.12.0",
|
"cli-progress": "^3.12.0",
|
||||||
"csv-parse": "^6.2.1",
|
"csv-parse": "^6.2.1",
|
||||||
"domain-alive": "^0.1.20",
|
"domain-alive": "^0.1.22",
|
||||||
"fast-cidr-tools": "^0.3.4",
|
"fast-cidr-tools": "^0.3.4",
|
||||||
"fast-escape-regexp": "^1.0.1",
|
"fast-escape-regexp": "^1.0.1",
|
||||||
"fast-uri": "^3.1.0",
|
"fast-uri": "^3.1.0",
|
||||||
|
|||||||
10
pnpm-lock.yaml
generated
10
pnpm-lock.yaml
generated
@@ -33,8 +33,8 @@ importers:
|
|||||||
specifier: ^6.2.1
|
specifier: ^6.2.1
|
||||||
version: 6.2.1
|
version: 6.2.1
|
||||||
domain-alive:
|
domain-alive:
|
||||||
specifier: ^0.1.20
|
specifier: ^0.1.22
|
||||||
version: 0.1.20
|
version: 0.1.22
|
||||||
fast-cidr-tools:
|
fast-cidr-tools:
|
||||||
specifier: ^0.3.4
|
specifier: ^0.3.4
|
||||||
version: 0.3.4
|
version: 0.3.4
|
||||||
@@ -1090,8 +1090,8 @@ packages:
|
|||||||
dom-serializer@1.4.1:
|
dom-serializer@1.4.1:
|
||||||
resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==}
|
resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==}
|
||||||
|
|
||||||
domain-alive@0.1.20:
|
domain-alive@0.1.22:
|
||||||
resolution: {integrity: sha512-2GdRUDUJVEesfdA39W6bSznACEhm6V0qYWyxRedGg/Sr6WSFh7x6nYrix0GQ/+ZFQwhIdjRNn5mszm4OBqZkiQ==}
|
resolution: {integrity: sha512-jmGCN6EOuLs7BwitNEUVhqF5tTFGvFtXAhhANbKR60tLCCWNuER72+YSiSCsO8OVXgXV1jL/zQ6RyrBUPmogaA==}
|
||||||
|
|
||||||
domelementtype@2.3.0:
|
domelementtype@2.3.0:
|
||||||
resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==}
|
resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==}
|
||||||
@@ -2850,7 +2850,7 @@ snapshots:
|
|||||||
domhandler: 4.3.1
|
domhandler: 4.3.1
|
||||||
entities: 2.2.0
|
entities: 2.2.0
|
||||||
|
|
||||||
domain-alive@0.1.20:
|
domain-alive@0.1.22:
|
||||||
dependencies:
|
dependencies:
|
||||||
debug: 4.4.1
|
debug: 4.4.1
|
||||||
foxts: 5.4.0
|
foxts: 5.4.0
|
||||||
|
|||||||
Reference in New Issue
Block a user