| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 | /*! * forwarded * Copyright(c) 2014-2017 Douglas Christopher Wilson * MIT Licensed */'use strict'/** * Module exports. * @public */module.exports = forwarded/** * Get all addresses in the request, using the `X-Forwarded-For` header. * * @param {object} req * @return {array} * @public */function forwarded (req) {  if (!req) {    throw new TypeError('argument req is required')  }  // simple header parsing  var proxyAddrs = parse(req.headers['x-forwarded-for'] || '')  var socketAddr = getSocketAddr(req)  var addrs = [socketAddr].concat(proxyAddrs)  // return all addresses  return addrs}/** * Get the socket address for a request. * * @param {object} req * @return {string} * @private */function getSocketAddr (req) {  return req.socket    ? req.socket.remoteAddress    : req.connection.remoteAddress}/** * Parse the X-Forwarded-For header. * * @param {string} header * @private */function parse (header) {  var end = header.length  var list = []  var start = header.length  // gather addresses, backwards  for (var i = header.length - 1; i >= 0; i--) {    switch (header.charCodeAt(i)) {      case 0x20: /*   */        if (start === end) {          start = end = i        }        break      case 0x2c: /* , */        if (start !== end) {          list.push(header.substring(start, end))        }        start = end = i        break      default:        start = i        break    }  }  // final address  if (start !== end) {    list.push(header.substring(start, end))  }  return list}
 |