-
Notifications
You must be signed in to change notification settings - Fork 0
/
RequestUrl.js
130 lines (122 loc) · 5.26 KB
/
RequestUrl.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
const {is_private_ip, is_valid_ip, is_loopback_ip, cleanup_ip} = require('ipware')();
const originalurl = require('original-url');
const cookie = require('cookie')
const signature = require('cookie-signature')
module.exports = (req) => {
const getIp = (request) => {
//testing manually because do not want req to be populated with attibutes.
return [
"HTTP_X_FORWARDED_FOR",
"HTTP_CLIENT_IP",
"HTTP_X_REAL_IP",
"HTTP_X_FORWARDED",
"HTTP_X_CLUSTER_CLIENT_IP",
"HTTP_FORWARDED_FOR",
"HTTP_FORWARDED",
"HTTP_VIA",
"CF-Connecting-IP",
"X-Real-IP",
"X-Client-IP",
"X-Forwarded-For",
"REMOTE_ADDR"
].reduce(
(acc, key) => (req.headers[key] ||
req.headers[key.toUpperCase()] ||
req.headers[key.toLowerCase()] ||
req.headers[key.toLowerCase().replace(/_/g, '-')] ||
req.headers[key.toUpperCase().replace(/_/g, '-')] ||
request.connection.remoteAddress || '127.0.0.1').split(/\s*,\s*/).reduce(
(ret, cur) => {
last = cleanup_ip(ret)
if (last && is_valid_ip(last) && !is_private_ip(last)) return last
else {
ip = cleanup_ip(cur)
if (ip && is_valid_ip(ip)) {
if (is_private_ip(ip)) {
if (!last || (!is_loopback_ip(ip) && is_loopback_ip(last))) return ip
} else return ip
}
else return last
}
},
acc
)
) || '127.0.0.1';
}
const getNow = (request) =>{
return request.headers['x-now-deployment-url'] || '';
}
const getCookies = (request, secret) => {
var secrets = !secret || Array.isArray(secret) ? (secret || []) : [secret]
var cookiesHeader = request.headers.cookie
if (!cookiesHeader) return null
const JSONCookie = (str) => {
if (typeof str !== 'string' || str.substr(0, 2) !== 'j:') return undefined
try {
return JSON.parse(str.slice(2))
} catch (err) {
return undefined
}
}
const JSONCookies = (obj) => {
for (const key of Object.keys(obj)) {
var val = JSONCookie(obj[key])
if (val) obj[key] = val
}
return obj
}
const signedCookie = (str) => {
if (typeof str !== 'string') return undefined
if (str.substr(0, 2) !== 's:') return str
return secrets.reduce( (acc,cur) => (!acc) ? signature.unsign(str.slice(2), cur) : false, false )
}
const signedCookies = (obj) => {
var ret = Object.create(null)
for (const key of Object.keys(obj)) {
var dec = signedCookie(obj[key], secret)
if (obj[key] !== dec) {
ret[key] = dec
delete obj[key]
}
}
return ret
}
var cookies = cookie.parse(cookiesHeader)
// parse signed cookies
if (secrets.length !== 0) {
var signedCookies = signedCookies(cookies, secrets)
signedCookies = JSONCookies(signedCookies)
}
cookies = JSONCookies(cookies)
return {cookies, signedCookies}
}
const setCookies = (res, name, value, secret, options = {}) => {
if (secret) options.signed = true;
var val = typeof value === 'object' ? 'j:' + JSON.stringify(value) : String(value);
if ('maxAge' in options) {
options.expires = new Date(Date.now() + options.maxAge);
options.maxAge /= 1000;
}
if (options.path == null) options.path = '/';
if (options.signed) val = 's:' + signature.sign(val, secret);
res.setHeader('Set-Cookie', cookie.serialize(name, String(val), options));
}
req['originalUrl'] = req.url
const {origin, protocol, host, hostname, port, pathname, search, hash} = new URL(originalurl(req).full)
req["origin"] = origin
req["protocol"] = protocol
req["host"] = host
req["hostname"] = hostname
req["port"] = port !== '' ? Number(port) : undefined
req["path"] = pathname
req["hash"] = hash // Only here for documentation pourposes
req["search"] = search // https://nodejs.org/api/url.html#url_class_urlsearchparams
req["secure"] = ('https' == protocol)
req["ip"] = getIp(req)
req["ipRoutable"] = !is_private_ip(req.ip);
req["nowUrl"] = getNow(req)
req.cookies = Object.create(null)
req.signedCookies = Object.create(null)
const {cookies, signedCookies} = getCookies(req, "secret", options)
req = Object.assign(req, {cookies, signedCookies} )
}