Skip to content

Commit 5aaff53

Browse files
fix(dns): fixed lookup function decorator to work properly in node v20; (#6011)
1 parent a48a63a commit 5aaff53

File tree

5 files changed

+90
-21
lines changed

5 files changed

+90
-21
lines changed

index.d.cts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,15 @@ declare namespace axios {
361361

362362
type AxiosAdapterConfig = AxiosAdapter | AxiosAdapterName;
363363

364+
type AddressFamily = 4 | 6 | undefined;
365+
366+
interface LookupAddressEntry {
367+
address: string;
368+
family?: AddressFamily;
369+
}
370+
371+
type LookupAddress = string | LookupAddressEntry;
372+
364373
interface AxiosRequestConfig<D = any> {
365374
url?: string;
366375
method?: Method | string;
@@ -402,9 +411,9 @@ declare namespace axios {
402411
FormData?: new (...args: any[]) => object;
403412
};
404413
formSerializer?: FormSerializerOptions;
405-
family?: 4 | 6 | undefined;
406-
lookup?: ((hostname: string, options: object, cb: (err: Error | null, address: string, family: number) => void) => void) |
407-
((hostname: string, options: object) => Promise<[address: string, family: number] | string>);
414+
family?: AddressFamily;
415+
lookup?: ((hostname: string, options: object, cb: (err: Error | null, address: LookupAddress | LookupAddress[], family?: AddressFamily) => void) => void) |
416+
((hostname: string, options: object) => Promise<[address: LookupAddressEntry | LookupAddressEntry[], family?: AddressFamily] | LookupAddress>);
408417
}
409418

410419
// Alias

index.d.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,15 @@ type AxiosAdapterName = 'xhr' | 'http' | string;
302302

303303
type AxiosAdapterConfig = AxiosAdapter | AxiosAdapterName;
304304

305+
export type AddressFamily = 4 | 6 | undefined;
306+
307+
export interface LookupAddressEntry {
308+
address: string;
309+
family?: AddressFamily;
310+
}
311+
312+
export type LookupAddress = string | LookupAddressEntry;
313+
305314
export interface AxiosRequestConfig<D = any> {
306315
url?: string;
307316
method?: Method | string;
@@ -343,9 +352,9 @@ export interface AxiosRequestConfig<D = any> {
343352
FormData?: new (...args: any[]) => object;
344353
};
345354
formSerializer?: FormSerializerOptions;
346-
family?: 4 | 6 | undefined;
347-
lookup?: ((hostname: string, options: object, cb: (err: Error | null, address: string, family: number) => void) => void) |
348-
((hostname: string, options: object) => Promise<[address: string, family: number] | string>);
355+
family?: AddressFamily;
356+
lookup?: ((hostname: string, options: object, cb: (err: Error | null, address: LookupAddress | LookupAddress[], family?: AddressFamily) => void) => void) |
357+
((hostname: string, options: object) => Promise<[address: LookupAddressEntry | LookupAddressEntry[], family?: AddressFamily] | LookupAddress>);
349358
}
350359

351360
// Alias

lib/adapters/http.js

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,18 @@ const wrapAsync = (asyncExecutor) => {
144144
})
145145
};
146146

