dns-over-http-resolver
Advanced tools
Comparing version 2.0.2 to 2.1.0
import type { DNSJSON } from './utils'; | ||
export interface Request { | ||
(resource: string): Promise<DNSJSON>; | ||
(resource: string, signal: AbortSignal): Promise<DNSJSON>; | ||
} | ||
@@ -18,2 +18,3 @@ interface ResolverOptions { | ||
private readonly _request; | ||
private _abortControllers; | ||
/** | ||
@@ -27,2 +28,7 @@ * @class | ||
/** | ||
* Cancel all outstanding DNS queries made by this resolver. Any outstanding | ||
* requests will be aborted and promises rejected. | ||
*/ | ||
cancel(): void; | ||
/** | ||
* Get an array of the IP addresses currently configured for DNS resolution. | ||
@@ -29,0 +35,0 @@ * These addresses are formatted according to RFC 5952. It can include a custom port. |
@@ -26,4 +26,12 @@ import debug from 'debug'; | ||
this._request = options.request ?? utils.request; | ||
this._abortControllers = []; | ||
} | ||
/** | ||
* Cancel all outstanding DNS queries made by this resolver. Any outstanding | ||
* requests will be aborted and promises rejected. | ||
*/ | ||
cancel() { | ||
this._abortControllers.forEach(controller => controller.abort()); | ||
} | ||
/** | ||
* Get an array of the IP addresses currently configured for DNS resolution. | ||
@@ -86,5 +94,8 @@ * These addresses are formatted according to RFC 5952. It can include a custom port. | ||
} | ||
let aborted = false; | ||
for (const server of this._getShuffledServers()) { | ||
const controller = new AbortController(); | ||
this._abortControllers.push(controller); | ||
try { | ||
const response = await this._request(utils.buildResource(server, hostname, recordType)); | ||
const response = await this._request(utils.buildResource(server, hostname, recordType), controller.signal); | ||
const data = response.Answer.map(a => a.data); | ||
@@ -96,5 +107,16 @@ const ttl = Math.min(...response.Answer.map(a => a.TTL)); | ||
catch (err) { | ||
if (controller.signal.aborted) { | ||
aborted = true; | ||
} | ||
log.error(`${server} could not resolve ${hostname} record ${recordType}`); | ||
} | ||
finally { | ||
this._abortControllers = this._abortControllers.filter(c => c !== controller); | ||
} | ||
} | ||
if (aborted) { | ||
throw Object.assign(new Error('queryA ECANCELLED'), { | ||
code: 'ECANCELLED' | ||
}); | ||
} | ||
throw new Error(`Could not resolve ${hostname} record ${recordType}`); | ||
@@ -113,5 +135,8 @@ } | ||
} | ||
let aborted = false; | ||
for (const server of this._getShuffledServers()) { | ||
const controller = new AbortController(); | ||
this._abortControllers.push(controller); | ||
try { | ||
const response = await this._request(utils.buildResource(server, hostname, recordType)); | ||
const response = await this._request(utils.buildResource(server, hostname, recordType), controller.signal); | ||
const data = response.Answer.map(a => a.data); | ||
@@ -123,5 +148,16 @@ const ttl = Math.min(...response.Answer.map(a => a.TTL)); | ||
catch (err) { | ||
if (controller.signal.aborted) { | ||
aborted = true; | ||
} | ||
log.error(`${server} could not resolve ${hostname} record ${recordType}`); | ||
} | ||
finally { | ||
this._abortControllers = this._abortControllers.filter(c => c !== controller); | ||
} | ||
} | ||
if (aborted) { | ||
throw Object.assign(new Error('queryAaaa ECANCELLED'), { | ||
code: 'ECANCELLED' | ||
}); | ||
} | ||
throw new Error(`Could not resolve ${hostname} record ${recordType}`); | ||
@@ -140,5 +176,8 @@ } | ||
} | ||
let aborted = false; | ||
for (const server of this._getShuffledServers()) { | ||
const controller = new AbortController(); | ||
this._abortControllers.push(controller); | ||
try { | ||
const response = await this._request(utils.buildResource(server, hostname, recordType)); | ||
const response = await this._request(utils.buildResource(server, hostname, recordType), controller.signal); | ||
const data = response.Answer.map(a => [a.data.replace(/['"]+/g, '')]); | ||
@@ -150,5 +189,16 @@ const ttl = Math.min(...response.Answer.map(a => a.TTL)); | ||
catch (err) { | ||
if (controller.signal.aborted) { | ||
aborted = true; | ||
} | ||
log.error(`${server} could not resolve ${hostname} record ${recordType}`); | ||
} | ||
finally { | ||
this._abortControllers = this._abortControllers.filter(c => c !== controller); | ||
} | ||
} | ||
if (aborted) { | ||
throw Object.assign(new Error('queryTxt ECANCELLED'), { | ||
code: 'ECANCELLED' | ||
}); | ||
} | ||
throw new Error(`Could not resolve ${hostname} record ${recordType}`); | ||
@@ -155,0 +205,0 @@ } |
@@ -22,3 +22,3 @@ /** | ||
*/ | ||
export declare function request(resource: string): Promise<DNSJSON>; | ||
export declare function request(resource: string, signal: AbortSignal): Promise<DNSJSON>; | ||
/** | ||
@@ -25,0 +25,0 @@ * Creates cache key composed by recordType and hostname |
@@ -11,7 +11,8 @@ import { fetch as nativeFetch, Headers } from 'native-fetch'; | ||
*/ | ||
export async function request(resource) { | ||
export async function request(resource, signal) { | ||
const req = await nativeFetch(resource, { | ||
headers: new Headers({ | ||
accept: 'application/dns-json' | ||
}) | ||
}), | ||
signal | ||
}); | ||
@@ -18,0 +19,0 @@ const res = await req.json(); |
{ | ||
"name": "dns-over-http-resolver", | ||
"version": "2.0.2", | ||
"version": "2.1.0", | ||
"description": "DNS over HTTP resolver", | ||
@@ -147,3 +147,3 @@ "author": "Vasco Santos", | ||
"aegir": "^37.4.4", | ||
"sinon": "^13.0.0", | ||
"sinon": "^14.0.0", | ||
"ts-sinon": "^2.0.2", | ||
@@ -150,0 +150,0 @@ "util": "^0.12.3" |
@@ -10,3 +10,3 @@ import debug from 'debug' | ||
export interface Request { (resource: string): Promise<DNSJSON> } | ||
export interface Request { (resource: string, signal: AbortSignal): Promise<DNSJSON> } | ||
@@ -27,2 +27,3 @@ interface ResolverOptions { | ||
private readonly _request: Request | ||
private _abortControllers: AbortController[] | ||
@@ -43,5 +44,14 @@ /** | ||
this._request = options.request ?? utils.request | ||
this._abortControllers = [] | ||
} | ||
/** | ||
* Cancel all outstanding DNS queries made by this resolver. Any outstanding | ||
* requests will be aborted and promises rejected. | ||
*/ | ||
cancel () { | ||
this._abortControllers.forEach(controller => controller.abort()) | ||
} | ||
/** | ||
* Get an array of the IP addresses currently configured for DNS resolution. | ||
@@ -110,4 +120,8 @@ * These addresses are formatted according to RFC 5952. It can include a custom port. | ||
} | ||
let aborted = false | ||
for (const server of this._getShuffledServers()) { | ||
const controller = new AbortController() | ||
this._abortControllers.push(controller) | ||
try { | ||
@@ -118,3 +132,3 @@ const response = await this._request(utils.buildResource( | ||
recordType | ||
)) | ||
), controller.signal) | ||
@@ -128,6 +142,18 @@ const data = response.Answer.map(a => a.data) | ||
} catch (err) { | ||
if (controller.signal.aborted) { | ||
aborted = true | ||
} | ||
log.error(`${server} could not resolve ${hostname} record ${recordType}`) | ||
} finally { | ||
this._abortControllers = this._abortControllers.filter(c => c !== controller) | ||
} | ||
} | ||
if (aborted) { | ||
throw Object.assign(new Error('queryA ECANCELLED'), { | ||
code: 'ECANCELLED' | ||
}) | ||
} | ||
throw new Error(`Could not resolve ${hostname} record ${recordType}`) | ||
@@ -147,4 +173,8 @@ } | ||
} | ||
let aborted = false | ||
for (const server of this._getShuffledServers()) { | ||
const controller = new AbortController() | ||
this._abortControllers.push(controller) | ||
try { | ||
@@ -155,3 +185,3 @@ const response = await this._request(utils.buildResource( | ||
recordType | ||
)) | ||
), controller.signal) | ||
@@ -165,6 +195,18 @@ const data = response.Answer.map(a => a.data) | ||
} catch (err) { | ||
if (controller.signal.aborted) { | ||
aborted = true | ||
} | ||
log.error(`${server} could not resolve ${hostname} record ${recordType}`) | ||
} finally { | ||
this._abortControllers = this._abortControllers.filter(c => c !== controller) | ||
} | ||
} | ||
if (aborted) { | ||
throw Object.assign(new Error('queryAaaa ECANCELLED'), { | ||
code: 'ECANCELLED' | ||
}) | ||
} | ||
throw new Error(`Could not resolve ${hostname} record ${recordType}`) | ||
@@ -184,4 +226,8 @@ } | ||
} | ||
let aborted = false | ||
for (const server of this._getShuffledServers()) { | ||
const controller = new AbortController() | ||
this._abortControllers.push(controller) | ||
try { | ||
@@ -192,3 +238,3 @@ const response = await this._request(utils.buildResource( | ||
recordType | ||
)) | ||
), controller.signal) | ||
@@ -202,6 +248,18 @@ const data = response.Answer.map(a => [a.data.replace(/['"]+/g, '')]) | ||
} catch (err) { | ||
if (controller.signal.aborted) { | ||
aborted = true | ||
} | ||
log.error(`${server} could not resolve ${hostname} record ${recordType}`) | ||
} finally { | ||
this._abortControllers = this._abortControllers.filter(c => c !== controller) | ||
} | ||
} | ||
if (aborted) { | ||
throw Object.assign(new Error('queryTxt ECANCELLED'), { | ||
code: 'ECANCELLED' | ||
}) | ||
} | ||
throw new Error(`Could not resolve ${hostname} record ${recordType}`) | ||
@@ -208,0 +266,0 @@ } |
@@ -30,7 +30,8 @@ import { fetch as nativeFetch, Headers } from 'native-fetch' | ||
*/ | ||
export async function request (resource: string) { | ||
export async function request (resource: string, signal: AbortSignal) { | ||
const req = await nativeFetch(resource, { | ||
headers: new Headers({ | ||
accept: 'application/dns-json' | ||
}) | ||
}), | ||
signal | ||
}) | ||
@@ -37,0 +38,0 @@ const res = await req.json() |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
39826
601