| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327 | 
							- /*!
 
-  * proxy-addr
 
-  * Copyright(c) 2014-2016 Douglas Christopher Wilson
 
-  * MIT Licensed
 
-  */
 
- 'use strict'
 
- /**
 
-  * Module exports.
 
-  * @public
 
-  */
 
- module.exports = proxyaddr
 
- module.exports.all = alladdrs
 
- module.exports.compile = compile
 
- /**
 
-  * Module dependencies.
 
-  * @private
 
-  */
 
- var forwarded = require('forwarded')
 
- var ipaddr = require('ipaddr.js')
 
- /**
 
-  * Variables.
 
-  * @private
 
-  */
 
- var DIGIT_REGEXP = /^[0-9]+$/
 
- var isip = ipaddr.isValid
 
- var parseip = ipaddr.parse
 
- /**
 
-  * Pre-defined IP ranges.
 
-  * @private
 
-  */
 
- var IP_RANGES = {
 
-   linklocal: ['169.254.0.0/16', 'fe80::/10'],
 
-   loopback: ['127.0.0.1/8', '::1/128'],
 
-   uniquelocal: ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16', 'fc00::/7']
 
- }
 
- /**
 
-  * Get all addresses in the request, optionally stopping
 
-  * at the first untrusted.
 
-  *
 
-  * @param {Object} request
 
-  * @param {Function|Array|String} [trust]
 
-  * @public
 
-  */
 
- function alladdrs (req, trust) {
 
-   // get addresses
 
-   var addrs = forwarded(req)
 
-   if (!trust) {
 
-     // Return all addresses
 
-     return addrs
 
-   }
 
-   if (typeof trust !== 'function') {
 
-     trust = compile(trust)
 
-   }
 
-   for (var i = 0; i < addrs.length - 1; i++) {
 
-     if (trust(addrs[i], i)) continue
 
-     addrs.length = i + 1
 
-   }
 
-   return addrs
 
- }
 
- /**
 
-  * Compile argument into trust function.
 
-  *
 
-  * @param {Array|String} val
 
-  * @private
 
-  */
 
- function compile (val) {
 
-   if (!val) {
 
-     throw new TypeError('argument is required')
 
-   }
 
-   var trust
 
-   if (typeof val === 'string') {
 
-     trust = [val]
 
-   } else if (Array.isArray(val)) {
 
-     trust = val.slice()
 
-   } else {
 
-     throw new TypeError('unsupported trust argument')
 
-   }
 
-   for (var i = 0; i < trust.length; i++) {
 
-     val = trust[i]
 
-     if (!Object.prototype.hasOwnProperty.call(IP_RANGES, val)) {
 
-       continue
 
-     }
 
-     // Splice in pre-defined range
 
-     val = IP_RANGES[val]
 
-     trust.splice.apply(trust, [i, 1].concat(val))
 
-     i += val.length - 1
 
-   }
 
-   return compileTrust(compileRangeSubnets(trust))
 
- }
 
- /**
 
-  * Compile `arr` elements into range subnets.
 
-  *
 
-  * @param {Array} arr
 
-  * @private
 
-  */
 
- function compileRangeSubnets (arr) {
 
-   var rangeSubnets = new Array(arr.length)
 
-   for (var i = 0; i < arr.length; i++) {
 
-     rangeSubnets[i] = parseipNotation(arr[i])
 
-   }
 
-   return rangeSubnets
 
- }
 
- /**
 
-  * Compile range subnet array into trust function.
 
-  *
 
-  * @param {Array} rangeSubnets
 
-  * @private
 
-  */
 
- function compileTrust (rangeSubnets) {
 
-   // Return optimized function based on length
 
-   var len = rangeSubnets.length
 
-   return len === 0
 
-     ? trustNone
 
-     : len === 1
 
-       ? trustSingle(rangeSubnets[0])
 
-       : trustMulti(rangeSubnets)
 
- }
 
- /**
 
-  * Parse IP notation string into range subnet.
 
-  *
 
-  * @param {String} note
 
-  * @private
 
-  */
 
