http-proxy-middleware 0.17.4 → 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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## [v0.18.0](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.18.0)
4
+ - fix(vulnerability): update micromatch to v3.x ([npm:braces:20180219](https://snyk.io/test/npm/http-proxy-middleware?tab=issues&severity=high&severity=medium&severity=low#npm:braces:20180219
5
+ ))
6
+ - test(node): drop node 0.x support ([#212](https://github.com/chimurai/http-proxy-middleware/pull/212))
7
+
8
+
3
9
  ## [v0.17.4](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.17.4)
4
10
  - fix(ntlm authentication): fixed bug preventing proxying with ntlm authentication. ([#132](https://github.com/chimurai/http-proxy-middleware/pull/149)) (Thanks: [EladBezalel](https://github.com/EladBezalel), [oshri551](https://github.com/oshri551))
5
11
 
package/README.md CHANGED
@@ -4,6 +4,7 @@
4
4
  [![Coveralls](https://img.shields.io/coveralls/chimurai/http-proxy-middleware.svg?style=flat-square)](https://coveralls.io/r/chimurai/http-proxy-middleware)
5
5
  [![dependency Status](https://img.shields.io/david/chimurai/http-proxy-middleware.svg?style=flat-square)](https://david-dm.org/chimurai/http-proxy-middleware#info=dependencies)
6
6
  [![dependency Status](https://snyk.io/test/npm/http-proxy-middleware/badge.svg)](https://snyk.io/test/npm/http-proxy-middleware)
7
+ [![JavaScript Style Guide](https://img.shields.io/badge/codestyle-standard-brightgreen.svg)](https://standardjs.com)
7
8
 
8
9
  Node.js proxying made simple. Configure proxy middleware with ease for [connect](https://github.com/senchalabs/connect), [express](https://github.com/strongloop/express), [browser-sync](https://github.com/BrowserSync/browser-sync) and [many more](#compatible-servers).
9
10
 
@@ -130,7 +131,7 @@ var app = express();
130
131
 
131
132
  Providing an alternative way to decide which requests should be proxied; In case you are not able to use the server's [`path` parameter](http://expressjs.com/en/4x/api.html#app.use) to mount the proxy or when you need more flexibility.
132
133
 
133
- The [RFC 3986 `path`](https://tools.ietf.org/html/rfc3986#section-3.3) is be used for context matching.
134
+ [RFC 3986 `path`](https://tools.ietf.org/html/rfc3986#section-3.3) is used for context matching.
134
135
 
135
136
  ```
136
137
  foo://example.com:8042/over/there?name=ferret#nose
@@ -419,18 +420,13 @@ Run the test suite:
419
420
  ```bash
420
421
  # install dependencies
421
422
  $ npm install
422
- ```
423
423
 
424
- unit testing
424
+ # linting
425
+ $ npm run lint
425
426
 
426
- ```bash
427
427
  # unit tests
428
428
  $ npm test
429
- ```
430
429
 
431
- coverage
432
-
433
- ```bash
434
430
  # code coverage
435
431
  $ npm run cover
436
432
  ```
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
- var HPM = require('./lib');
1
+ var HPM = require('./lib')
2
2
 
3
- module.exports = function(context, opts) {
4
- return new HPM(context, opts);
5
- };
3
+ module.exports = function (context, opts) {
4
+ return new HPM(context, opts)
5
+ }
@@ -1,54 +1,55 @@
1
- var _ = require('lodash');
2
- var url = require('url');
3
- var logger = require('./logger').getInstance();
1
+ var _ = require('lodash')
2
+ var url = require('url')
3
+ var ERRORS = require('./errors')
4
+ var logger = require('./logger').getInstance()
4
5
 
5
6
  module.exports = {
6
- createConfig: createConfig
7
- };
8
-
9
- function createConfig(context, opts) {
10
- // structure of config object to be returned
11
- var config = {
12
- context: undefined,
13
- options: {}
14
- };
15
-
16
- // app.use('/api', proxy({target:'http://localhost:9000'}));
17
- if (isContextless(context, opts)) {
18
- config.context = '/';
19
- config.options = _.assign(config.options, context);
20
- }
21
- // app.use('/api', proxy('http://localhost:9000'));
22
- // app.use(proxy('http://localhost:9000/api'));
23
- else if (isStringShortHand(context)) {
24
- var oUrl = url.parse(context);
25
- var target = [oUrl.protocol, '//', oUrl.host].join('');
26
-
27
- config.context = oUrl.pathname || '/';
28
- config.options = _.assign(config.options, {target: target}, opts);
29
-
30
- if (oUrl.protocol === 'ws:' || oUrl.protocol === 'wss:') {
31
- config.options.ws = true;
32
- }
33
- // app.use('/api', proxy({target:'http://localhost:9000'}));
34
- } else {
35
- config.context = context;
36
- config.options = _.assign(config.options, opts);
7
+ createConfig: createConfig
8
+ }
9
+
10
+ function createConfig (context, opts) {
11
+ // structure of config object to be returned
12
+ var config = {
13
+ context: undefined,
14
+ options: {}
15
+ }
16
+
17
+ // app.use('/api', proxy({target:'http://localhost:9000'}));
18
+ if (isContextless(context, opts)) {
19
+ config.context = '/'
20
+ config.options = _.assign(config.options, context)
21
+
22
+ // app.use('/api', proxy('http://localhost:9000'));
23
+ // app.use(proxy('http://localhost:9000/api'));
24
+ } else if (isStringShortHand(context)) {
25
+ var oUrl = url.parse(context)
26
+ var target = [oUrl.protocol, '//', oUrl.host].join('')
27
+
28
+ config.context = oUrl.pathname || '/'
29
+ config.options = _.assign(config.options, {target: target}, opts)
30
+
31
+ if (oUrl.protocol === 'ws:' || oUrl.protocol === 'wss:') {
32
+ config.options.ws = true
37
33
  }
34
+ // app.use('/api', proxy({target:'http://localhost:9000'}));
35
+ } else {
36
+ config.context = context
37
+ config.options = _.assign(config.options, opts)
38
+ }
38
39
 
39
- configureLogger(config.options);
40
+ configureLogger(config.options)
40
41
 
41
- if (!config.options.target) {
42
- throw new Error('[HPM] Missing "target" option. Example: {target: "http://www.example.org"}');
43
- }
42
+ if (!config.options.target) {
43
+ throw new Error(ERRORS.ERR_CONFIG_FACTORY_TARGET_MISSING)
44
+ }
44
45
 
45
- // Legacy option.proxyHost
46
- config.options = mapLegacyProxyHostOption(config.options);
46
+ // Legacy option.proxyHost
47
+ config.options = mapLegacyProxyHostOption(config.options)
47
48
 
48
- // Legacy option.proxyTable > option.router
49
- config.options = mapLegacyProxyTableOption(config.options);
49
+ // Legacy option.proxyTable > option.router
50
+ config.options = mapLegacyProxyTableOption(config.options)
50
51
 
51
- return config;
52
+ return config
52
53
  }
53
54
 
54
55
  /**
@@ -62,10 +63,10 @@ function createConfig(context, opts) {
62
63
  * @param {String} context [description]
63
64
  * @return {Boolean} [description]
64
65
  */
65
- function isStringShortHand(context) {
66
- if (_.isString(context)) {
67
- return (url.parse(context).host) ? true : false;
68
- }
66
+ function isStringShortHand (context) {
67
+ if (_.isString(context)) {
68
+ return !!(url.parse(context).host)
69
+ }
69
70
  }
70
71
 
71
72
  /**
@@ -79,48 +80,48 @@ function isStringShortHand(context) {
79
80
  * @param {*} opts [description]
80
81
  * @return {Boolean} [description]
81
82
  */
82
- function isContextless(context, opts) {
83
- return (_.isPlainObject(context) && _.isEmpty(opts));
83
+ function isContextless (context, opts) {
84
+ return (_.isPlainObject(context) && _.isEmpty(opts))
84
85
  }
85
86
 
86
- function mapLegacyProxyHostOption(options) {
87
- // set options.headers.host when option.proxyHost is provided
88
- if (options.proxyHost) {
89
- logger.warn('*************************************');
90
- logger.warn('[HPM] Deprecated "option.proxyHost"');
91
- logger.warn(' Use "option.changeOrigin" or "option.headers.host" instead');
92
- logger.warn(' "option.proxyHost" will be removed in future release.');
93
- logger.warn('*************************************');
94
-
95
- options.headers = options.headers || {};
96
- options.headers.host = options.proxyHost;
97
- }
87
+ function mapLegacyProxyHostOption (options) {
88
+ // set options.headers.host when option.proxyHost is provided
89
+ if (options.proxyHost) {
90
+ logger.warn('*************************************')
91
+ logger.warn('[HPM] Deprecated "option.proxyHost"')
92
+ logger.warn(' Use "option.changeOrigin" or "option.headers.host" instead')
93
+ logger.warn(' "option.proxyHost" will be removed in future release.')
94
+ logger.warn('*************************************')
98
95
 
99
- return options;
96
+ options.headers = options.headers || {}
97
+ options.headers.host = options.proxyHost
98
+ }
99
+
100
+ return options
100
101
  }
101
102
 
102
103
  // Warn deprecated proxyTable api usage
103
- function mapLegacyProxyTableOption(options) {
104
- if (options.proxyTable) {
105
- logger.warn('*************************************');
106
- logger.warn('[HPM] Deprecated "option.proxyTable"');
107
- logger.warn(' Use "option.router" instead');
108
- logger.warn(' "option.proxyTable" will be removed in future release.');
109
- logger.warn('*************************************');
110
-
111
- options.router = _.clone(options.proxyTable);
112
- _.omit(options, 'proxyTable');
113
- }
114
-
115
- return options;
104
+ function mapLegacyProxyTableOption (options) {
105
+ if (options.proxyTable) {
106
+ logger.warn('*************************************')
107
+ logger.warn('[HPM] Deprecated "option.proxyTable"')
108
+ logger.warn(' Use "option.router" instead')
109
+ logger.warn(' "option.proxyTable" will be removed in future release.')
110
+ logger.warn('*************************************')
111
+
112
+ options.router = _.clone(options.proxyTable)
113
+ _.omit(options, 'proxyTable')
114
+ }
115
+
116
+ return options
116
117
  }
117
118
 
118
- function configureLogger(options) {
119
- if (options.logLevel) {
120
- logger.setLevel(options.logLevel);
121
- }
119
+ function configureLogger (options) {
120
+ if (options.logLevel) {
121
+ logger.setLevel(options.logLevel)
122
+ }
122
123
 
123
- if (options.logProvider) {
124
- logger.setProvider(options.logProvider);
125
- }
124
+ if (options.logProvider) {
125
+ logger.setProvider(options.logProvider)
126
+ }
126
127
  }
@@ -1,43 +1,43 @@
1
- var _ = require('lodash');
2
- var url = require('url');
3
- var isGlob = require('is-glob');
4
- var micromatch = require('micromatch');
1
+ var _ = require('lodash')
2
+ var url = require('url')
3
+ var isGlob = require('is-glob')
4
+ var micromatch = require('micromatch')
5
+ var ERRORS = require('./errors')
5
6
 
6
7
  module.exports = {
7
- match: matchContext
8
- };
8
+ match: matchContext
9
+ }
9
10
 
10
- function matchContext(context, uri, req) {
11
+ function matchContext (context, uri, req) {
12
+ // single path
13
+ if (isStringPath(context)) {
14
+ return matchSingleStringPath(context, uri)
15
+ }
11
16
 
12
- // single path
13
- if (isStringPath(context)) {
14
- return matchSingleStringPath(context, uri);
15
- }
17
+ // single glob path
18
+ if (isGlobPath(context)) {
19
+ return matchSingleGlobPath(context, uri)
20
+ }
16
21
 
17
- // single glob path
18
- if (isGlobPath(context)) {
19
- return matchSingleGlobPath(context, uri);
22
+ // multi path
23
+ if (Array.isArray(context)) {
24
+ if (context.every(isStringPath)) {
25
+ return matchMultiPath(context, uri)
20
26
  }
21
-
22
- // multi path
23
- if (Array.isArray(context)) {
24
- if (context.every(isStringPath)) {
25
- return matchMultiPath(context, uri);
26
- }
27
- if (context.every(isGlobPath)) {
28
- return matchMultiGlobPath(context, uri);
29
- }
30
-
31
- throw new Error('[HPM] Invalid context. Expecting something like: ["/api", "/ajax"] or ["/api/**", "!**.html"]');
27
+ if (context.every(isGlobPath)) {
28
+ return matchMultiGlobPath(context, uri)
32
29
  }
33
30
 
34
- // custom matching
35
- if (_.isFunction(context)) {
36
- var pathname = getUrlPathName(uri);
37
- return context(pathname, req);
38
- }
31
+ throw new Error(ERRORS.ERR_CONTEXT_MATCHER_INVALID_ARRAY)
32
+ }
33
+
34
+ // custom matching
35
+ if (_.isFunction(context)) {
36
+ var pathname = getUrlPathName(uri)
37
+ return context(pathname, req)
38
+ }
39
39
 
40
- throw new Error('[HPM] Invalid context. Expecting something like: "/api" or ["/api", "/ajax"]');
40
+ throw new Error(ERRORS.ERR_CONTEXT_MATCHER_GENERIC)
41
41
  }
42
42
 
43
43
  /**
@@ -45,34 +45,34 @@ function matchContext(context, uri, req) {
45
45
  * @param {String} uri 'http://example.org/api/b/c/d.html'
46
46
  * @return {Boolean}
47
47
  */
48
- function matchSingleStringPath(context, uri) {
49
- var pathname = getUrlPathName(uri);
50
- return pathname.indexOf(context) === 0;
48
+ function matchSingleStringPath (context, uri) {
49
+ var pathname = getUrlPathName(uri)
50
+ return pathname.indexOf(context) === 0
51
51
  }
52
52
 
53
- function matchSingleGlobPath(pattern, uri) {
54
- var pathname = getUrlPathName(uri);
55
- var matches = micromatch(pathname, pattern);
56
- return matches && (matches.length > 0);
53
+ function matchSingleGlobPath (pattern, uri) {
54
+ var pathname = getUrlPathName(uri)
55
+ var matches = micromatch(pathname, pattern)
56
+ return matches && (matches.length > 0)
57
57
  }
58
58
 
59
- function matchMultiGlobPath(patternList, uri) {
60
- return matchSingleGlobPath(patternList, uri);
59
+ function matchMultiGlobPath (patternList, uri) {
60
+ return matchSingleGlobPath(patternList, uri)
61
61
  }
62
62
 
63
63
  /**
64
- * @param {String} context ['/api', '/ajax']
64
+ * @param {String} contextList ['/api', '/ajax']
65
65
  * @param {String} uri 'http://example.org/api/b/c/d.html'
66
66
  * @return {Boolean}
67
67
  */
68
- function matchMultiPath(contextList, uri) {
69
- for (var i = 0; i < contextList.length; i++) {
70
- var context = contextList[i];
71
- if (matchSingleStringPath(context, uri)) {
72
- return true;
73
- }
68
+ function matchMultiPath (contextList, uri) {
69
+ for (var i = 0; i < contextList.length; i++) {
70
+ var context = contextList[i]
71
+ if (matchSingleStringPath(context, uri)) {
72
+ return true
74
73
  }
75
- return false;
74
+ }
75
+ return false
76
76
  }
77
77
 
78
78
  /**
@@ -81,14 +81,14 @@ function matchMultiPath(contextList, uri) {
81
81
  * @param {String} uri from req.url
82
82
  * @return {String} RFC 3986 path
83
83
  */
84
- function getUrlPathName(uri) {
85
- return uri && url.parse(uri).pathname;
84
+ function getUrlPathName (uri) {
85
+ return uri && url.parse(uri).pathname
86
86
  }
87
87
 
88
- function isStringPath(context) {
89
- return _.isString(context) && !isGlob(context);
88
+ function isStringPath (context) {
89
+ return _.isString(context) && !isGlob(context)
90
90
  }
91
91
 
92
- function isGlobPath(context) {
93
- return isGlob(context);
92
+ function isGlobPath (context) {
93
+ return isGlob(context)
94
94
  }
package/lib/errors.js ADDED
@@ -0,0 +1,8 @@
1
+ /* eslint-disable max-len */
2
+
3
+ module.exports = {
4
+ ERR_CONFIG_FACTORY_TARGET_MISSING: '[HPM] Missing "target" option. Example: {target: "http://www.example.org"}',
5
+ ERR_CONTEXT_MATCHER_GENERIC: '[HPM] Invalid context. Expecting something like: "/api" or ["/api", "/ajax"]',
6
+ ERR_CONTEXT_MATCHER_INVALID_ARRAY: '[HPM] Invalid context. Expecting something like: ["/api", "/ajax"] or ["/api/**", "!**.html"]',
7
+ ERR_PATH_REWRITER_CONFIG: '[HPM] Invalid pathRewrite config. Expecting object with pathRewrite config or a rewrite function'
8
+ }
package/lib/handlers.js CHANGED
@@ -1,74 +1,74 @@
1
- var _ = require('lodash');
2
- var logger = require('./logger').getInstance();
1
+ var _ = require('lodash')
2
+ var logger = require('./logger').getInstance()
3
3
 
4
4
  module.exports = {
5
- init: init,
6
- getHandlers: getProxyEventHandlers
7
- };
5
+ init: init,
6
+ getHandlers: getProxyEventHandlers
7
+ }
8
8
 
9
- function init(proxy, opts) {
10
- var handlers = getProxyEventHandlers(opts);
9
+ function init (proxy, opts) {
10
+ var handlers = getProxyEventHandlers(opts)
11
11
 
12
- _.forIn(handlers, function(handler, eventName) {
13
- proxy.on(eventName, handlers[eventName]);
14
- });
12
+ _.forIn(handlers, function (handler, eventName) {
13
+ proxy.on(eventName, handlers[eventName])
14
+ })
15
15
 
16
- logger.debug('[HPM] Subscribed to http-proxy events: ', _.keys(handlers));
16
+ logger.debug('[HPM] Subscribed to http-proxy events: ', _.keys(handlers))
17
17
  }
18
18
 
19
- function getProxyEventHandlers(opts) {
20
- // https://github.com/nodejitsu/node-http-proxy#listening-for-proxy-events
21
- var proxyEvents = ['error', 'proxyReq', 'proxyReqWs', 'proxyRes', 'open', 'close'];
22
- var handlers = {};
23
-
24
- _.forEach(proxyEvents, function(event) {
25
- // all handlers for the http-proxy events are prefixed with 'on'.
26
- // loop through options and try to find these handlers
27
- // and add them to the handlers object for subscription in init().
28
- var eventName = _.camelCase('on ' + event);
29
- var fnHandler = _.get(opts, eventName);
19
+ function getProxyEventHandlers (opts) {
20
+ // https://github.com/nodejitsu/node-http-proxy#listening-for-proxy-events
21
+ var proxyEvents = ['error', 'proxyReq', 'proxyReqWs', 'proxyRes', 'open', 'close']
22
+ var handlers = {}
30
23
 
31
- if (_.isFunction(fnHandler)) {
32
- handlers[event] = fnHandler;
33
- }
34
- });
24
+ _.forEach(proxyEvents, function (event) {
25
+ // all handlers for the http-proxy events are prefixed with 'on'.
26
+ // loop through options and try to find these handlers
27
+ // and add them to the handlers object for subscription in init().
28
+ var eventName = _.camelCase('on ' + event)
29
+ var fnHandler = _.get(opts, eventName)
35
30
 
36
- // add default error handler in absence of error handler
37
- if (!_.isFunction(handlers.error)) {
38
- handlers.error = defaultErrorHandler;
31
+ if (_.isFunction(fnHandler)) {
32
+ handlers[event] = fnHandler
39
33
  }
34
+ })
40
35
 
41
- // add default close handler in absence of close handler
42
- if (!_.isFunction(handlers.close)) {
43
- handlers.close = logClose;
44
- }
36
+ // add default error handler in absence of error handler
37
+ if (!_.isFunction(handlers.error)) {
38
+ handlers.error = defaultErrorHandler
39
+ }
45
40
 
46
- return handlers;
47
- };
41
+ // add default close handler in absence of close handler
42
+ if (!_.isFunction(handlers.close)) {
43
+ handlers.close = logClose
44
+ }
45
+
46
+ return handlers
47
+ }
48
48
 
49
- function defaultErrorHandler(err, req, res) {
50
- var host = (req.headers && req.headers.host);
51
- var code = err.code;
49
+ function defaultErrorHandler (err, req, res) {
50
+ var host = (req.headers && req.headers.host)
51
+ var code = err.code
52
52
 
53
- if (res.writeHead && !res.headersSent) {
54
- if (/HPE_INVALID/.test(code)) {
55
- res.writeHead(502);
56
- } else {
57
- switch(code) {
58
- case 'ECONNRESET':
59
- case 'ENOTFOUND':
60
- case 'ECONNREFUSED':
61
- res.writeHead(504);
62
- break;
63
- default: res.writeHead(500);
64
- }
65
- }
53
+ if (res.writeHead && !res.headersSent) {
54
+ if (/HPE_INVALID/.test(code)) {
55
+ res.writeHead(502)
56
+ } else {
57
+ switch (code) {
58
+ case 'ECONNRESET':
59
+ case 'ENOTFOUND':
60
+ case 'ECONNREFUSED':
61
+ res.writeHead(504)
62
+ break
63
+ default: res.writeHead(500)
64
+ }
66
65
  }
66
+ }
67
67
 
68
- res.end('Error occured while trying to proxy to: ' + host + req.url);
68
+ res.end('Error occured while trying to proxy to: ' + host + req.url)
69
69
  }
70
70
 
71
- function logClose(req, socket, head) {
72
- // view disconnected websocket connections
73
- logger.info('[HPM] Client disconnected');
71
+ function logClose (req, socket, head) {
72
+ // view disconnected websocket connections
73
+ logger.info('[HPM] Client disconnected')
74
74
  }