source: trip-planner-front/node_modules/proxy-addr/index.js@ 76712b2

Last change on this file since 76712b2 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 5.9 KB
Line 
1/*!
2 * proxy-addr
3 * Copyright(c) 2014-2016 Douglas Christopher Wilson
4 * MIT Licensed
5 */
6
7'use strict'
8
9/**
10 * Module exports.
11 * @public
12 */
13
14module.exports = proxyaddr
15module.exports.all = alladdrs
16module.exports.compile = compile
17
18/**
19 * Module dependencies.
20 * @private
21 */
22
23var forwarded = require('forwarded')
24var ipaddr = require('ipaddr.js')
25
26/**
27 * Variables.
28 * @private
29 */
30
31var DIGIT_REGEXP = /^[0-9]+$/
32var isip = ipaddr.isValid
33var parseip = ipaddr.parse
34
35/**
36 * Pre-defined IP ranges.
37 * @private
38 */
39
40var IP_RANGES = {
41 linklocal: ['169.254.0.0/16', 'fe80::/10'],
42 loopback: ['127.0.0.1/8', '::1/128'],
43 uniquelocal: ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16', 'fc00::/7']
44}
45
46/**
47 * Get all addresses in the request, optionally stopping
48 * at the first untrusted.
49 *
50 * @param {Object} request
51 * @param {Function|Array|String} [trust]
52 * @public
53 */
54
55function alladdrs (req, trust) {
56 // get addresses
57 var addrs = forwarded(req)
58
59 if (!trust) {
60 // Return all addresses
61 return addrs
62 }
63
64 if (typeof trust !== 'function') {
65 trust = compile(trust)
66 }
67
68 for (var i = 0; i < addrs.length - 1; i++) {
69 if (trust(addrs[i], i)) continue
70
71 addrs.length = i + 1
72 }
73
74 return addrs
75}
76
77/**
78 * Compile argument into trust function.
79 *
80 * @param {Array|String} val
81 * @private
82 */
83
84function compile (val) {
85 if (!val) {
86 throw new TypeError('argument is required')
87 }
88
89 var trust
90
91 if (typeof val === 'string') {
92 trust = [val]
93 } else if (Array.isArray(val)) {
94 trust = val.slice()
95 } else {
96 throw new TypeError('unsupported trust argument')
97 }
98
99 for (var i = 0; i < trust.length; i++) {
100 val = trust[i]
101
102 if (!Object.prototype.hasOwnProperty.call(IP_RANGES, val)) {
103 continue
104 }
105
106 // Splice in pre-defined range
107 val = IP_RANGES[val]
108 trust.splice.apply(trust, [i, 1].concat(val))
109 i += val.length - 1
110 }
111
112 return compileTrust(compileRangeSubnets(trust))
113}
114
115/**
116 * Compile `arr` elements into range subnets.
117 *
118 * @param {Array} arr
119 * @private
120 */
121
122function compileRangeSubnets (arr) {
123 var rangeSubnets = new Array(arr.length)
124
125 for (var i = 0; i < arr.length; i++) {
126 rangeSubnets[i] = parseipNotation(arr[i])
127 }
128
129 return rangeSubnets
130}
131
132/**
133 * Compile range subnet array into trust function.
134 *
135 * @param {Array} rangeSubnets
136 * @private
137 */
138
139function compileTrust (rangeSubnets) {
140 // Return optimized function based on length
141 var len = rangeSubnets.length
142 return len === 0
143 ? trustNone
144 : len === 1
145 ? trustSingle(rangeSubnets[0])
146 : trustMulti(rangeSubnets)
147}
148
149/**
150 * Parse IP notation string into range subnet.
151 *
152 * @param {String} note
153 * @private
154 */
155
156function parseipNotation (note) {
157 var pos = note.lastIndexOf('/')
158 var str = pos !== -1
159 ? note.substring(0, pos)
160 : note
161
162 if (!isip(str)) {
163 throw new TypeError('invalid IP address: ' + str)
164 }
165
166 var ip = parseip(str)
167
168 if (pos === -1 && ip.kind() === 'ipv6' && ip.isIPv4MappedAddress()) {
169 // Store as IPv4
170 ip = ip.toIPv4Address()
171 }
172
173 var max = ip.kind() === 'ipv6'
174 ? 128
175 : 32
176
177 var range = pos !== -1
178 ? note.substring(pos + 1, note.length)
179 : null
180
181 if (range === null) {
182 range = max
183 } else if (DIGIT_REGEXP.test(range)) {
184 range = parseInt(range, 10)
185 } else if (ip.kind() === 'ipv4' && isip(range)) {
186 range = parseNetmask(range)
187 } else {
188 range = null
189 }
190
191 if (range <= 0 || range > max) {
192 throw new TypeError('invalid range on address: ' + note)
193 }
194
195 return [ip, range]
196}
197
198/**
199 * Parse netmask string into CIDR range.
200 *
201 * @param {String} netmask
202 * @private
203 */
204
205function parseNetmask (netmask) {
206 var ip = parseip(netmask)
207 var kind = ip.kind()
208
209 return kind === 'ipv4'
210 ? ip.prefixLengthFromSubnetMask()
211 : null
212}
213
214/**
215 * Determine address of proxied request.
216 *
217 * @param {Object} request
218 * @param {Function|Array|String} trust
219 * @public
220 */
221
222function proxyaddr (req, trust) {
223 if (!req) {
224 throw new TypeError('req argument is required')
225 }
226
227 if (!trust) {
228 throw new TypeError('trust argument is required')
229 }
230
231 var addrs = alladdrs(req, trust)
232 var addr = addrs[addrs.length - 1]
233
234 return addr
235}
236
237/**
238 * Static trust function to trust nothing.
239 *
240 * @private
241 */
242
243function trustNone () {
244 return false
245}
246
247/**
248 * Compile trust function for multiple subnets.
249 *
250 * @param {Array} subnets
251 * @private
252 */
253
254function trustMulti (subnets) {
255 return function trust (addr) {
256 if (!isip(addr)) return false
257
258 var ip = parseip(addr)
259 var ipconv
260 var kind = ip.kind()
261
262 for (var i = 0; i < subnets.length; i++) {
263 var subnet = subnets[i]
264 var subnetip = subnet[0]
265 var subnetkind = subnetip.kind()
266 var subnetrange = subnet[1]
267 var trusted = ip
268
269 if (kind !== subnetkind) {
270 if (subnetkind === 'ipv4' && !ip.isIPv4MappedAddress()) {
271 // Incompatible IP addresses
272 continue
273 }
274
275 if (!ipconv) {
276 // Convert IP to match subnet IP kind
277 ipconv = subnetkind === 'ipv4'
278 ? ip.toIPv4Address()
279 : ip.toIPv4MappedAddress()
280 }
281
282 trusted = ipconv
283 }
284
285 if (trusted.match(subnetip, subnetrange)) {
286 return true
287 }
288 }
289
290 return false
291 }
292}
293
294/**
295 * Compile trust function for single subnet.
296 *
297 * @param {Object} subnet
298 * @private
299 */
300
301function trustSingle (subnet) {
302 var subnetip = subnet[0]
303 var subnetkind = subnetip.kind()
304 var subnetisipv4 = subnetkind === 'ipv4'
305 var subnetrange = subnet[1]
306
307 return function trust (addr) {
308 if (!isip(addr)) return false
309
310 var ip = parseip(addr)
311 var kind = ip.kind()
312
313 if (kind !== subnetkind) {
314 if (subnetisipv4 && !ip.isIPv4MappedAddress()) {
315 // Incompatible IP addresses
316 return false
317 }
318
319 // Convert IP to match subnet IP kind
320 ip = subnetisipv4
321 ? ip.toIPv4Address()
322 : ip.toIPv4MappedAddress()
323 }
324
325 return ip.match(subnetip, subnetrange)
326 }
327}
Note: See TracBrowser for help on using the repository browser.