-
Notifications
You must be signed in to change notification settings - Fork 2
/
index.js
97 lines (87 loc) · 2.81 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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
const process = require('node:process');
const http = require('node:http');
const util = require('node:util');
const Router = require('router');
const _ = require('lodash');
const finalhandler = require('finalhandler');
const parse = require('url-parse');
const proxyWrap = require('findhit-proxywrap');
const { boolean } = require('boolean');
class ProxyServer {
constructor(config) {
this.config = {
logger: console,
port: process.env.PROXY_PORT || 0,
serverHost: process.env.PROXY_HOST || '::',
certbot: {
name: process.env.CERTBOT_WELL_KNOWN_NAME || null,
contents: process.env.CERTBOT_WELL_KNOWN_CONTENTS || null
},
proxyProtocol: boolean(process.env.PROXY_PROTOCOL || false),
removeWwwPrefix: true,
// useful option if you don't need https redirect
// (e.g. it's just a certbot server)
redirect: true,
// <https://github.com/cusspvz/proxywrap>
proxyOptions: {},
...config
};
const proxiedHttp = proxyWrap.proxy(http, this.config.proxyOptions);
const router = new Router();
// support for lets encrypt verification
if (
_.isObject(this.config.certbot) &&
_.isString(this.config.certbot.name) &&
_.isString(this.config.certbot.contents)
)
router.get(
`/.well-known/acme-challenge/${this.config.certbot.name}`,
(request, response) => {
response.setHeader('Content-Type', 'text/plain; charset=utf-8');
response.end(this.config.certbot.contents);
}
);
if (this.config.redirect)
router.use((request, response) => {
if (this.config.removeWwwPrefix)
request.headers.host = request.headers.host.replace('www.', '');
response.writeHead(301, {
Location: parse(`https://${request.headers.host}${request.url}`).href
});
response.end();
});
else
router.use((request, response) => {
// X-Robots-Tag
// <https://developers.google.com/search/docs/crawling-indexing/robots-meta-tag>
response.writeHead(200, {
'X-Robots-Tag': 'none'
});
response.end('OK');
});
const createServer = this.config.proxyProtocol
? proxiedHttp.createServer
: http.createServer;
this.server = createServer((request, response) => {
router(request, response, finalhandler(request, response));
});
// bind listen/close to this
this.listen = this.listen.bind(this);
this.close = this.close.bind(this);
}
async listen(
port = this.config.port,
host = this.config.serverHost,
...args
) {
await util.promisify(this.server.listen).bind(this.server)(
port,
host,
...args
);
}
async close() {
await util.promisify(this.server.close).bind(this.server)();
}
}
module.exports = ProxyServer;