1
|
/*!
|
2
|
* forwarded
|
3
|
* Copyright(c) 2014-2017 Douglas Christopher Wilson
|
4
|
* MIT Licensed
|
5
|
*/
|
6
|
|
7
|
'use strict'
|
8
|
|
9
|
/**
|
10
|
* Module exports.
|
11
|
* @public
|
12
|
*/
|
13
|
|
14
|
module.exports = forwarded
|
15
|
|
16
|
/**
|
17
|
* Get all addresses in the request, using the `X-Forwarded-For` header.
|
18
|
*
|
19
|
* @param {object} req
|
20
|
* @return {array}
|
21
|
* @public
|
22
|
*/
|
23
|
|
24
|
function forwarded (req) {
|
25
|
if (!req) {
|
26
|
throw new TypeError('argument req is required')
|
27
|
}
|
28
|
|
29
|
// simple header parsing
|
30
|
var proxyAddrs = parse(req.headers['x-forwarded-for'] || '')
|
31
|
var socketAddr = req.connection.remoteAddress
|
32
|
var addrs = [socketAddr].concat(proxyAddrs)
|
33
|
|
34
|
// return all addresses
|
35
|
return addrs
|
36
|
}
|
37
|
|
38
|
/**
|
39
|
* Parse the X-Forwarded-For header.
|
40
|
*
|
41
|
* @param {string} header
|
42
|
* @private
|
43
|
*/
|
44
|
|
45
|
function parse (header) {
|
46
|
var end = header.length
|
47
|
var list = []
|
48
|
var start = header.length
|
49
|
|
50
|
// gather addresses, backwards
|
51
|
for (var i = header.length - 1; i >= 0; i--) {
|
52
|
switch (header.charCodeAt(i)) {
|
53
|
case 0x20: /* */
|
54
|
if (start === end) {
|
55
|
start = end = i
|
56
|
}
|
57
|
break
|
58
|
case 0x2c: /* , */
|
59
|
if (start !== end) {
|
60
|
list.push(header.substring(start, end))
|
61
|
}
|
62
|
start = end = i
|
63
|
break
|
64
|
default:
|
65
|
start = i
|
66
|
break
|
67
|
}
|
68
|
}
|
69
|
|
70
|
// final address
|
71
|
if (start !== end) {
|
72
|
list.push(header.substring(start, end))
|
73
|
}
|
74
|
|
75
|
return list
|
76
|
}
|