From d231b9fb66364a2f3f4032b461ff52942c48d8d2 Mon Sep 17 00:00:00 2001
From: chimurai <655241+chimurai@users.noreply.github.com>
Date: Sat, 19 Feb 2022 23:38:52 +0100
Subject: [PATCH 01/64] feat: remove shorthand usage [BREAKING CHANGE] (#716)
---
README.md | 63 ++++-----------
recipes/shorthand.md | 62 ---------------
src/config-factory.ts | 29 -------
test/e2e/http-proxy-middleware.spec.ts | 14 ----
test/e2e/websocket.spec.ts | 26 -------
test/unit/config-factory.spec.ts | 103 +------------------------
6 files changed, 17 insertions(+), 280 deletions(-)
delete mode 100644 recipes/shorthand.md
diff --git a/README.md b/README.md
index 4eb8e111..d4560a12 100644
--- a/README.md
+++ b/README.md
@@ -57,13 +57,12 @@ _All_ `http-proxy` [options](https://github.com/nodejitsu/node-http-proxy#option
- [Install](#install)
- [Core concept](#core-concept)
- [Example](#example)
+ - [app.use(path, proxy)](#appusepath-proxy)
- [Context matching](#context-matching)
- [Options](#options)
- [http-proxy-middleware options](#http-proxy-middleware-options)
- [http-proxy events](#http-proxy-events)
- [http-proxy options](#http-proxy-options)
-- [Shorthand](#shorthand)
- - [app.use(path, proxy)](#appusepath-proxy)
- [WebSocket](#websocket)
- [External WebSocket upgrade](#external-websocket-upgrade)
- [Intercept and manipulate requests](#intercept-and-manipulate-requests)
@@ -104,15 +103,6 @@ const apiProxy = createProxyMiddleware('/api', { target: 'http://www.example.org
(full list of [`http-proxy-middleware` configuration options](#options))
-#### createProxyMiddleware(uri [, config])
-
-```javascript
-// shorthand syntax for the example above:
-const apiProxy = createProxyMiddleware('http://www.example.org/api');
-```
-
-More about the [shorthand configuration](#shorthand).
-
## Example
An example with `express` server.
@@ -148,6 +138,21 @@ app.use('/api', exampleProxy);
app.listen(3000);
```
+### app.use(path, proxy)
+
+If you want to use the server's `app.use` `path` parameter to match requests;
+Create and mount the proxy without the http-proxy-middleware `context` parameter:
+
+```javascript
+app.use('/api', createProxyMiddleware({ target: 'http://www.example.org', changeOrigin: true }));
+```
+
+`app.use` documentation:
+
+- express: http://expressjs.com/en/4x/api.html#app.use
+- connect: https://github.com/senchalabs/connect#mount-middleware
+- polka: https://github.com/lukeed/polka#usebase-fn
+
## Context matching
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.
@@ -422,47 +427,11 @@ The following options are provided by the underlying [http-proxy](https://github
};
```
-## Shorthand
-
-Use the shorthand syntax when verbose configuration is not needed. The `context` and `option.target` will be automatically configured when shorthand is used. Options can still be used if needed.
-
-```javascript
-createProxyMiddleware('http://www.example.org:8000/api');
-// createProxyMiddleware('/api', {target: 'http://www.example.org:8000'});
-
-createProxyMiddleware('http://www.example.org:8000/api/books/*/**.json');
-// createProxyMiddleware('/api/books/*/**.json', {target: 'http://www.example.org:8000'});
-
-createProxyMiddleware('http://www.example.org:8000/api', { changeOrigin: true });
-// createProxyMiddleware('/api', {target: 'http://www.example.org:8000', changeOrigin: true});
-```
-
-### app.use(path, proxy)
-
-If you want to use the server's `app.use` `path` parameter to match requests;
-Create and mount the proxy without the http-proxy-middleware `context` parameter:
-
-```javascript
-app.use('/api', createProxyMiddleware({ target: 'http://www.example.org', changeOrigin: true }));
-```
-
-`app.use` documentation:
-
-- express: http://expressjs.com/en/4x/api.html#app.use
-- connect: https://github.com/senchalabs/connect#mount-middleware
-- polka: https://github.com/lukeed/polka#usebase-fn
-
## WebSocket
```javascript
// verbose api
createProxyMiddleware('/', { target: 'http://echo.websocket.org', ws: true });
-
-// shorthand
-createProxyMiddleware('http://echo.websocket.org', { ws: true });
-
-// shorter shorthand
-createProxyMiddleware('ws://echo.websocket.org');
```
### External WebSocket upgrade
diff --git a/recipes/shorthand.md b/recipes/shorthand.md
deleted file mode 100644
index 30ca8b7f..00000000
--- a/recipes/shorthand.md
+++ /dev/null
@@ -1,62 +0,0 @@
-# Shorthand
-
-This example will create a proxy middleware using the shorthand notation.
-
-The http-proxy-middleware `context` and `config.target` will be set automatically.
-
-```javascript
-const { createProxyMiddleware } = require('http-proxy-middleware');
-
-const apiProxy = createProxyMiddleware('http://localhost:3000/api');
-
-// equivalent:
-// const apiProxy = createProxyMiddleware('/api', {target:'http://localhost:3000'});
-```
-
-## Shorthand - Wildcard context
-
-This example will create a proxy middleware with shorthand wildcard context.
-
-```javascript
-const { createProxyMiddleware } = require('http-proxy-middleware');
-
-const apiProxy = createProxyMiddleware('http://localhost:3000/api/books/*/**.json');
-// equals:
-// const apiProxy = createProxyMiddleware('/api/books/*/**.json', {target:'http://localhost:3000'});
-```
-
-## Shorthand with additional configuration
-
-This example will create a proxy middleware with shorthand and additional configuration.
-
-```javascript
-const { createProxyMiddleware } = require('http-proxy-middleware');
-
-const apiProxy = createProxyMiddleware('http://localhost:3000/api', { changeOrigin: true });
-// equals:
-// const apiProxy = createProxyMiddleware('/api', {target:'http://localhost:3000', {changeOrigin:true}});
-```
-
-## Shorthand - WebSocket
-
-This example will create a proxy middleware with shorthand and additional configuration for WebSocket support.
-
-```javascript
-const { createProxyMiddleware } = require('http-proxy-middleware');
-
-const apiProxy = createProxyMiddleware('http://localhost:3000/api', { ws: true });
-// equals:
-// const apiProxy = createProxyMiddleware('/api', {target:'http://localhost:3000', ws: true});
-```
-
-## Shorthand - WebSocket only
-
-This example will create a proxy middleware with websocket shorthand only configuration.
-
-```javascript
-const { createProxyMiddleware } = require('http-proxy-middleware');
-
-const apiProxy = createProxyMiddleware('ws://localhost:3000/api');
-// equals:
-// const apiProxy = createProxyMiddleware('/api', {target:'ws://localhost:3000', ws: true});
-```
diff --git a/src/config-factory.ts b/src/config-factory.ts
index f57dd702..3053dfa2 100644
--- a/src/config-factory.ts
+++ b/src/config-factory.ts
@@ -1,5 +1,4 @@
import isPlainObj = require('is-plain-obj');
-import * as url from 'url';
import { ERRORS } from './errors';
import { getInstance } from './logger';
import { Filter, Options } from './types';
@@ -22,17 +21,6 @@ export function createConfig(context, opts?: Options): Config {
// app.use('/api', proxy('http://localhost:9000'));
// app.use(proxy('http://localhost:9000/api'));
- } else if (isStringShortHand(context)) {
- const oUrl = url.parse(context);
- const target = [oUrl.protocol, '//', oUrl.host].join('');
-
- config.context = oUrl.pathname || '/';
- config.options = Object.assign(config.options, { target }, opts);
-
- if (oUrl.protocol === 'ws:' || oUrl.protocol === 'wss:') {
- config.options.ws = true;
- }
- // app.use('/api', proxy({target:'http://localhost:9000'}));
} else {
config.context = context;
config.options = Object.assign(config.options, opts);
@@ -47,23 +35,6 @@ export function createConfig(context, opts?: Options): Config {
return config;
}
-/**
- * Checks if a String only target/config is provided.
- * This can be just the host or with the optional path.
- *
- * @example
- * app.use('/api', proxy('http://localhost:9000'));
- * app.use(proxy('http://localhost:9000/api'));
- *
- * @param {String} context [description]
- * @return {Boolean} [description]
- */
-function isStringShortHand(context: Filter) {
- if (typeof context === 'string') {
- return !!url.parse(context).host;
- }
-}
-
/**
* Checks if a Object only config is provided, without a context.
* In this case the all paths will be proxied.
diff --git a/test/e2e/http-proxy-middleware.spec.ts b/test/e2e/http-proxy-middleware.spec.ts
index 4685cc07..772430c1 100644
--- a/test/e2e/http-proxy-middleware.spec.ts
+++ b/test/e2e/http-proxy-middleware.spec.ts
@@ -389,20 +389,6 @@ describe('E2E http-proxy-middleware', () => {
});
});
- describe('shorthand usage', () => {
- beforeEach(() => {
- agent = request(
- createApp(createProxyMiddleware(`http://localhost:${mockTargetServer.port}/api`))
- );
- });
-
- it('should have proxy with shorthand configuration', async () => {
- await mockTargetServer.get('/api/foo/bar').thenReply(200, 'HELLO /api/foo/bar');
- const response = await agent.get(`/api/foo/bar`).expect(200);
- expect(response.text).toBe('HELLO /api/foo/bar');
- });
- });
-
describe('express with path + proxy', () => {
beforeEach(() => {
agent = request(
diff --git a/test/e2e/websocket.spec.ts b/test/e2e/websocket.spec.ts
index ad946d4a..d3f15e8a 100644
--- a/test/e2e/websocket.spec.ts
+++ b/test/e2e/websocket.spec.ts
@@ -95,32 +95,6 @@ describe('E2E WebSocket proxy', () => {
});
});
- describe('option.ws with external server "upgrade" and shorthand usage', () => {
- beforeEach(() => {
- proxyServer = createApp(
- createProxyMiddleware(`ws://localhost:${WS_SERVER_PORT}`, {
- pathRewrite: { '^/socket': '' },
- })
- ).listen(SERVER_PORT);
-
- proxyServer.on('upgrade', proxyMiddleware.upgrade);
- });
-
- beforeEach((done) => {
- ws = new WebSocket(`ws://localhost:${SERVER_PORT}/socket`);
- ws.on('open', done);
- });
-
- it('should proxy to path', (done) => {
- ws.on('message', (data, isBinary) => {
- const message = isBinary ? data : data.toString();
- expect(message).toBe('foobar');
- done();
- });
- ws.send('foobar');
- });
- });
-
describe('with router and pathRewrite', () => {
beforeEach(() => {
// override
diff --git a/test/unit/config-factory.spec.ts b/test/unit/config-factory.spec.ts
index e2f18243..610ec3bc 100644
--- a/test/unit/config-factory.spec.ts
+++ b/test/unit/config-factory.spec.ts
@@ -26,92 +26,7 @@ describe('configFactory', () => {
});
});
- describe('shorthand String', () => {
- describe('shorthand String config', () => {
- beforeEach(() => {
- result = createConfig('http://www.example.org:8000/api');
- });
-
- it('should return config object', () => {
- expect(Object.keys(result)).toEqual(['context', 'options']);
- });
-
- it('should return config object with context', () => {
- expect(result.context).toBe('/api');
- });
-
- it('should return config object with options', () => {
- expect(result.options).toEqual({
- target: 'http://www.example.org:8000',
- });
- });
- });
-
- describe('shorthand String config for whole domain', () => {
- beforeEach(() => {
- result = createConfig('http://www.example.org:8000');
- });
-
- it('should return config object with context', () => {
- expect(result.context).toBe('/');
- });
- });
-
- describe('shorthand String config for websocket url', () => {
- beforeEach(() => {
- result = createConfig('ws://www.example.org:8000');
- });
-
- it('should return config object with context', () => {
- expect(result.context).toBe('/');
- });
-
- it('should return options with ws = true', () => {
- expect(result.options.ws).toBe(true);
- });
- });
-
- describe('shorthand String config for secure websocket url', () => {
- beforeEach(() => {
- result = createConfig('wss://www.example.org:8000');
- });
-
- it('should return config object with context', () => {
- expect(result.context).toBe('/');
- });
-
- it('should return options with ws = true', () => {
- expect(result.options.ws).toBe(true);
- });
- });
-
- describe('shorthand String config with globbing', () => {
- beforeEach(() => {
- result = createConfig('http://www.example.org:8000/api/*.json');
- });
-
- it('should return config object with context', () => {
- expect(result.context).toBe('/api/*.json');
- });
- });
-
- describe('shorthand String config with options', () => {
- beforeEach(() => {
- result = createConfig('http://www.example.org:8000/api', {
- changeOrigin: true,
- });
- });
-
- it('should return config object with additional options', () => {
- expect(result.options).toEqual({
- changeOrigin: true,
- target: 'http://www.example.org:8000',
- });
- });
- });
- });
-
- describe('shorthand Object config', () => {
+ describe('Object config', () => {
beforeEach(() => {
result = createConfig({ target: 'http://www.example.org:8000' });
});
@@ -156,21 +71,5 @@ describe('configFactory', () => {
expect(fn).not.toThrowError(Error);
});
});
-
- describe('faulty config. mixing classic with shorthand', () => {
- beforeEach(() => {
- result = createConfig('http://localhost:3000/api', {
- target: 'http://localhost:8000',
- });
- });
-
- it('should use the target in the configuration as target', () => {
- expect(result.options.target).toBe('http://localhost:8000');
- });
-
- it('should not use the host from the shorthand as target', () => {
- expect(result.options.target).not.toBe('http://localhost:3000');
- });
- });
});
});
From f990e749124dad032004de50d2de39eb16c4da12 Mon Sep 17 00:00:00 2001
From: chimurai <655241+chimurai@users.noreply.github.com>
Date: Sun, 27 Feb 2022 12:28:48 +0100
Subject: [PATCH 02/64] feat(option): refactor context to pathFilter option
[BREAKING CHANGE] (#722)
---
README.md | 234 +++++++--------
examples/browser-sync/index.js | 3 +-
examples/websocket/index.html | 2 +-
examples/websocket/index.js | 4 +-
recipes/README.md | 10 +-
recipes/basic.md | 8 +-
.../{context-matching.md => pathFilter.md} | 38 +--
src/config-factory.ts | 61 ----
src/configuration.ts | 23 ++
src/errors.ts | 2 +-
src/http-proxy-middleware.ts | 29 +-
src/index.ts | 13 +-
src/{context-matcher.ts => path-filter.ts} | 44 +--
src/types.ts | 1 +
test/e2e/express-router.spec.ts | 3 +-
test/e2e/http-proxy-middleware.spec.ts | 48 ++--
test/e2e/websocket.spec.ts | 5 +-
test/types.spec.ts | 8 +-
test/unit/config-factory.spec.ts | 75 -----
test/unit/configuration.spec.ts | 36 +++
test/unit/context-matcher.spec.ts | 266 ------------------
test/unit/path-filter.spec.ts | 254 +++++++++++++++++
22 files changed, 558 insertions(+), 609 deletions(-)
rename recipes/{context-matching.md => pathFilter.md} (69%)
delete mode 100644 src/config-factory.ts
create mode 100644 src/configuration.ts
rename src/{context-matcher.ts => path-filter.ts} (55%)
delete mode 100644 test/unit/config-factory.spec.ts
create mode 100644 test/unit/configuration.spec.ts
delete mode 100644 test/unit/context-matcher.spec.ts
create mode 100644 test/unit/path-filter.spec.ts
diff --git a/README.md b/README.md
index d4560a12..905de29e 100644
--- a/README.md
+++ b/README.md
@@ -54,15 +54,20 @@ _All_ `http-proxy` [options](https://github.com/nodejitsu/node-http-proxy#option
## Table of Contents
+
+
- [Install](#install)
- [Core concept](#core-concept)
-- [Example](#example)
+- [Express Server Example](#express-server-example)
- [app.use(path, proxy)](#appusepath-proxy)
-- [Context matching](#context-matching)
- [Options](#options)
- - [http-proxy-middleware options](#http-proxy-middleware-options)
- - [http-proxy events](#http-proxy-events)
- - [http-proxy options](#http-proxy-options)
+ - [`pathFilter` (string, []string, glob, []glob, function)](#pathfilter-string-string-glob-glob-function)
+ - [`pathRewrite` (object/function)](#pathrewrite-objectfunction)
+ - [`router` (object/function)](#router-objectfunction)
+ - [`logLevel` (string)](#loglevel-string)
+ - [`logProvider` (function)](#logprovider-function)
+- [`http-proxy` events](#http-proxy-events)
+- [`http-proxy` options](#http-proxy-options)
- [WebSocket](#websocket)
- [External WebSocket upgrade](#external-websocket-upgrade)
- [Intercept and manipulate requests](#intercept-and-manipulate-requests)
@@ -74,36 +79,36 @@ _All_ `http-proxy` [options](https://github.com/nodejitsu/node-http-proxy#option
- [Changelog](#changelog)
- [License](#license)
+
+
## Install
-```bash
-$ npm install --save-dev http-proxy-middleware
+```shell
+npm install --save-dev http-proxy-middleware
```
## Core concept
-Proxy middleware configuration.
-
-#### createProxyMiddleware([context,] config)
+Create and configure a proxy middleware with: `createProxyMiddleware(config)`.
```javascript
const { createProxyMiddleware } = require('http-proxy-middleware');
-const apiProxy = createProxyMiddleware('/api', { target: 'http://www.example.org' });
-// \____/ \_____________________________/
-// | |
-// context options
+const apiProxy = createProxyMiddleware({
+ pathFilter: '/api',
+ target: 'http://www.example.org',
+});
// 'apiProxy' is now ready to be used as middleware in a server.
```
-- **context**: Determine which requests should be proxied to the target host.
- (more on [context matching](#context-matching))
+- **options.pathFilter**: Determine which requests should be proxied to the target host.
+ (more on [path filter](#path-filter))
- **options.target**: target host to proxy to. _(protocol + host)_
-(full list of [`http-proxy-middleware` configuration options](#options))
+- see full list of [`http-proxy-middleware` configuration options](#options)
-## Example
+## Express Server Example
An example with `express` server.
@@ -129,7 +134,7 @@ const options = {
},
};
-// create the proxy (without context)
+// create the proxy
const exampleProxy = createProxyMiddleware(options);
// mount `exampleProxy` in web server
@@ -140,8 +145,8 @@ app.listen(3000);
### app.use(path, proxy)
-If you want to use the server's `app.use` `path` parameter to match requests;
-Create and mount the proxy without the http-proxy-middleware `context` parameter:
+If you want to use the server's `app.use` `path` parameter to match requests.
+Use `pathFilter` option to further include/exclude requests which you want to proxy.
```javascript
app.use('/api', createProxyMiddleware({ target: 'http://www.example.org', changeOrigin: true }));
@@ -153,11 +158,15 @@ app.use('/api', createProxyMiddleware({ target: 'http://www.example.org', change
- connect: https://github.com/senchalabs/connect#mount-middleware
- polka: https://github.com/lukeed/polka#usebase-fn
-## Context matching
+## Options
+
+http-proxy-middleware options:
+
+### `pathFilter` (string, []string, glob, []glob, function)
-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.
+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.
-[RFC 3986 `path`](https://tools.ietf.org/html/rfc3986#section-3.3) is used for context matching.
+[RFC 3986 `path`](https://tools.ietf.org/html/rfc3986#section-3.3) is used in `pathFilter`.
```ascii
foo://example.com:8042/over/there?name=ferret#nose
@@ -169,23 +178,22 @@ Providing an alternative way to decide which requests should be proxied; In case
- **path matching**
- `createProxyMiddleware({...})` - matches any path, all requests will be proxied.
- - `createProxyMiddleware('/', {...})` - matches any path, all requests will be proxied.
- - `createProxyMiddleware('/api', {...})` - matches paths starting with `/api`
+ - `createProxyMiddleware({ pathFilter: '/api', ...})` - matches paths starting with `/api`
- **multiple path matching**
- - `createProxyMiddleware(['/api', '/ajax', '/someotherpath'], {...})`
+ - `createProxyMiddleware({ pathFilter: ['/api', '/ajax', '/someotherpath'], ...})`
- **wildcard path matching**
For fine-grained control you can use wildcard matching. Glob pattern matching is done by _micromatch_. Visit [micromatch](https://www.npmjs.com/package/micromatch) or [glob](https://www.npmjs.com/package/glob) for more globbing examples.
- - `createProxyMiddleware('**', {...})` matches any path, all requests will be proxied.
- - `createProxyMiddleware('**/*.html', {...})` matches any path which ends with `.html`
- - `createProxyMiddleware('/*.html', {...})` matches paths directly under path-absolute
- - `createProxyMiddleware('/api/**/*.html', {...})` matches requests ending with `.html` in the path of `/api`
- - `createProxyMiddleware(['/api/**', '/ajax/**'], {...})` combine multiple patterns
- - `createProxyMiddleware(['/api/**', '!**/bad.json'], {...})` exclusion
+ - `createProxyMiddleware({ pathFilter: '**', ...})` matches any path, all requests will be proxied.
+ - `createProxyMiddleware({ pathFilter: '**/*.html', ...})` matches any path which ends with `.html`
+ - `createProxyMiddleware({ pathFilter: '/*.html', ...})` matches paths directly under path-absolute
+ - `createProxyMiddleware({ pathFilter: '/api/**/*.html', ...})` matches requests ending with `.html` in the path of `/api`
+ - `createProxyMiddleware({ pathFilter: ['/api/**', '/ajax/**'], ...})` combine multiple patterns
+ - `createProxyMiddleware({ pathFilter: ['/api/**', '!**/bad.json'], ...})` exclusion
**Note**: In multiple path matching, you cannot use string paths and wildcard paths together.
@@ -197,8 +205,8 @@ Providing an alternative way to decide which requests should be proxied; In case
/**
* @return {Boolean}
*/
- const filter = function (pathname, req) {
- return pathname.match('^/api') && req.method === 'GET';
+ const filter = function (path, req) {
+ return path.match('^/api') && req.method === 'GET';
};
const apiProxy = createProxyMiddleware(filter, {
@@ -206,95 +214,101 @@ Providing an alternative way to decide which requests should be proxied; In case
});
```
-## Options
+### `pathRewrite` (object/function)
-### http-proxy-middleware options
+Rewrite target's url path. Object-keys will be used as _RegExp_ to match paths.
-- **option.pathRewrite**: object/function, rewrite target's url path. Object-keys will be used as _RegExp_ to match paths.
+```javascript
+// rewrite path
+pathRewrite: {'^/old/api' : '/new/api'}
- ```javascript
- // rewrite path
- pathRewrite: {'^/old/api' : '/new/api'}
+// remove path
+pathRewrite: {'^/remove/api' : ''}
- // remove path
- pathRewrite: {'^/remove/api' : ''}
+// add base path
+pathRewrite: {'^/' : '/basepath/'}
- // add base path
- pathRewrite: {'^/' : '/basepath/'}
+// custom rewriting
+pathRewrite: function (path, req) { return path.replace('/api', '/base/api') }
- // custom rewriting
- pathRewrite: function (path, req) { return path.replace('/api', '/base/api') }
+// custom rewriting, returning Promise
+pathRewrite: async function (path, req) {
+ const should_add_something = await httpRequestToDecideSomething(path);
+ if (should_add_something) path += "something";
+ return path;
+}
+```
- // custom rewriting, returning Promise
- pathRewrite: async function (path, req) {
- const should_add_something = await httpRequestToDecideSomething(path);
- if (should_add_something) path += "something";
- return path;
- }
- ```
+### `router` (object/function)
-- **option.router**: object/function, re-target `option.target` for specific requests.
+Re-target `option.target` for specific requests.
- ```javascript
- // Use `host` and/or `path` to match requests. First match will be used.
- // The order of the configuration matters.
- router: {
- 'integration.localhost:3000' : 'http://localhost:8001', // host only
- 'staging.localhost:3000' : 'http://localhost:8002', // host only
- 'localhost:3000/api' : 'http://localhost:8003', // host + path
- '/rest' : 'http://localhost:8004' // path only
- }
+```javascript
+// Use `host` and/or `path` to match requests. First match will be used.
+// The order of the configuration matters.
+router: {
+ 'integration.localhost:3000' : 'http://localhost:8001', // host only
+ 'staging.localhost:3000' : 'http://localhost:8002', // host only
+ 'localhost:3000/api' : 'http://localhost:8003', // host + path
+ '/rest' : 'http://localhost:8004' // path only
+}
+
+// Custom router function (string target)
+router: function(req) {
+ return 'http://localhost:8004';
+}
+
+// Custom router function (target object)
+router: function(req) {
+ return {
+ protocol: 'https:', // The : is required
+ host: 'localhost',
+ port: 8004
+ };
+}
- // Custom router function (string target)
- router: function(req) {
- return 'http://localhost:8004';
- }
+// Asynchronous router function which returns promise
+router: async function(req) {
+ const url = await doSomeIO();
+ return url;
+}
+```
- // Custom router function (target object)
- router: function(req) {
- return {
- protocol: 'https:', // The : is required
- host: 'localhost',
- port: 8004
- };
- }
+### `logLevel` (string)
- // Asynchronous router function which returns promise
- router: async function(req) {
- const url = await doSomeIO();
- return url;
- }
- ```
+Default: `'info'`
-- **option.logLevel**: string, ['debug', 'info', 'warn', 'error', 'silent']. Default: `'info'`
+Values: ['debug', 'info', 'warn', 'error', 'silent'].
-- **option.logProvider**: function, modify or replace log provider. Default: `console`.
+### `logProvider` (function)
- ```javascript
- // simple replace
- function logProvider(provider) {
- // replace the default console log provider.
- return require('winston');
- }
- ```
+Modify or replace log provider. Default: `console`.
- ```javascript
- // verbose replacement
- function logProvider(provider) {
- const logger = new (require('winston').Logger)();
-
- const myCustomProvider = {
- log: logger.log,
- debug: logger.debug,
- info: logger.info,
- warn: logger.warn,
- error: logger.error,
- };
- return myCustomProvider;
- }
- ```
+```javascript
+// simple replace
+function logProvider(provider) {
+ // replace the default console log provider.
+ return require('winston');
+}
+```
+
+```javascript
+// verbose replacement
+function logProvider(provider) {
+ const logger = new (require('winston').Logger)();
+
+ const myCustomProvider = {
+ log: logger.log,
+ debug: logger.debug,
+ info: logger.info,
+ warn: logger.warn,
+ error: logger.error,
+ };
+ return myCustomProvider;
+}
+```
-### http-proxy events
+## `http-proxy` events
Subscribe to [http-proxy events](https://github.com/nodejitsu/node-http-proxy#listening-for-proxy-events):
@@ -355,7 +369,7 @@ Subscribe to [http-proxy events](https://github.com/nodejitsu/node-http-proxy#li
}
```
-### http-proxy options
+## `http-proxy` options
The following options are provided by the underlying [http-proxy](https://github.com/nodejitsu/node-http-proxy#options) library.
@@ -431,7 +445,7 @@ The following options are provided by the underlying [http-proxy](https://github
```javascript
// verbose api
-createProxyMiddleware('/', { target: 'http://echo.websocket.org', ws: true });
+createProxyMiddleware({ pathFilter: '/', target: 'http://echo.websocket.org', ws: true });
```
### External WebSocket upgrade
@@ -439,7 +453,7 @@ createProxyMiddleware('/', { target: 'http://echo.websocket.org', ws: true });
In the previous WebSocket examples, http-proxy-middleware relies on a initial http request in order to listen to the http `upgrade` event. If you need to proxy WebSockets without the initial http request, you can subscribe to the server's http `upgrade` event manually.
```javascript
-const wsProxy = createProxyMiddleware('ws://echo.websocket.org', { changeOrigin: true });
+const wsProxy = createProxyMiddleware({ target: 'ws://echo.websocket.org', changeOrigin: true });
const app = express();
app.use(wsProxy);
diff --git a/examples/browser-sync/index.js b/examples/browser-sync/index.js
index 1705647c..2342b3bd 100644
--- a/examples/browser-sync/index.js
+++ b/examples/browser-sync/index.js
@@ -7,8 +7,9 @@ const { createProxyMiddleware } = require('../../dist'); // require('http-proxy-
/**
* Configure proxy middleware
*/
-const jsonPlaceholderProxy = createProxyMiddleware('/users', {
+const jsonPlaceholderProxy = createProxyMiddleware({
target: 'http://jsonplaceholder.typicode.com',
+ pathFilter: '/users',
changeOrigin: true, // for vhosted sites, changes host header to match to target's host
logLevel: 'debug',
});
diff --git a/examples/websocket/index.html b/examples/websocket/index.html
index 38674154..b295129c 100644
--- a/examples/websocket/index.html
+++ b/examples/websocket/index.html
@@ -21,7 +21,7 @@