forked from nfriedly/nodeunblocker.com
-
Notifications
You must be signed in to change notification settings - Fork 2
/
app.js
128 lines (110 loc) · 3.87 KB
/
app.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
/***************
* node-unblocker: Web Proxy for evading firewalls and content filters,
* similar to CGIProxy or PHProxy
*
*
* This project is hosted on github: https://github.com/nfriedly/nodeunblocker.com
*
* By Nathan Friedly - http://nfriedly.com
* Released under the terms of the Affero GPL v3
*/
var url = require('url');
var querystring = require('querystring');
var express = require('express');
var Unblocker = require('unblocker');
var Transform = require('stream').Transform;
var youtube = require('unblocker/examples/youtube/youtube.js')
var app = express();
var google_analytics_id = process.env.GA_ID || null;
function addGa(html) {
if (google_analytics_id) {
var ga = [
"<!-- Google tag (gtag.js) -->",
"<script async src=\"https://www.googletagmanager.com/gtag/js?id=" + google_analytics_id + "\"></script>",
"<script>",
" window.dataLayer = window.dataLayer || [];",
" function gtag(){dataLayer.push(arguments);}",
" gtag('js', new Date());",
"\n",
" gtag('config', " + google_analytics_id + ");",
"</script>"
].join("\n");
html = html.replace("<head>", "<head>\n\n" + ga);
}
return html;
}
function googleAnalyticsMiddleware(data) {
if (data.contentType == 'text/html') {
// https://nodejs.org/api/stream.html#stream_transform
data.stream = data.stream.pipe(new Transform({
decodeStrings: false,
transform: function(chunk, encoding, next) {
this.push(addGa(chunk.toString()));
next();
}
}));
}
}
function forceUpgrade(html) {
var meta = [
"<meta http-equiv=\"Content-Security-Policy\" content=\"upgrade-insecure-requests\">"
].join("\n");
html = html.replace("</head>", meta + "\n\n</head>");
return html;
}
function forceHttpsUpgradeMiddleware(data) {
if (data.contentType == 'text/html') {
// https://nodejs.org/api/stream.html#stream_transform
data.stream = data.stream.pipe(new Transform({
decodeStrings: false,
transform: function(chunk, encoding, next) {
this.push(forceUpgrade(chunk.toString()));
next();
}
}));
}
}
function tetrioPatch(html) {
var meta = [
"<meta http-equiv=\"Content-Security-Policy\" content=\"upgrade-insecure-requests\">"
].join("\n");
html = html.replace("<meta name=googlebot content=notranslate>", "<meta name=googlebot content=notranslate>\n\n" + meta);
return html;
}
function tetrioPatchMiddleware(data) {
if (data.contentType == 'text/html') {
// https://nodejs.org/api/stream.html#stream_transform
data.stream = data.stream.pipe(new Transform({
decodeStrings: false,
transform: function(chunk, encoding, next) {
this.push(tetrioPatch(chunk.toString()));
next();
}
}));
}
}
var unblocker = new Unblocker({
prefix: '/proxy/',
requestMiddleware: [
youtube.processRequest
],
responseMiddleware: [
googleAnalyticsMiddleware,
tetrioPatch
]
});
// this line must appear before any express.static calls (or anything else that sends responses)
app.use(unblocker);
// serve up static files *after* the proxy is run
app.use('/', express.static(__dirname + '/public'));
// this is for users who's form actually submitted due to JS being disabled or whatever
app.get("/no-js", function(req, res) {
// grab the "url" parameter from the querystring
var site = querystring.parse(url.parse(req.url).query).url;
// and redirect the user to /proxy/url
res.redirect(unblockerConfig.prefix + site);
});
const port = process.env.PORT || process.env.VCAP_APP_PORT || 8080;
app.listen(port, function() {
console.log(`node unblocker process listening at http://localhost:${port}/`);
}).on("upgrade", unblocker.onUpgrade); // onUpgrade handles websockets