All files / koa/middleware real_ip.js

100% Statements 19/19
75% Branches 6/8
100% Functions 8/8
100% Lines 19/19

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 455x 5x               88x 1320x   88x         5x 5x 88x   88x     88x 88x 88x 88x   88x     88x 88x   88x   1x       88x      
const insubnet = require('insubnet')
const privates = ['0.0.0.0/8', '10.0.0.0/8', '100.64.0.0/10',
  '127.0.0.0/8', '169.254.0.0/16', '172.16.0.0/12',
  '192.0.0.0/24', '192.0.0.0/29', '192.0.2.0/24',
  '192.168.0.0/16', '198.18.0.0/15', '198.51.100.0/24',
  '203.0.113.0/24', '240.0.0.0/4', '255.255.255.255/32',
]
 
function isPrivateIp(ip) {
  let filtered = privates.filter((privateSubnet) => {
    return insubnet.Auto(ip, privateSubnet)
  })
  return filtered.length > 0
}
 
// This is a hack, since the nginx RealIP module seems sometimes give wrong IPs.
// To enable this, `app.proxy` needs to be set as `true`.
module.exports = function () {
  return function (ctx, next) {
    return Promise.resolve()
      .then(function () {
        let ips = Array.isArray(ctx.request.ips) && ctx.request.ips.length > 0
          ? ctx.request.ips : ctx.get('x-forwarded-for').split(',')
 
        Eif (ips.length > 0) {
          ips = ips.filter((ip) => {
            let current = ip.trim()
            return !isPrivateIp(current)
          }).map((ip) => {
            return ip.trim()
          })
 
          let ip = ips[0]
          let currentIp = ctx.request.ip
          // redefine the getter
          Object.defineProperty(ctx.request, 'ip', {
            get: function () {
              return ip || currentIp
            },
          })
        }
        return next()
      })
  }
}