91 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			91 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /*!
 | |
|  * 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
 | |
| }
 |