Speed up probe option

main
Elbert Alias 4 years ago
parent 967785c339
commit 44f7a3eae1

@ -460,7 +460,8 @@ class Site {
promiseTimeout( promiseTimeout(
promise, promise,
fallback, fallback,
errorMessage = 'Operation took too long to respond' errorMessage = 'Operation took too long to respond',
maxWait = this.options.maxWait
) { ) {
let timeout = null let timeout = null
@ -478,7 +479,7 @@ class Site {
error.code = 'PROMISE_TIMEOUT_ERROR' error.code = 'PROMISE_TIMEOUT_ERROR'
fallback !== undefined ? resolve(fallback) : reject(error) fallback !== undefined ? resolve(fallback) : reject(error)
}, this.options.maxWait) }, maxWait)
}), }),
promise.then((value) => { promise.then((value) => {
clearTimeout(timeout) clearTimeout(timeout)
@ -890,17 +891,26 @@ class Site {
await sleep(this.options.delay * index) await sleep(this.options.delay * index)
} }
const links = await this.goto(url) await Promise.all([
(async () => {
if (links && this.options.recursive && depth < this.options.maxDepth) { const links = await this.goto(url)
await this.batch(links.slice(0, this.options.maxUrls), depth + 1)
}
if (this.options.probe && !this.probed) { if (
this.probed = true links &&
this.options.recursive &&
depth < this.options.maxDepth
) {
await this.batch(links.slice(0, this.options.maxUrls), depth + 1)
}
})(),
(async () => {
if (this.options.probe && !this.probed) {
this.probed = true
await this.probe(url) await this.probe(url)
} }
})(),
])
} catch (error) { } catch (error) {
this.analyzedUrls[url.href] = { this.analyzedUrls[url.href] = {
status: 0, status: 0,
@ -950,31 +960,9 @@ class Site {
magento: '/magento_version', magento: '/magento_version',
} }
for (const file of Object.keys(files)) {
const path = files[file]
try {
await sleep(this.options.delay)
const body = await get(new URL(path, url.href), {
userAgent: this.options.userAgent,
timeout: Math.min(this.options.maxWait, 3000),
})
this.log(`get ${path}: ok`)
await this.onDetect(
url,
await analyze({ [file]: body.slice(0, 100000) })
)
} catch (error) {
this.error(`get ${path}: ${error.message || error}`)
}
}
// DNS // DNS
const records = {} const records = {}
const resolve = (func, hostname) => { const resolveDns = (func, hostname) => {
return this.promiseTimeout( return this.promiseTimeout(
func(hostname).catch((error) => { func(hostname).catch((error) => {
if (error.code !== 'ENODATA') { if (error.code !== 'ENODATA') {
@ -984,39 +972,74 @@ class Site {
return [] return []
}), }),
[], [],
'Timeout (dns)' 'Timeout (dns)',
Math.min(this.options.maxWait, 15000)
) )
} }
const domain = url.hostname.replace(/^www\./, '') const domain = url.hostname.replace(/^www\./, '')
;[records.cname, records.ns, records.mx, records.txt, records.soa] = await Promise.all([
await Promise.all([ // Static files
resolve(dns.resolveCname, url.hostname), ...Object.keys(files).map(async (file, index) => {
resolve(dns.resolveNs, domain), const path = files[file]
resolve(dns.resolveMx, domain),
resolve(dns.resolveTxt, domain),
resolve(dns.resolveSoa, domain),
])
const dnsRecords = Object.keys(records).reduce((dns, type) => { try {
dns[type] = dns[type] || [] await sleep(this.options.delay * index)
Array.prototype.push.apply( const body = await get(new URL(path, url.href), {
dns[type], userAgent: this.options.userAgent,
Array.isArray(records[type]) timeout: Math.min(this.options.maxWait, 3000),
? records[type].map((value) => { })
return typeof value === 'object'
? Object.values(value).join(' ') this.log(`Probe ok (${path})`)
: value
}) await this.onDetect(
: [Object.values(records[type]).join(' ')] url,
) await analyze({ [file]: body.slice(0, 100000) })
)
} catch (error) {
this.error(`Probe failed (${path}): ${error.message || error}`)
}
}),
// DNS
// eslint-disable-next-line no-async-promise-executor
new Promise(async (resolve, reject) => {
;[records.cname, records.ns, records.mx, records.txt, records.soa] =
await Promise.all([
resolveDns(dns.resolveCname, url.hostname),
resolveDns(dns.resolveNs, domain),
resolveDns(dns.resolveMx, domain),
resolveDns(dns.resolveTxt, domain),
resolveDns(dns.resolveSoa, domain),
])
const dnsRecords = Object.keys(records).reduce((dns, type) => {
dns[type] = dns[type] || []
Array.prototype.push.apply(
dns[type],
Array.isArray(records[type])
? records[type].map((value) => {
return typeof value === 'object'
? Object.values(value).join(' ')
: value
})
: [Object.values(records[type]).join(' ')]
)
return dns return dns
}, {}) }, {})
await this.onDetect(url, await analyze({ dns: dnsRecords })) this.log(
`Probe DNS ok: (${Object.values(dnsRecords).flat().length} records)`
)
await this.onDetect(url, await analyze({ dns: dnsRecords }))
resolve()
}),
])
} }
async batch(links, depth, batch = 0) { async batch(links, depth, batch = 0) {