1 | var _ = require('lodash');
|
2 | var httpProxy = require('http-proxy');
|
3 | var configFactory = require('./config-factory');
|
4 | var handlers = require('./handlers');
|
5 | var contextMatcher = require('./context-matcher');
|
6 | var PathRewriter = require('./path-rewriter');
|
7 | var ProxyTable = require('./proxy-table');
|
8 | var logger = require('./logger').getInstance();
|
9 | var getArrow = require('./logger').getArrow;
|
10 |
|
11 | module.exports = HttpProxyMiddleware;
|
12 |
|
13 | function HttpProxyMiddleware(context, opts) {
|
14 |
|
15 | var wsUpgradeDebounced = _.debounce(handleUpgrade);
|
16 | var config = configFactory.createConfig(context, opts);
|
17 | var proxyOptions = config.options;
|
18 |
|
19 |
|
20 | var proxy = httpProxy.createProxyServer(proxyOptions);
|
21 | logger.info('[HPM] Proxy created:', config.context, ' -> ', proxyOptions.target);
|
22 |
|
23 | var pathRewriter = PathRewriter.create(proxyOptions.pathRewrite);
|
24 |
|
25 |
|
26 | handlers.init(proxy, proxyOptions);
|
27 |
|
28 |
|
29 | proxy.on('error', logError);
|
30 |
|
31 |
|
32 |
|
33 | middleware.upgrade = wsUpgradeDebounced;
|
34 |
|
35 | return middleware;
|
36 |
|
37 | function middleware(req, res, next) {
|
38 |
|
39 | req.url = req.originalUrl;
|
40 |
|
41 | if (contextMatcher.match(config.context, req.url, req)) {
|
42 | var activeProxyOptions = prepareProxyRequest(req);
|
43 | proxy.web(req, res, activeProxyOptions);
|
44 | } else {
|
45 | next();
|
46 | }
|
47 |
|
48 | if (proxyOptions.ws === true) {
|
49 | catchUpgradeRequest(req.connection.server);
|
50 | }
|
51 | }
|
52 |
|
53 | function catchUpgradeRequest(server) {
|
54 | server.on('upgrade', wsUpgradeDebounced);
|
55 | }
|
56 |
|
57 | function handleUpgrade(req, socket, head) {
|
58 | if (contextMatcher.match(config.context, req.url, req)) {
|
59 | var activeProxyOptions = prepareProxyRequest(req);
|
60 | proxy.ws(req, socket, head, activeProxyOptions);
|
61 | logger.info('[HPM] Upgrading to WebSocket');
|
62 | }
|
63 | }
|
64 |
|
65 | |
66 |
|
67 |
|
68 |
|
69 |
|
70 |
|
71 | function prepareProxyRequest(req) {
|
72 |
|
73 | var originalPath = req.url;
|
74 |
|
75 |
|
76 |
|
77 |
|
78 | var alteredProxyOptions = __applyProxyTableOption(req, proxyOptions);
|
79 | __applyPathRewrite(pathRewriter, req);
|
80 |
|
81 |
|
82 | if (proxyOptions.logLevel === 'debug') {
|
83 | var arrow = getArrow(originalPath, req.url, proxyOptions.target, alteredProxyOptions.target);
|
84 | logger.debug('[HPM] %s %s %s %s', req.method, originalPath, arrow, alteredProxyOptions.target);
|
85 | }
|
86 |
|
87 | return alteredProxyOptions;
|
88 | }
|
89 |
|
90 |
|
91 |
|
92 | function __applyProxyTableOption(req) {
|
93 | var result = proxyOptions;
|
94 |
|
95 | if (proxyOptions.proxyTable) {
|
96 | result = ProxyTable.createProxyOptions(req, proxyOptions);
|
97 | }
|
98 |
|
99 | return result;
|
100 | }
|
101 |
|
102 |
|
103 | function __applyPathRewrite(pathRewriter, req) {
|
104 | if (pathRewriter) {
|
105 | var path = pathRewriter(req.url, req);
|
106 |
|
107 | if (path) {
|
108 | req.url = path;
|
109 | } else {
|
110 | logger.info('[HPM] pathRewrite: No rewritten path found. (%s)', req.url);
|
111 | }
|
112 | }
|
113 | }
|
114 |
|
115 | function logError(err, req, res) {
|
116 | var hostname = (req.hostname || req.host) || (req.headers && req.headers.host);
|
117 | var targetUri = (proxyOptions.target.host || proxyOptions.target) + req.url;
|
118 |
|
119 | logger.error('[HPM] PROXY ERROR: %s. %s -> %s', err.code, hostname, targetUri);
|
120 | }
|
121 | };
|