http-proxy-middleware 0.17.2-beta → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js CHANGED
@@ -1,137 +1,152 @@
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 Router = require('./router');
8
- var logger = require('./logger').getInstance();
9
- var getArrow = require('./logger').getArrow;
10
-
11
- module.exports = HttpProxyMiddleware;
12
-
13
- function HttpProxyMiddleware(context, opts) {
14
- // https://github.com/chimurai/http-proxy-middleware/issues/57
15
- var wsUpgradeDebounced = _.debounce(handleUpgrade);
16
- var config = configFactory.createConfig(context, opts);
17
- var proxyOptions = config.options;
18
-
19
- // create proxy
20
- var proxy = httpProxy.createProxyServer({});
21
- logger.info('[HPM] Proxy created:', config.context, ' -> ', proxyOptions.target);
22
-
23
- var pathRewriter = PathRewriter.create(proxyOptions.pathRewrite); // returns undefined when "pathRewrite" is not provided
24
-
25
- // attach handler to http-proxy events
26
- handlers.init(proxy, proxyOptions);
27
-
28
- // log errors for debug purpose
29
- proxy.on('error', logError);
30
-
31
- // https://github.com/chimurai/http-proxy-middleware/issues/19
32
- // expose function to upgrade externally
33
- middleware.upgrade = wsUpgradeDebounced;
34
-
35
- return middleware;
36
-
37
- function middleware(req, res, next) {
38
- if (shouldProxy(config.context, req)) {
39
- var activeProxyOptions = prepareProxyRequest(req);
40
- proxy.web(req, res, activeProxyOptions);
41
- } else {
42
- next();
43
- }
44
-
45
- if (proxyOptions.ws === true) {
46
- catchUpgradeRequest(req.connection.server);
47
- }
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 Router = require('./router')
8
+ var logger = require('./logger').getInstance()
9
+ var getArrow = require('./logger').getArrow
10
+
11
+ module.exports = HttpProxyMiddleware
12
+
13
+ function HttpProxyMiddleware (context, opts) {
14
+ // https://github.com/chimurai/http-proxy-middleware/issues/57
15
+ var wsUpgradeDebounced = _.debounce(handleUpgrade)
16
+ var wsInitialized = false
17
+ var config = configFactory.createConfig(context, opts)
18
+ var proxyOptions = config.options
19
+
20
+ // create proxy
21
+ var proxy = httpProxy.createProxyServer({})
22
+ logger.info('[HPM] Proxy created:', config.context, ' -> ', proxyOptions.target)
23
+
24
+ var pathRewriter = PathRewriter.create(proxyOptions.pathRewrite) // returns undefined when "pathRewrite" is not provided
25
+
26
+ // attach handler to http-proxy events
27
+ handlers.init(proxy, proxyOptions)
28
+
29
+ // log errors for debug purpose
30
+ proxy.on('error', logError)
31
+
32
+ // https://github.com/chimurai/http-proxy-middleware/issues/19
33
+ // expose function to upgrade externally
34
+ middleware.upgrade = wsUpgradeDebounced
35
+
36
+ return middleware
37
+
38
+ function middleware (req, res, next) {
39
+ if (shouldProxy(config.context, req)) {
40
+ var activeProxyOptions = prepareProxyRequest(req)
41
+ proxy.web(req, res, activeProxyOptions)
42
+ } else {
43
+ next()
48
44
  }
49
45
 
50
- function catchUpgradeRequest(server) {
51
- server.on('upgrade', wsUpgradeDebounced);
46
+ if (proxyOptions.ws === true) {
47
+ // use initial request to access the server object to subscribe to http upgrade event
48
+ catchUpgradeRequest(req.connection.server)
52
49
  }
53
-
54
- function handleUpgrade(req, socket, head) {
55
- if (shouldProxy(config.context, req)) {
56
- var activeProxyOptions = prepareProxyRequest(req);
57
- proxy.ws(req, socket, head, activeProxyOptions);
58
- logger.info('[HPM] Upgrading to WebSocket');
59
- }
50
+ }
51
+
52
+ function catchUpgradeRequest (server) {
53
+ // subscribe once; don't subscribe on every request...
54
+ // https://github.com/chimurai/http-proxy-middleware/issues/113
55
+ if (!wsInitialized) {
56
+ server.on('upgrade', wsUpgradeDebounced)
57
+ wsInitialized = true
60
58
  }
59
+ }
61
60
 
62
- /**
63
- * Determine whether request should be proxied.
64
- *
65
- * @private
66
- * @return {Boolean}
67
- */
68
- function shouldProxy(context, req) {
69
- var path = (req.originalUrl || req.url);
70
- return contextMatcher.match(context, path, req);
71
- }
61
+ function handleUpgrade (req, socket, head) {
62
+ // set to initialized when used externally
63
+ wsInitialized = true
72
64
 
73
- /**
74
- * Apply option.router and option.pathRewrite
75
- * Order matters:
76
- Router uses original path for routing;
77
- NOT the modified path, after it has been rewritten by pathRewrite
78
- */
79
- function prepareProxyRequest(req) {
80
- // https://github.com/chimurai/http-proxy-middleware/issues/17
81
- // https://github.com/chimurai/http-proxy-middleware/issues/94
82
- req.url = (req.originalUrl || req.url);
83
-
84
- // store uri before it gets rewritten for logging
85
- var originalPath = req.url;
86
- var newProxyOptions = _.cloneDeep(proxyOptions);
87
-
88
- // Apply in order:
89
- // 1. option.router
90
- // 2. option.pathRewrite
91
- __applyRouter(req, newProxyOptions);
92
- __applyPathRewrite(req, pathRewriter);
93
-
94
- // debug logging for both http(s) and websockets
95
- if (proxyOptions.logLevel === 'debug') {
96
- var arrow = getArrow(originalPath, req.url, proxyOptions.target, newProxyOptions.target);
97
- logger.debug('[HPM] %s %s %s %s', req.method, originalPath, arrow, newProxyOptions.target);
98
- }
99
-
100
- return newProxyOptions;
65
+ if (shouldProxy(config.context, req)) {
66
+ var activeProxyOptions = prepareProxyRequest(req)
67
+ proxy.ws(req, socket, head, activeProxyOptions)
68
+ logger.info('[HPM] Upgrading to WebSocket')
69
+ }
70
+ }
71
+
72
+ /**
73
+ * Determine whether request should be proxied.
74
+ *
75
+ * @private
76
+ * @param {String} context [description]
77
+ * @param {Object} req [description]
78
+ * @return {Boolean}
79
+ */
80
+ function shouldProxy (context, req) {
81
+ var path = (req.originalUrl || req.url)
82
+ return contextMatcher.match(context, path, req)
83
+ }
84
+
85
+ /**
86
+ * Apply option.router and option.pathRewrite
87
+ * Order matters:
88
+ * Router uses original path for routing;
89
+ * NOT the modified path, after it has been rewritten by pathRewrite
90
+ * @param {Object} req
91
+ * @return {Object} proxy options
92
+ */
93
+ function prepareProxyRequest (req) {
94
+ // https://github.com/chimurai/http-proxy-middleware/issues/17
95
+ // https://github.com/chimurai/http-proxy-middleware/issues/94
96
+ req.url = (req.originalUrl || req.url)
97
+
98
+ // store uri before it gets rewritten for logging
99
+ var originalPath = req.url
100
+ var newProxyOptions = _.assign({}, proxyOptions)
101
+
102
+ // Apply in order:
103
+ // 1. option.router
104
+ // 2. option.pathRewrite
105
+ __applyRouter(req, newProxyOptions)
106
+ __applyPathRewrite(req, pathRewriter)
107
+
108
+ // debug logging for both http(s) and websockets
109
+ if (proxyOptions.logLevel === 'debug') {
110
+ var arrow = getArrow(originalPath, req.url, proxyOptions.target, newProxyOptions.target)
111
+ logger.debug('[HPM] %s %s %s %s', req.method, originalPath, arrow, newProxyOptions.target)
101
112
  }
102
113
 
103
- // Modify option.target when router present.
104
- function __applyRouter(req, options) {
105
- var newTarget;
114
+ return newProxyOptions
115
+ }
106
116
 
107
- if (options.router) {
108
- newTarget = Router.getTarget(req, options);
117
+ // Modify option.target when router present.
118
+ function __applyRouter (req, options) {
119
+ var newTarget
109
120
 
110
- if (newTarget) {
111
- logger.debug('[HPM] Router new target: %s -> "%s"', options.target, newTarget);
112
- options.target = newTarget;
113
- }
114
- }
115
- }
121
+ if (options.router) {
122
+ newTarget = Router.getTarget(req, options)
116
123
 
117
- // rewrite path
118
- function __applyPathRewrite(req, pathRewriter) {
119
- if (pathRewriter) {
120
- var path = pathRewriter(req.url, req);
121
-
122
- if (path) {
123
- req.url = path;
124
- } else {
125
- logger.info('[HPM] pathRewrite: No rewritten path found. (%s)', req.url);
126
- }
127
- }
124
+ if (newTarget) {
125
+ logger.debug('[HPM] Router new target: %s -> "%s"', options.target, newTarget)
126
+ options.target = newTarget
127
+ }
128
+ }
129
+ }
130
+
131
+ // rewrite path
132
+ function __applyPathRewrite (req, pathRewriter) {
133
+ if (pathRewriter) {
134
+ var path = pathRewriter(req.url, req)
135
+
136
+ if (typeof path === 'string') {
137
+ req.url = path
138
+ } else {
139
+ logger.info('[HPM] pathRewrite: No rewritten path found. (%s)', req.url)
140
+ }
128
141
  }
142
+ }
129
143
 
130
- function logError(err, req, res) {
131
- var hostname = (req.headers && req.headers.host) || (req.hostname || req.host); // (websocket) || (node0.10 || node 4/5)
132
- var target = proxyOptions.target.host || proxyOptions.target;
133
- var errReference = 'https://nodejs.org/api/errors.html#errors_common_system_errors'; // link to Node Common Systems Errors page
144
+ function logError (err, req, res) {
145
+ var hostname = (req.headers && req.headers.host) || (req.hostname || req.host) // (websocket) || (node0.10 || node 4/5)
146
+ var target = proxyOptions.target.host || proxyOptions.target
147
+ var errorMessage = '[HPM] Error occurred while trying to proxy request %s from %s to %s (%s) (%s)'
148
+ var errReference = 'https://nodejs.org/api/errors.html#errors_common_system_errors' // link to Node Common Systems Errors page
134
149
 
135
- logger.error('[HPM] Error occurred while trying to proxy request %s from %s to %s (%s) (%s)', req.url, hostname, target, err.code, errReference);
136
- }
137
- };
150
+ logger.error(errorMessage, req.url, hostname, target, err.code, errReference)
151
+ }
152
+ }
package/lib/logger.js CHANGED
@@ -1,144 +1,144 @@
1
- var util = require('util');
2
- var _ = require('lodash');
1
+ var util = require('util')
2
+ var _ = require('lodash')
3
3
 
4
- var loggerInstance;
4
+ var loggerInstance
5
5
 
6
6
  var defaultProvider = {
7
- log: console.log,
8
- debug: console.log, // use .log(); since console does not have .debug()
9
- info: console.info,
10
- warn: console.warn,
11
- error: console.error
12
- };
7
+ log: console.log,
8
+ debug: console.log, // use .log(); since console does not have .debug()
9
+ info: console.info,
10
+ warn: console.warn,
11
+ error: console.error
12
+ }
13
13
 
14
14
  // log level 'weight'
15
15
  var LEVELS = {
16
- debug: 10,
17
- info: 20,
18
- warn: 30,
19
- error: 50,
20
- silent: 80
21
- };
16
+ debug: 10,
17
+ info: 20,
18
+ warn: 30,
19
+ error: 50,
20
+ silent: 80
21
+ }
22
22
 
23
23
  module.exports = {
24
- // singleton
25
- getInstance: function() {
26
- if (!loggerInstance) {
27
- loggerInstance = new Logger();
28
- }
24
+ // singleton
25
+ getInstance: function () {
26
+ if (!loggerInstance) {
27
+ loggerInstance = new Logger()
28
+ }
29
+
30
+ return loggerInstance
31
+ },
32
+ getArrow: getArrow
33
+ }
29
34
 
30
- return loggerInstance;
35
+ function Logger () {
36
+ var logLevel
37
+ var provider
38
+
39
+ var api = {
40
+ log: log,
41
+ debug: debug,
42
+ info: info,
43
+ warn: warn,
44
+ error: error,
45
+ setLevel: function (v) {
46
+ if (isValidLevel(v)) {
47
+ logLevel = v
48
+ }
31
49
  },
32
- getArrow: getArrow
33
- };
34
-
35
- function Logger() {
36
- var logLevel;
37
- var provider;
38
-
39
- var api = {
40
- log: log,
41
- debug: debug,
42
- info: info,
43
- warn: warn,
44
- error: error,
45
- setLevel: function(v) {
46
- if (isValidLevel(v)) {
47
- logLevel = v;
48
- }
49
- },
50
- setProvider: function(fn) {
51
- if (fn && isValidProvider(fn)) {
52
- provider = fn(defaultProvider);
53
- }
54
- }
55
- };
56
-
57
- init();
58
-
59
- return api;
60
-
61
- function init() {
62
- api.setLevel('info');
63
- api.setProvider(function() {
64
- return defaultProvider;
65
- });
50
+ setProvider: function (fn) {
51
+ if (fn && isValidProvider(fn)) {
52
+ provider = fn(defaultProvider)
53
+ }
66
54
  }
55
+ }
67
56
 
68
- // log will log messages, regardless of logLevels
69
- function log() {
70
- provider.log(_interpolate.apply(null, arguments));
71
- }
57
+ init()
72
58
 
73
- function debug() {
74
- if (_showLevel('debug')) {
75
- provider.debug(_interpolate.apply(null, arguments));
76
- }
77
- }
59
+ return api
78
60
 
79
- function info() {
80
- if (_showLevel('info')) {
81
- provider.info(_interpolate.apply(null, arguments));
82
- }
83
- }
61
+ function init () {
62
+ api.setLevel('info')
63
+ api.setProvider(function () {
64
+ return defaultProvider
65
+ })
66
+ }
84
67
 
85
- function warn() {
86
- if (_showLevel('warn')) {
87
- provider.warn(_interpolate.apply(null, arguments));
88
- }
89
- }
68
+ // log will log messages, regardless of logLevels
69
+ function log () {
70
+ provider.log(_interpolate.apply(null, arguments))
71
+ }
90
72
 
91
- function error() {
92
- if (_showLevel('error')) {
93
- provider.error(_interpolate.apply(null, arguments));
94
- }
73
+ function debug () {
74
+ if (_showLevel('debug')) {
75
+ provider.debug(_interpolate.apply(null, arguments))
95
76
  }
77
+ }
96
78
 
97
- /**
98
- * Decide to log or not to log, based on the log levels 'weight'
99
- * @param {String} showLevel [debug, info, warn, error, silent]
100
- * @return {Boolean}
101
- */
102
- function _showLevel(showLevel) {
103
- var result = false;
104
- var currentLogLevel = LEVELS[logLevel];
79
+ function info () {
80
+ if (_showLevel('info')) {
81
+ provider.info(_interpolate.apply(null, arguments))
82
+ }
83
+ }
105
84
 
106
- if (currentLogLevel && (currentLogLevel <= LEVELS[showLevel])) {
107
- result = true;
108
- }
85
+ function warn () {
86
+ if (_showLevel('warn')) {
87
+ provider.warn(_interpolate.apply(null, arguments))
88
+ }
89
+ }
109
90
 
110
- return result;
91
+ function error () {
92
+ if (_showLevel('error')) {
93
+ provider.error(_interpolate.apply(null, arguments))
94
+ }
95
+ }
96
+
97
+ /**
98
+ * Decide to log or not to log, based on the log levels 'weight'
99
+ * @param {String} showLevel [debug, info, warn, error, silent]
100
+ * @return {Boolean}
101
+ */
102
+ function _showLevel (showLevel) {
103
+ var result = false
104
+ var currentLogLevel = LEVELS[logLevel]
105
+
106
+ if (currentLogLevel && (currentLogLevel <= LEVELS[showLevel])) {
107
+ result = true
111
108
  }
112
109
 
113
- // make sure logged messages and its data are return interpolated
114
- // make it possible for additional log data, such date/time or custom prefix.
115
- function _interpolate() {
116
- var fn = _.spread(util.format);
117
- var result = fn(_.slice(arguments));
110
+ return result
111
+ }
118
112
 
119
- return result;
120
- }
113
+ // make sure logged messages and its data are return interpolated
114
+ // make it possible for additional log data, such date/time or custom prefix.
115
+ function _interpolate () {
116
+ var fn = _.spread(util.format)
117
+ var result = fn(_.slice(arguments))
121
118
 
122
- function isValidProvider(fnProvider) {
123
- var result = true;
119
+ return result
120
+ }
124
121
 
125
- if (fnProvider && !_.isFunction(fnProvider)) {
126
- throw new Error('[HPM] Log provider config error. Expecting a function.');
127
- }
122
+ function isValidProvider (fnProvider) {
123
+ var result = true
128
124
 
129
- return result;
125
+ if (fnProvider && !_.isFunction(fnProvider)) {
126
+ throw new Error('[HPM] Log provider config error. Expecting a function.')
130
127
  }
131
128
 
132
- function isValidLevel(levelName) {
133
- var validLevels = _.keys(LEVELS);
134
- var isValid = _.includes(validLevels, levelName);
129
+ return result
130
+ }
135
131
 
136
- if (!isValid) {
137
- throw new Error('[HPM] Log level error. Invalid logLevel.');
138
- }
132
+ function isValidLevel (levelName) {
133
+ var validLevels = _.keys(LEVELS)
134
+ var isValid = _.includes(validLevels, levelName)
139
135
 
140
- return isValid;
136
+ if (!isValid) {
137
+ throw new Error('[HPM] Log level error. Invalid logLevel.')
141
138
  }
139
+
140
+ return isValid
141
+ }
142
142
  }
143
143
 
144
144
  /**
@@ -146,13 +146,27 @@ function Logger() {
146
146
  * => router
147
147
  * ~> pathRewrite
148
148
  * ≈> router + pathRewrite
149
+ *
150
+ * @param {String} originalPath
151
+ * @param {String} newPath
152
+ * @param {String} originalTarget
153
+ * @param {String} newTarget
154
+ * @return {String}
149
155
  */
150
- function getArrow(originalPath, newPath, originalTarget, newTarget) {
151
- var arrow = ['>'];
152
- var isNewTarget = (originalTarget !== newTarget); // router
153
- var isNewPath = (originalPath !== newPath); // pathRewrite
154
-
155
- if (isNewPath && !isNewTarget) {arrow.unshift('~');} else if (!isNewPath && isNewTarget) {arrow.unshift('=');} else if (isNewPath && isNewTarget) {arrow.unshift('≈');} else {arrow.unshift('-');}
156
-
157
- return arrow.join('');
156
+ function getArrow (originalPath, newPath, originalTarget, newTarget) {
157
+ var arrow = ['>']
158
+ var isNewTarget = (originalTarget !== newTarget) // router
159
+ var isNewPath = (originalPath !== newPath) // pathRewrite
160
+
161
+ if (isNewPath && !isNewTarget) {
162
+ arrow.unshift('~')
163
+ } else if (!isNewPath && isNewTarget) {
164
+ arrow.unshift('=')
165
+ } else if (isNewPath && isNewTarget) {
166
+ arrow.unshift('≈')
167
+ } else {
168
+ arrow.unshift('-')
169
+ }
170
+
171
+ return arrow.join('')
158
172
  }