Skip to content

Commit 39f2c9b

Browse files
author
v1rtl
committed
improve types and move deps onto separate file
1 parent b3407cb commit 39f2c9b

File tree

8 files changed

+74
-47
lines changed

8 files changed

+74
-47
lines changed

.vscode/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"deno.enable": true
3+
}

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# proxy_addr
22

3-
[![GitHub release (latest by date)][releases]][releases-page] [![][docs-badge]][docs] [![GitHub Workflow Status][gh-actions-img]][github-actions] [![Codecov][codecov-badge]][codecov]
3+
[![GitHub release (latest by date)][releases]][releases-page]
4+
[![][docs-badge]][docs]
5+
[![GitHub Workflow Status][gh-actions-img]][github-actions]
6+
[![Codecov][codecov-badge]][codecov]
47

58
Deno port of
69
[proxy-addr](https://github.com/jshttp/proxy-addr/blob/master/index.js) library.

deno.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
{
22
"fmt": {
3-
"useTabs": false,
4-
"lineWidth": 80,
5-
"indentWidth": 2,
6-
"singleQuote": true,
7-
"semiColons": false
3+
"useTabs": false,
4+
"lineWidth": 80,
5+
"indentWidth": 2,
6+
"singleQuote": true,
7+
"semiColons": false
88
},
99
"tasks": {
1010
"test": "deno test --coverage=coverage",

deno.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

deps.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/// <reference types="./ipaddr.d.ts" />
2+
export {
3+
isValid,
4+
parse,
5+
} from "https://esm.sh/[email protected]/lib/ipaddr.js?exports=isValid,parse";
6+
export type { IPv4, IPv6 } from "./ipaddr.d.ts";
7+
export type { RequestWithConnection } from "https://deno.land/x/[email protected]/mod.ts";
8+
export { forwarded } from "https://deno.land/x/[email protected]/mod.ts";

ipaddr.d.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Common methods/properties for IPv4 and IPv6 classes.
2+
export class IP {
3+
toString(): string;
4+
}
5+
6+
export function isValid(addr: string): boolean;
7+
export function parse(addr: string): IPv4 | IPv6;
8+
9+
export class IPv4 extends IP {
10+
constructor(octets: number[]);
11+
kind(): "ipv4";
12+
toIPv4MappedAddress(): IPv6;
13+
}
14+
15+
export class IPv6 extends IP {
16+
constructor(parts: number[]);
17+
isIPv4MappedAddress(): boolean;
18+
kind(): "ipv6";
19+
toIPv4Address(): IPv4;
20+
}

mod.ts

Lines changed: 30 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
1-
// deno-lint-ignore-file
2-
import { default as ipaddr, IPv4, IPv6 } from 'https://esm.sh/[email protected]/'
3-
import { forwarded } from 'https://deno.land/x/[email protected]/mod.ts'
4-
import type { RequestWithConnection } from 'https://deno.land/x/[email protected]/mod.ts'
1+
import { forwarded, IPv4, IPv6, isValid, parse } from './deps.ts'
2+
import type { RequestWithConnection } from './deps.ts'
3+
export { RequestWithConnection }
54

6-
export type { RequestWithConnection }
5+
type Trust = ((addr: string, i?: number) => boolean) | string[] | string
76

87
const DIGIT_REGEXP = /^[0-9]+$/
9-
const isip = ipaddr.isValid
10-
const parseip = ipaddr.parse
118
/**
129
* Pre-defined IP ranges.
1310
*/
@@ -23,10 +20,7 @@ const IP_RANGES: Record<string, string[]> = {
2320
* @param request
2421
* @param trust
2522
*/
26-
function alladdrs(
27-
req: RequestWithConnection,
28-
trust?: ((...args: any[]) => any) | any[] | string[] | string,
29-
) {
23+
function alladdrs(req: RequestWithConnection, trust?: Trust) {
3024
// get addresses
3125

3226
const addrs = forwarded(req)
@@ -70,9 +64,11 @@ function compile(val: string | string[]) {
7064
/**
7165
* Compile `arr` elements into range subnets.
7266
*/
73-
function compileRangeSubnets(arr: any[]) {
67+
function compileRangeSubnets(arr: string[]) {
7468
const rangeSubnets = new Array(arr.length)
75-
for (let i = 0; i < arr.length; i++) rangeSubnets[i] = parseIPNotation(arr[i])
69+
for (let i = 0; i < arr.length; i++) {
70+
rangeSubnets[i] = parseIPNotation(arr[i])
71+
}
7672

7773
return rangeSubnets
7874
}
@@ -81,7 +77,7 @@ function compileRangeSubnets(arr: any[]) {
8177
*
8278
* @param rangeSubnets
8379
*/
84-
function compileTrust(rangeSubnets: any[]) {
80+
function compileTrust(rangeSubnets: (IPv4 | IPv6)[][]) {
8581
// Return optimized function based on length
8682
const len = rangeSubnets.length
8783
return len === 0
@@ -100,9 +96,9 @@ export function parseIPNotation(note: string) {
10096
const pos = note.lastIndexOf('/')
10197
const str = pos !== -1 ? note.substring(0, pos) : note
10298

103-
if (!isip(str)) throw new TypeError('invalid IP address: ' + str)
99+
if (!isValid(str)) throw new TypeError('invalid IP address: ' + str)
104100

105-
let ip = parseip(str)
101+
let ip = parse(str)
106102

107103
if (pos === -1 && ip.kind() === 'ipv6') {
108104
ip = ip as typeof IPv6
@@ -118,7 +114,7 @@ export function parseIPNotation(note: string) {
118114

119115
if (range === null) range = max
120116
else if (DIGIT_REGEXP.test(range)) range = parseInt(range, 10)
121-
else if (ip.kind() === 'ipv4' && isip(range)) range = parseNetmask(range)
117+
else if (ip.kind() === 'ipv4' && isValid(range)) range = parseNetmask(range)
122118
else range = null
123119

124120
if (range && typeof range === 'number' && (range <= 0 || range > max)) {
@@ -134,7 +130,7 @@ export function parseIPNotation(note: string) {
134130
* @private
135131
*/
136132
function parseNetmask(netmask: string) {
137-
const ip = parseip(netmask)
133+
const ip = parse(netmask)
138134
return ip.kind() === 'ipv4' ? ip.prefixLengthFromSubnetMask() : null
139135
}
140136
/**
@@ -144,10 +140,7 @@ function parseNetmask(netmask: string) {
144140
* @param trust
145141
* @public
146142
*/
147-
export function proxyaddr(
148-
req: RequestWithConnection,
149-
trust?: ((...args: any[]) => any) | any[] | string[] | string,
150-
) {
143+
export function proxyaddr(req: RequestWithConnection, trust?: Trust) {
151144
const addrs = alladdrs(req, trust)
152145

153146
return addrs[addrs.length - 1]
@@ -159,10 +152,10 @@ const trustNone = () => false
159152
/**
160153
* Compile trust function for multiple subnets.
161154
*/
162-
function trustMulti(subnets: any[]) {
155+
function trustMulti(subnets: (IPv4 | IPv6)[][]) {
163156
return function trust(addr: string) {
164-
if (!isip(addr)) return false
165-
const ip = parseip(addr)
157+
if (!isValid(addr)) return false
158+
const ip = parse(addr)
166159
let ipconv
167160
const kind = ip.kind()
168161
for (let i = 0; i < subnets.length; i++) {
@@ -172,19 +165,19 @@ function trustMulti(subnets: any[]) {
172165
const subnetrange = subnet[1]
173166
let trusted = ip
174167
if (kind !== subnetkind) {
175-
if (
176-
subnetkind === 'ipv4' && !(ip as typeof IPv6).isIPv4MappedAddress()
177-
) continue
168+
if (subnetkind === 'ipv4' && !(ip as IPv6).isIPv4MappedAddress()) {
169+
continue
170+
}
178171

179172
if (!ipconv) {
180173
ipconv = subnetkind === 'ipv4'
181-
? (ip as typeof IPv6).toIPv4Address()
182-
: (ip as typeof IPv4).toIPv4MappedAddress()
174+
? ip.toIPv4Address()
175+
: ip.toIPv4MappedAddress()
183176
}
184177

185178
trusted = ipconv
186179
}
187-
if ((trusted as typeof IPv4).match(subnetip, subnetrange)) return true
180+
if (trusted.match(subnetip, subnetrange)) return true
188181
}
189182
return false
190183
}
@@ -194,25 +187,23 @@ function trustMulti(subnets: any[]) {
194187
*
195188
* @param subnet
196189
*/
197-
function trustSingle(subnet: any[]) {
190+
function trustSingle(subnet: (IPv4 | IPv6)[]) {
198191
const subnetip = subnet[0]
199192
const subnetkind = subnetip.kind()
200193
const subnetisipv4 = subnetkind === 'ipv4'
201194
const subnetrange = subnet[1]
202195
return function trust(addr: string) {
203-
if (!isip(addr)) return false
204-
let ip = parseip(addr)
196+
if (!isValid(addr)) return false
197+
let ip = parse(addr)
205198
const kind = ip.kind()
206199
if (kind !== subnetkind) {
207-
if (subnetisipv4 && !(ip as typeof IPv6).isIPv4MappedAddress()) {
200+
if (subnetisipv4 && !(ip as IPv6).isIPv4MappedAddress()) {
208201
return false
209202
}
210203

211-
ip = subnetisipv4
212-
? (ip as typeof IPv6).toIPv4Address()
213-
: (ip as typeof IPv4).toIPv4MappedAddress()
204+
ip = subnetisipv4 ? ip.toIPv4Address() : ip.toIPv4MappedAddress()
214205
}
215-
return (ip as typeof IPv6).match(subnetip, subnetrange)
206+
return ip.match(subnetip, subnetrange)
216207
}
217208
}
218209

mod_test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,13 @@ describe('all(req, trust)', () => {
3939
})
4040
it('with trust argument should stop at first untrusted', () => {
4141
const req = createReq('127.0.0.1', {
42-
'x-forwarded-for': '10.0.0.1, 10.0.0.2'
42+
'x-forwarded-for': '10.0.0.1, 10.0.0.2',
4343
})
4444
expect(all(req, '127.0.0.1')).toEqual(['127.0.0.1', '10.0.0.2'])
4545
})
4646
it('with trust argument should be only socket address for no trust', () => {
4747
const req = createReq('127.0.0.1', {
48-
'x-forwarded-for': '10.0.0.1, 10.0.0.2'
48+
'x-forwarded-for': '10.0.0.1, 10.0.0.2',
4949
})
5050
expect(all(req, [])).toEqual(['127.0.0.1'])
5151
})

0 commit comments

Comments
 (0)