Spaces:
Sleeping
Sleeping
/*! | |
* forwarded | |
* Copyright(c) 2014-2017 Douglas Christopher Wilson | |
* MIT Licensed | |
*/ | |
/** | |
* 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 | |
} | |