- function parseipNotation (note) {
 
-   var pos = note.lastIndexOf('/')
 
-   var str = pos !== -1
 
-     ? note.substring(0, pos)
 
-     : note
 
-   if (!isip(str)) {
 
-     throw new TypeError('invalid IP address: ' + str)
 
-   }
 
-   var ip = parseip(str)
 
-   if (pos === -1 && ip.kind() === 'ipv6' && ip.isIPv4MappedAddress()) {
 
-     // Store as IPv4
 
-     ip = ip.toIPv4Address()
 
-   }
 
-   var max = ip.kind() === 'ipv6'
 
-     ? 128
 
-     : 32
 
-   var range = pos !== -1
 
-     ? note.substring(pos + 1, note.length)
 
-     : null
 
-   if (range === null) {
 
-     range = max
 
-   } else if (DIGIT_REGEXP.test(range)) {
 
-     range = parseInt(range, 10)
 
-   } else if (ip.kind() === 'ipv4' && isip(range)) {
 
-     range = parseNetmask(range)
 
-   } else {
 
-     range = null
 
-   }
 
-   if (range <= 0 || range > max) {
 
-     throw new TypeError('invalid range on address: ' + note)
 
-   }
 
-   return [ip, range]
 
- }
 
- /**
 
-  * Parse netmask string into CIDR range.
 
-  *
 
-  * @param {String} netmask
 
-  * @private
 
-  */
 
- function parseNetmask (netmask) {
 
-   var ip = parseip(netmask)
 
-   var kind = ip.kind()
 
-   return kind === 'ipv4'
 
-     ? ip.prefixLengthFromSubnetMask()
 
-     : null
 
- }
 
- /**
 
-  * Determine address of proxied request.
 
-  *
 
-  * @param {Object} request
 
-  * @param {Function|Array|String} trust
 
-  * @public
 
-  */
 
- function proxyaddr (req, trust) {
 
-   if (!req) {
 
-     throw new TypeError('req argument is required')
 
-   }
 
-   if (!trust) {
 
-     throw new TypeError('trust argument is required')
 
-   }
 
-   var addrs = alladdrs(req, trust)
 
-   var addr = addrs[addrs.length - 1]
 
-   return addr
 
- }
 
- /**
 
-  * Static trust function to trust nothing.
 
-  *
 
-  * @private
 
-  */
 
- function trustNone () {
 
-   return false
 
- }
 
- /**
 
-  * Compile trust function for multiple subnets.
 
-  *
 
-  * @param {Array} subnets
 
-  * @private
 
-  */
 
- function trustMulti (subnets) {
 
-   return function trust (addr) {
 
-     if (!isip(addr)) return false
 
-     var ip = parseip(addr)
 
-     var ipconv
 
-     var kind = ip.kind()
 
-     for (var i = 0; i < subnets.length; i++) {
 
-       var subnet = subnets[i]
 
-       var subnetip = subnet[0]
 
-       var subnetkind = subnetip.kind()
 
-       var subnetrange = subnet[1]
 
-       var trusted = ip
 
-       if (kind !== subnetkind) {
 
-         if (subnetkind === 'ipv4' && !ip.isIPv4MappedAddress()) {
 
-           // Incompatible IP addresses
 
-           continue
 
-         }
 
-         if (!ipconv) {
 
-           // Convert IP to match subnet IP kind
 
-           ipconv = subnetkind === 'ipv4'
 
-             ? ip.toIPv4Address()
 
-             : ip.toIPv4MappedAddress()
 
-         }
 
-         trusted = ipconv
 
-       }
 
-       if (trusted.match(subnetip, subnetrange)) {
 
-         return true
 
-       }
 
-     }
 
-     return false
 
-   }
 
- }
 
- /**
 
-  * Compile trust function for single subnet.
 
-  *
 
-  * @param {Object} subnet
 
-  * @private
 
-  */
 
- function trustSingle (subnet) {
 
-   var subnetip = subnet[0]
 
-   var subnetkind = subnetip.kind()
 
-   var subnetisipv4 = subnetkind === 'ipv4'
 
-   var subnetrange = subnet[1]
 
-   return function trust (addr) {
 
-     if (!isip(addr)) return false
 
-     var ip = parseip(addr)
 
-     var kind = ip.kind()
 
-     if (kind !== subnetkind) {
 
-       if (subnetisipv4 && !ip.isIPv4MappedAddress()) {
 
-         // Incompatible IP addresses
 
-         return false
 
-       }
 
-       // Convert IP to match subnet IP kind
 
-       ip = subnetisipv4
 
-         ? ip.toIPv4Address()
 
-         : ip.toIPv4MappedAddress()
 
-     }
 
-     return ip.match(subnetip, subnetrange)
 
-   }
 
- }
 
 
  |