147+
const resolveFamily = ({address, family}) => {
148+
if (!utils.isString(address)) {
149+
throw TypeError('address must be a string');
150+
}
151+
return ({
152+
address,
153+
family: family || (address.indexOf('.') < 0 ? 6 : 4)
154+
});
155+
}
156+
157+
const buildAddressEntry = (address, family) => resolveFamily(utils.isObject(address) ? address : {address, family});
158+
147159
/*eslint consistent-return:0*/
148160
export default isHttpAdapterSupported && function httpAdapter(config) {
149161
return wrapAsync(async function dispatchHttpRequest(resolve, reject, onDone) {
@@ -154,15 +166,16 @@ export default isHttpAdapterSupported && function httpAdapter(config) {
154166
let rejected = false;
155167
let req;
156168

157-
if (lookup && utils.isAsyncFn(lookup)) {
158-
lookup = callbackify(lookup, (entry) => {
159-
if(utils.isString(entry)) {
160-
entry = [entry, entry.indexOf('.') < 0 ? 6 : 4]
161-
} else if (!utils.isArray(entry)) {
162-
throw new TypeError('lookup async function must return an array [ip: string, family: number]]')
163-
}
164-
return entry;
165-
})
169+
if (lookup) {
170+
const _lookup = callbackify(lookup, (value) => utils.isArray(value) ? value : [value]);
171+
// hotfix to support opt.all option which is required for node 20.x
172+
lookup = (hostname, opt, cb) => {
173+
_lookup(hostname, opt, (err, arg0, arg1) => {
174+
const addresses = utils.isArray(arg0) ? arg0.map(addr => buildAddressEntry(addr)) : [buildAddressEntry(arg0, arg1)];
175+
176+
opt.all ? cb(err, addresses) : cb(err, addresses[0].address, addresses[0].family);
177+
});
178+
}
166179
}
167180

168181
// temporary internal emitter until the AxiosRequest class will be implemented

test/module/typings/esm/index.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import axios, {
2020
all,
2121
isCancel,
2222
isAxiosError,
23-
spread
23+
spread, AddressFamily
2424
} from 'axios';
2525

2626
const config: AxiosRequestConfig = {
@@ -574,7 +574,7 @@ axios.get('/user', {
574574

575575
{
576576
// getAdapter
577-
577+
578578
getAdapter(axios.create().defaults.adapter);
579579
getAdapter(undefined);
580580
getAdapter([]);
@@ -658,7 +658,7 @@ for (const [header, value] of headers) {
658658

659659
// lookup
660660
axios.get('/user', {
661-
lookup: (hostname: string, opt: object, cb: (err: Error | null, address: string, family: number) => void) => {
661+
lookup: (hostname: string, opt: object, cb: (err: Error | null, address: string, family: AddressFamily) => void) => {
662662
cb(null, '127.0.0.1', 4);
663663
}
664664
});

test/unit/adapters/http.js

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2122,7 +2122,7 @@ describe('supports http with nodejs', function () {
21222122
});
21232123

21242124
describe('DNS', function() {
2125-
it('should support custom DNS lookup function', async function () {
2125+
it('should support a custom DNS lookup function', async function () {
21262126
server = await startHTTPServer(SERVER_HANDLER_STREAM_ECHO);
21272127

21282128
const payload = 'test';
@@ -2141,7 +2141,26 @@ describe('supports http with nodejs', function () {
21412141
assert.strictEqual(data, payload);
21422142
});
21432143

2144-
it('should support custom DNS lookup function (async)', async function () {
2144+
it('should support a custom DNS lookup function with address entry passing', async function () {
2145+
server = await startHTTPServer(SERVER_HANDLER_STREAM_ECHO);
2146+
2147+
const payload = 'test';
2148+
2149+
let isCalled = false;
2150+
2151+
const {data} = await axios.post(`http://fake-name.axios:4444`, payload,{
2152+
lookup: (hostname, opt, cb) => {
2153+
isCalled = true;
2154+
cb(null, {address: '127.0.0.1', family: 4});
2155+
}
2156+
});
2157+
2158+
assert.ok(isCalled);
2159+
2160+
assert.strictEqual(data, payload);
2161+
});
2162+
2163+
it('should support a custom DNS lookup function (async)', async function () {
21452164
server = await startHTTPServer(SERVER_HANDLER_STREAM_ECHO);
21462165

21472166
const payload = 'test';
@@ -2160,7 +2179,26 @@ describe('supports http with nodejs', function () {
21602179
assert.strictEqual(data, payload);
21612180
});
21622181

2163-
it('should support custom DNS lookup function that returns only IP address (async)', async function () {
2182+
it('should support a custom DNS lookup function with address entry (async)', async function () {
2183+
server = await startHTTPServer(SERVER_HANDLER_STREAM_ECHO);
2184+
2185+
const payload = 'test';
2186+
2187+
let isCalled = false;
2188+
2189+
const {data} = await axios.post(`http://fake-name.axios:4444`, payload,{
2190+
lookup: async (hostname, opt) => {
2191+
isCalled = true;
2192+
return {address: '127.0.0.1', family: 4};
2193+
}
2194+
});
2195+
2196+
assert.ok(isCalled);
2197+
2198+
assert.strictEqual(data, payload);
2199+
});
2200+
2201+
it('should support a custom DNS lookup function that returns only IP address (async)', async function () {
21642202
server = await startHTTPServer(SERVER_HANDLER_STREAM_ECHO);
21652203

21662204
const payload = 'test';

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy