Skip to content

Commit e74499e

Browse files
committed
fix: server mounting [BREAKING CHANGE]
1 parent 8a2e7a6 commit e74499e

File tree

9 files changed

+69
-68
lines changed

9 files changed

+69
-68
lines changed

README.md

+30-34
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,14 @@ const { createProxyMiddleware } = require('http-proxy-middleware');
2828

2929
const app = express();
3030

31-
app.use('/api', createProxyMiddleware({ target: 'http://www.example.org', changeOrigin: true }));
31+
app.use(
32+
'/api',
33+
createProxyMiddleware({ target: 'http://www.example.org/secret', changeOrigin: true })
34+
);
3235
app.listen(3000);
3336

34-
// http://localhost:3000/api/foo/bar -> http://www.example.org/api/foo/bar
37+
// proxy and change the base path from "/api" to "/secret"
38+
// http://localhost:3000/api/foo/bar -> http://www.example.org/secret/foo/bar
3539
```
3640

3741
```typescript
@@ -42,9 +46,13 @@ import { createProxyMiddleware, Filter, Options, RequestHandler } from 'http-pro
4246

4347
const app = express();
4448

45-
app.use('/api', createProxyMiddleware({ target: 'http://www.example.org', changeOrigin: true }));
49+
app.use(
50+
'/api',
51+
createProxyMiddleware({ target: 'http://www.example.org/api', changeOrigin: true })
52+
);
4653
app.listen(3000);
4754

55+
// proxy and keep the same base path "/api"
4856
// http://localhost:3000/api/foo/bar -> http://www.example.org/api/foo/bar
4957
```
5058

@@ -57,7 +65,7 @@ _All_ `http-proxy` [options](https://github.com/nodejitsu/node-http-proxy#option
5765
<!-- // spell-checker:disable -->
5866

5967
- [Install](#install)
60-
- [Core concept](#core-concept)
68+
- [Basic usage](#basic-usage)
6169
- [Express Server Example](#express-server-example)
6270
- [app.use(path, proxy)](#appusepath-proxy)
6371
- [Options](#options)
@@ -87,24 +95,23 @@ _All_ `http-proxy` [options](https://github.com/nodejitsu/node-http-proxy#option
8795
npm install --save-dev http-proxy-middleware
8896
```
8997

90-
## Core concept
98+
## Basic usage
9199

92100
Create and configure a proxy middleware with: `createProxyMiddleware(config)`.
93101

94102
```javascript
95103
const { createProxyMiddleware } = require('http-proxy-middleware');
96104

97105
const apiProxy = createProxyMiddleware({
98-
pathFilter: '/api',
99106
target: 'http://www.example.org',
107+
changeOrigin: true,
100108
});
101109

102110
// 'apiProxy' is now ready to be used as middleware in a server.
103111
```
104112

