| /*! | 
|  * 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 | 
| } |