Skip to content

Commit adf20ea

Browse files
feat(ip): support cidr strings in proxies (#5394)
Closes GH-5382.
1 parent ca46d50 commit adf20ea

File tree

2 files changed

+60
-1
lines changed

2 files changed

+60
-1
lines changed

ip/index.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -857,7 +857,21 @@ export function findIp(
857857
request: RequestLike,
858858
options?: Options | null | undefined,
859859
): string {
860-
const { platform, proxies } = options || {};
860+
const { platform, proxies: rawProxies } = options || {};
861+
const proxies: Array<Cidr | string> = [];
862+
863+
if (Array.isArray(rawProxies)) {
864+
for (const cidrOrIp of rawProxies) {
865+
if (typeof cidrOrIp === "string") {
866+
proxies.push(parseProxy(cidrOrIp));
867+
}
868+
869+
if (isIpv4Cidr(cidrOrIp) || isIpv6Cidr(cidrOrIp)) {
870+
proxies.push(cidrOrIp);
871+
}
872+
}
873+
}
874+
861875
// Prefer anything available via the platform over headers since headers can
862876
// be set by users. Only if we don't have an IP available in `request` do we
863877
// search the `headers`.

ip/test/ip.test.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,51 @@ test("`findIp`", async (t) => {
249249
},
250250
);
251251

252+
await t.test("should support an IP string in a proxy", function () {
253+
assert.equal(
254+
findIp(
255+
{ headers: { "x-forwarded-for": "1.1.1.1, 2.2.2.2, 3.3.3.3" } },
256+
{ proxies: ["3.3.3.3"] },
257+
),
258+
"2.2.2.2",
259+
);
260+
});
261+
262+
await t.test("should support an CIDR string in a proxy", function () {
263+
assert.equal(
264+
findIp(
265+
{ headers: { "x-forwarded-for": "1.1.1.1, 2.2.2.2, 3.3.3.3" } },
266+
{ proxies: ["3.3.3.3/32"] },
267+
),
268+
"2.2.2.2",
269+
);
270+
});
271+
272+
await t.test("should support an CIDR object in a proxy", function () {
273+
assert.equal(
274+
findIp(
275+
{ headers: { "x-forwarded-for": "1.1.1.1, 2.2.2.2, 3.3.3.3" } },
276+
{ proxies: [parseProxy("3.3.3.3/32")] },
277+
),
278+
"2.2.2.2",
279+
);
280+
});
281+
282+
await t.test("should filter an invalid value in a proxy", function () {
283+
assert.equal(
284+
findIp(
285+
{ headers: { "x-forwarded-for": "1.1.1.1, 2.2.2.2, 3.3.3.3" } },
286+
{
287+
proxies: [
288+
// @ts-expect-error: Testing type annotation violations
289+
123456789,
290+
],
291+
},
292+
),
293+
"3.3.3.3",
294+
);
295+
});
296+
252297
await t.test("request: `ip`", async (t) => {
253298
for (const [message, input, expected, proxies] of cases) {
254299
await t.test(message, () => {

0 commit comments

Comments
 (0)