1 |
|
2 |
|
3 | namespace HawtioBackend {
|
4 |
|
5 | function proxy(uri, req, res) {
|
6 | function handleError(e) {
|
7 | res.status(500).end('error proxying to "' + uri + '": ' + e);
|
8 | }
|
9 | delete req.headers.referer;
|
10 | var r = request({method: req.method, uri: uri, json: req.body, headers: req.headers, strictSSL: false});
|
11 | req.on('error', handleError)
|
12 | .pipe(r)
|
13 | .on('error', handleError)
|
14 | .on('response', (res2) => {
|
15 | if (res2.statusCode === 401 || res2.statusCode === 403) {
|
16 | log.info("Authentication failed on remote server:", res2.statusCode, res2.statusMessage, uri);
|
17 | log.debug("Response headers:\n", res2.headers);
|
18 | res.header(res2.headers).sendStatus(res2.statusCode);
|
19 | } else {
|
20 | if (res2.headers['content-type']) {
|
21 | res.header('content-type', res2.headers['content-type']);
|
22 | }
|
23 | res.status(res2.statusCode);
|
24 | res2.pipe(res).on('error', handleError);
|
25 | }
|
26 | });
|
27 | }
|
28 |
|
29 | addStartupTask(() => {
|
30 | var index = 0;
|
31 | config.staticProxies.forEach((proxyConfig:any) => {
|
32 | index = index + 1;
|
33 | _.defaults(proxyConfig, {
|
34 | path: '/proxy-' + index,
|
35 | hostname: 'localhost',
|
36 | port: 80,
|
37 | proto: 'http',
|
38 | targetPath: '/proxy-' + index
|
39 | });
|
40 | log.debug("adding static proxy config: \n", proxyConfig);
|
41 | var router = express.Router();
|
42 | router.use('/', (req, res, next) => {
|
43 | var path = [s.rtrim(proxyConfig.targetPath, '/'), s.ltrim(req.path, '/')].join('/');
|
44 | var uri = getTargetURI({
|
45 | proto: proxyConfig.proto,
|
46 | username: proxyConfig.username,
|
47 | password: proxyConfig.password,
|
48 | hostname: proxyConfig.hostname,
|
49 | port: proxyConfig.port,
|
50 | path: path,
|
51 | query: req.query
|
52 | });
|
53 | req.headers.host = proxyConfig.hostname;
|
54 | proxy(uri, req, res);
|
55 | });
|
56 | app.use(proxyConfig.path, router);
|
57 | proxyRoutes[proxyConfig.path] = {
|
58 | proxyConfig: proxyConfig,
|
59 | router: router
|
60 | };
|
61 | });
|
62 | });
|
63 |
|
64 |
|
65 | var proxyRouter = express.Router();
|
66 |
|
67 | proxyRouter.param('proto', (req, res, next, proto) => {
|
68 | log.debug("requesting proto: ", proto);
|
69 | switch (proto.toLowerCase()) {
|
70 | case 'http':
|
71 | case 'https':
|
72 | next();
|
73 | break;
|
74 | default:
|
75 | res.status(406).send('Invalid protocol: "' + proto + '"');
|
76 | }
|
77 | });
|
78 |
|
79 | proxyRouter.param('hostname', (req, res, next, hostname) => {
|
80 | log.debug("requesting hostname: ", hostname);
|
81 | next();
|
82 | });
|
83 |
|
84 | proxyRouter.param('port', (req, res, next, port) => {
|
85 | log.debug("requesting port: ", port);
|
86 | var portNumber = s.toNumber(port);
|
87 | log.debug("parsed port number: ", portNumber);
|
88 | if (isNaN(portNumber)) {
|
89 | res.status(406).send('Invalid port number: "' + port + '"');
|
90 | } else {
|
91 | next();
|
92 | }
|
93 | });
|
94 |
|
95 | proxyRouter.use('/', (req, res, next) => {
|
96 | if (req.path === '') {
|
97 | res.status(200).end();
|
98 | } else {
|
99 | next();
|
100 | }
|
101 | });
|
102 |
|
103 | proxyRouter.use('/:proto/:hostname/:port/', (req, res, next) => {
|
104 | var uri = getTargetURI({
|
105 | proto: req.params.proto,
|
106 | hostname: req.params.hostname,
|
107 | port: req.params.port,
|
108 | path: req.path,
|
109 | query: req.query
|
110 | });
|
111 | proxy(uri, req, res);
|
112 | });
|
113 |
|
114 | addStartupTask(() => {
|
115 | log.debug("Setting dynamic proxy mount point: ", config.proxy);
|
116 | app.use(config.proxy, proxyRouter);
|
117 | });
|
118 |
|
119 | }
|