You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
90 lines
1.5 KiB
90 lines
1.5 KiB
/*! |
|
* 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 |
|
}
|
|
|