105-
- **options.pathFilter**: Determine which requests should be proxied to the target host.
106-
(more on [path filter](#path-filter))
107113
- **options.target**: target host to proxy to. _(protocol + host)_
114+
- **options.changeOrigin**: for virtual hosted sites
108115

109116
- see full list of [`http-proxy-middleware` configuration options](#options)
110117

@@ -117,28 +124,19 @@ An example with `express` server.
117124
const express = require('express');
118125
const { createProxyMiddleware } = require('http-proxy-middleware');
119126

127+
const app = express();
128+
120129
// proxy middleware options
121130
/** @type {import('http-proxy-middleware/dist/types').Options} */
122131
const options = {
123-
target: 'http://www.example.org', // target host
132+
target: 'http://www.example.org/api', // target host with the same base path
124133
changeOrigin: true, // needed for virtual hosted sites
125-
ws: true, // proxy websockets
126-
pathRewrite: {
127-
'^/api/old-path': '/api/new-path', // rewrite path
128-
'^/api/remove/path': '/path', // remove base path
129-
},
130-
router: {
131-
// when request.headers.host == 'dev.localhost:3000',
132-
// override target 'http://www.example.org' to 'http://localhost:8000'
133-
'dev.localhost:3000': 'http://localhost:8000',
134-
},
135134
};
136135

137136
// create the proxy
138137
const exampleProxy = createProxyMiddleware(options);
139138

140139
// mount `exampleProxy` in web server
141-
const app = express();
142140
app.use('/api', exampleProxy);
143141
app.listen(3000);
144142
```
@@ -149,7 +147,13 @@ If you want to use the server's `app.use` `path` parameter to match requests.
149147
Use `pathFilter` option to further include/exclude requests which you want to proxy.
150148

151149
```javascript
152-
app.use('/api', createProxyMiddleware({ target: 'http://www.example.org', changeOrigin: true }));
150+
app.use(
151+
createProxyMiddleware({
152+
target: 'http://www.example.org/api',
153+
changeOrigin: true,
154+
pathFilter: '/api/proxy-only-this-path',
155+
})
156+
);
153157
```
154158

155159
`app.use` documentation:
@@ -164,20 +168,11 @@ http-proxy-middleware options:
164168

165169
### `pathFilter` (string, []string, glob, []glob, function)
166170

167-
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.
168-
169-
[RFC 3986 `path`](https://tools.ietf.org/html/rfc3986#section-3.3) is used in `pathFilter`.
170-
171-
```ascii
172-
foo://example.com:8042/over/there?name=ferret#nose
173-
\_/ \______________/\_________/ \_________/ \__/
174-
| | | | |
175-
scheme authority path query fragment
176-
```
171+
Narrow down which requests should be proxied. The `path` used for filtering is the `request.url` pathname. In Express, this is the `path` relative to the mount-point of the proxy.
177172

178173
- **path matching**
179174

180-
- `createProxyMiddleware({...})` - matches any path, all requests will be proxied.
175+
- `createProxyMiddleware({...})` - matches any path, all requests will be proxied when `pathFilter` is not configured.
181176
- `createProxyMiddleware({ pathFilter: '/api', ...})` - matches paths starting with `/api`
182177

183178
- **multiple path matching**
@@ -205,12 +200,13 @@ Decide which requests should be proxied; In case you are not able to use the ser
205200
/**
206201
* @return {Boolean}
207202
*/
208-
const filter = function (path, req) {
203+
const pathFilter = function (path, req) {
209204
return path.match('^/api') && req.method === 'GET';
210205
};
211206

212-
const apiProxy = createProxyMiddleware(filter, {
207+
const apiProxy = createProxyMiddleware({
213208
target: 'http://www.example.org',
209+
pathFilter: pathFilter,
214210
});
215211
```
216212

examples/connect/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const { createProxyMiddleware } = require('../../dist'); // require('http-proxy-
99
* Configure proxy middleware
1010
*/
1111
const jsonPlaceholderProxy = createProxyMiddleware({
12-
target: 'http://jsonplaceholder.typicode.com',
12+
target: 'http://jsonplaceholder.typicode.com/users',
1313
changeOrigin: true, // for vhosted sites, changes host header to match to target's host
1414
logLevel: 'debug',
1515
});

examples/express/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const { createProxyMiddleware } = require('../../dist'); // require('http-proxy-
88
* Configure proxy middleware
99
*/
1010
const jsonPlaceholderProxy = createProxyMiddleware({
11-
target: 'http://jsonplaceholder.typicode.com',
11+
target: 'http://jsonplaceholder.typicode.com/users',
1212
changeOrigin: true, // for vhosted sites, changes host header to match to target's host
1313
logLevel: 'debug',
1414
});

recipes/async-response.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Sometimes we need the ability to modify the response headers of the response of
44

55
```javascript
66
const myProxy = createProxyMiddleware({
7-
target: 'http://www.example.com',
7+
target: 'http://www.example.com/api',
88
changeOrigin: true,
99
selfHandleResponse: true,
1010
onProxyReq: (proxyReq, req, res) => {
@@ -45,7 +45,7 @@ const entryMiddleware = async (req, res, next) => {
4545
};
4646

4747
const myProxy = createProxyMiddleware({
48-
target: 'http://www.example.com',
48+
target: 'http://www.example.com/api',
4949
changeOrigin: true,
5050
selfHandleResponse: true,
5151
onProxyReq: (proxyReq, req, res) => {

recipes/basic.md

+5-13
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,19 @@ This example will create a basic proxy middleware.
66
const { createProxyMiddleware } = require('http-proxy-middleware');
77

88
const apiProxy = createProxyMiddleware({
9-
pathFilter: '/api',
109
target: 'http://localhost:3000',
10+
changeOrigin: true,
1111
});
1212
```
1313

1414
## Alternative configuration
1515

16-
The proxy behavior of the following examples are **exactly** the same; Just different ways to configure it.
17-
18-
```javascript
19-
app.use(createProxyMiddleware('/api', { target: 'http://localhost:3000', changeOrigin: true }));
20-
```
21-
22-
```javascript
23-
app.use(createProxyMiddleware('http://localhost:3000/api', { changeOrigin: true }));
24-
```
25-
2616
```javascript
27-
app.use('/api', createProxyMiddleware('http://localhost:3000', { changeOrigin: true }));
17+
app.use('/api', createProxyMiddleware({ target: 'http://localhost:3000/api', changeOrigin: true }));
2818
```
2919

3020
```javascript
31-
app.use('/api', createProxyMiddleware({ target: 'http://localhost:3000', changeOrigin: true }));
21+
app.use(
22+
createProxyMiddleware({ target: 'http://localhost:3000', changeOrigin: true, pathFilter: '/api' })
23+
);
3224
```

recipes/servers.md

+20-10
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,14 @@ https://github.com/expressjs/express
2626
const express = require('express');
2727
const { createProxyMiddleware } = require('http-proxy-middleware');
2828

29-
const apiProxy = createProxyMiddleware('/api', {
30-
target: 'http://www.example.org',
29+
const apiProxy = createProxyMiddleware({
30+
target: 'http://www.example.org/api',
3131
changeOrigin: true, // for vhosted sites
3232
});
3333

3434
const app = express();
3535

36-
app.use(apiProxy);
36+
app.use('/api', apiProxy);
3737
app.listen(3000);
3838
```
3939

@@ -48,13 +48,13 @@ const http = require('http');
4848
const connect = require('connect');
4949
const { createProxyMiddleware } = require('http-proxy-middleware');
5050

51-
const apiProxy = createProxyMiddleware('/api', {
52-
target: 'http://www.example.org',
51+
const apiProxy = createProxyMiddleware({
52+
target: 'http://www.example.org/api',
5353
changeOrigin: true, // for vhosted sites
5454
});
5555

5656
const app = connect();
57-
app.use(apiProxy);
57+
app.use('/api', apiProxy);
5858

5959
http.createServer(app).listen(3000);
6060
```
@@ -88,6 +88,12 @@ export default function handler(req: NextApiRequest, res: NextApiResponse) {
8888
});
8989
}
9090

91+
export const config = {
92+
api: {
93+
externalResolver: true,
94+
},
95+
};
96+
9197
// curl http://localhost:3000/api/users
9298
```
9399

@@ -101,9 +107,10 @@ https://github.com/BrowserSync/browser-sync
101107
const browserSync = require('browser-sync').create();
102108
const { createProxyMiddleware } = require('http-proxy-middleware');
103109

104-
const apiProxy = createProxyMiddleware('/api', {
110+
const apiProxy = createProxyMiddleware({
105111
target: 'http://www.example.org',
106112
changeOrigin: true, // for vhosted sites
113+
pathFilter: '/api',
107114
});
108115

109116
browserSync.init({
@@ -226,9 +233,10 @@ As a `function`:
226233
```javascript
227234
const { createProxyMiddleware } = require('http-proxy-middleware');
228235

229-
const apiProxy = createProxyMiddleware('/api', {
236+
const apiProxy = createProxyMiddleware({
230237
target: 'http://www.example.org',
231238
changeOrigin: true, // for vhosted sites
239+
pathFilter: '/api',
232240
});
233241

234242
grunt.initConfig({
@@ -262,9 +270,10 @@ gulp.task('connect', function () {
262270
connect.server({
263271
root: ['./app'],
264272
middleware: function (connect, opt) {
265-
const apiProxy = createProxyMiddleware('/api', {
273+
const apiProxy = createProxyMiddleware({
266274
target: 'http://www.example.org',
267275
changeOrigin: true, // for vhosted sites
276+
pathFilter: '/api',
268277
});
269278

270279
return [apiProxy];
@@ -284,9 +293,10 @@ https://github.com/BrowserSync/grunt-browser-sync
284293
```javascript
285294
const { createProxyMiddleware } = require('http-proxy-middleware');
286295

287-
const apiProxy = createProxyMiddleware('/api', {
296+
const apiProxy = createProxyMiddleware({
288297
target: 'http://www.example.org',
289298
changeOrigin: true, // for vhosted sites
299+
pathFilter: '/api',
290300
});
291301

292302
grunt.initConfig({

src/http-proxy-middleware.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,8 @@ export class HttpProxyMiddleware {
100100
* Determine whether request should be proxied.
101101
*/
102102
private shouldProxy = (pathFilter: Filter, req: Request): boolean => {
103-
const path = (req as Request<express.Request>).originalUrl || req.url;
104-
return matchPathFilter(pathFilter, path, req);
103+
// const path = (req as Request<express.Request>).originalUrl || req.url;
104+
return matchPathFilter(pathFilter, req.url, req);
105105
};
106106

107107
/**
@@ -115,7 +115,7 @@ export class HttpProxyMiddleware {
115115
private prepareProxyRequest = async (req: Request) => {
116116
// https://github.com/chimurai/http-proxy-middleware/issues/17
117117
// https://github.com/chimurai/http-proxy-middleware/issues/94
118-
req.url = (req as Request<express.Request>).originalUrl || req.url;
118+
// req.url = (req as Request<express.Request>).originalUrl || req.url;
119119

120120
// store uri before it gets rewritten for logging
121121
const originalPath = req.url;

src/types.ts

+4
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ export interface RequestHandler {
2222
export type Filter = string | string[] | ((pathname: string, req: Request) => boolean);
2323

2424
export interface Options extends httpProxy.ServerOptions {
25+
/**
26+
* Decide whether to proxy the request or not.
27+
* The `pathname` is relative to the proxy's "mounting" point in the server.
28+
*/
2529
pathFilter?: Filter;
2630
pathRewrite?:
2731
| { [regexp: string]: string }

test/e2e/http-proxy-middleware.spec.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,9 @@ describe('E2E http-proxy-middleware', () => {
1818

1919
describe('pathFilter matching', () => {
2020
describe('do not proxy', () => {
21-
const mockReq: Request<express.Request> = {
21+
const mockReq: Request = {
2222
url: '/foo/bar',
23-
originalUrl: '/foo/bar',
24-
} as Request<express.Request>;
23+
} as Request;
2524
const mockRes: Response = {} as Response;
2625
const mockNext: express.NextFunction = jest.fn();
2726

@@ -410,7 +409,7 @@ describe('E2E http-proxy-middleware', () => {
410409
agent = request(
411410
createAppWithPath(
412411
'/api',
413-
createProxyMiddleware({ target: `http://localhost:${mockTargetServer.port}` })
412+
createProxyMiddleware({ target: `http://localhost:${mockTargetServer.port}/api` })
414413
)
415414
);
416415
});

0 commit comments

Comments
 (0)