This repository has been archived by the owner on Apr 14, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathindex.js
81 lines (67 loc) · 2.04 KB
/
index.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
require('now-env');
const { parse, format } = require('url');
const { createServer } = require('http');
const { createProxy } = require('http-proxy');
const HOST = process.env.HOST || 'localhost';
const PORT = Number(process.env.PORT) || 3000;
// get the list of tes cases urls
const testCases = Object.entries(process.env)
.filter(([key]) => key.startsWith('TEST_'))
.reduce((acc, [key, value]) => {
acc[key] = value;
return acc;
}, {});
// create a proxy
const proxy = createProxy({
changeOrigin: true,
target: {
https: true
}
});
// parse cookies from headers
const parseCookies = req => {
const list = {};
const rc = req.headers.cookie;
rc &&
rc.split(';').forEach(cookie => {
const parts = cookie.split('=');
list[parts.shift().trim()] = decodeURI(parts.join('='));
});
return list;
};
// get the test URL to proxy
const getTestURL = (res, cookies = {}) => {
const cases = Object.keys(testCases);
if (!cookies.now_ab) {
const random = Math.floor(Math.random() * cases.length);
const testCase = cases[random];
// set the cookie now_ab with the random
// (don't let the user know the internal url)
res.setHeader('Set-Cookie', [`now_ab=${testCase}`]);
return testCases[testCase];
}
return testCases[cookies.now_ab];
};
// run the HTTP Proxy server
createServer((req, res) => {
const cookies = parseCookies(req);
const url = parse(req.url);
// get the url host from cookies if it's possible or random
url.host = getTestURL(res, cookies);
// if it's not defined anymore (we removed the test) just get it again random
if (url.host === undefined) {
url.host = getTestURL(res);
}
console.log(`Proxying to ${url.host}`);
// format the url host
const target = format(url);
// proxy to the specific target
return proxy.web(req, res, { target });
}).listen(PORT, error => {
if (error) {
console.error(error);
return process.exit(0);
}
console.log('A/B Test Server running on %s:%d', HOST, PORT);
console.log('Cases:', JSON.stringify(testCases, null, 2));
});