http-proxy-middleware 0.19.0 → 0.19.1
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 +35 -5
- package/README.md +278 -264
- package/index.js +1 -1
- package/lib/config-factory.js +14 -12
- package/lib/context-matcher.js +9 -9
- package/lib/errors.js +8 -4
- package/lib/handlers.js +17 -9
- package/lib/index.js +50 -20
- package/lib/logger.js +19 -19
- package/lib/path-rewriter.js +16 -10
- package/lib/router.js +8 -6
- package/package.json +20 -20
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
[](https://coveralls.io/r/chimurai/http-proxy-middleware)
|
|
5
5
|
[](https://david-dm.org/chimurai/http-proxy-middleware#info=dependencies)
|
|
6
6
|
[](https://snyk.io/test/npm/http-proxy-middleware)
|
|
7
|
-
[](https://github.com/prettier/prettier)
|
|
8
8
|
|
|
9
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).
|
|
10
10
|
|
|
@@ -15,13 +15,13 @@ Powered by the popular Nodejitsu [`http-proxy`](https://github.com/nodejitsu/nod
|
|
|
15
15
|
Proxy `/api` requests to `http://www.example.org`
|
|
16
16
|
|
|
17
17
|
```javascript
|
|
18
|
-
var express = require('express')
|
|
19
|
-
var proxy = require('http-proxy-middleware')
|
|
18
|
+
var express = require('express')
|
|
19
|
+
var proxy = require('http-proxy-middleware')
|
|
20
20
|
|
|
21
|
-
var app = express()
|
|
21
|
+
var app = express()
|
|
22
22
|
|
|
23
|
-
app.use('/api', proxy({target: 'http://www.example.org', changeOrigin: true}))
|
|
24
|
-
app.listen(3000)
|
|
23
|
+
app.use('/api', proxy({ target: 'http://www.example.org', changeOrigin: true }))
|
|
24
|
+
app.listen(3000)
|
|
25
25
|
|
|
26
26
|
// http://localhost:3000/api/foo/bar -> http://www.example.org/api/foo/bar
|
|
27
27
|
```
|
|
@@ -39,13 +39,13 @@ _All_ `http-proxy` [options](https://github.com/nodejitsu/node-http-proxy#option
|
|
|
39
39
|
- [Example](#example)
|
|
40
40
|
- [Context matching](#context-matching)
|
|
41
41
|
- [Options](#options)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
- [http-proxy-middleware options](#http-proxy-middleware-options)
|
|
43
|
+
- [http-proxy events](#http-proxy-events)
|
|
44
|
+
- [http-proxy options](#http-proxy-options)
|
|
45
45
|
- [Shorthand](#shorthand)
|
|
46
|
-
|
|
46
|
+
- [app.use\(path, proxy\)](#appusepath-proxy)
|
|
47
47
|
- [WebSocket](#websocket)
|
|
48
|
-
|
|
48
|
+
- [External WebSocket upgrade](#external-websocket-upgrade)
|
|
49
49
|
- [Working examples](#working-examples)
|
|
50
50
|
- [Recipes](#recipes)
|
|
51
51
|
- [Compatible servers](#compatible-servers)
|
|
@@ -55,7 +55,6 @@ _All_ `http-proxy` [options](https://github.com/nodejitsu/node-http-proxy#option
|
|
|
55
55
|
|
|
56
56
|
<!-- /MarkdownTOC -->
|
|
57
57
|
|
|
58
|
-
|
|
59
58
|
## Install
|
|
60
59
|
|
|
61
60
|
```javascript
|
|
@@ -69,28 +68,29 @@ Proxy middleware configuration.
|
|
|
69
68
|
#### proxy([context,] config)
|
|
70
69
|
|
|
71
70
|
```javascript
|
|
72
|
-
var proxy = require('http-proxy-middleware')
|
|
71
|
+
var proxy = require('http-proxy-middleware')
|
|
73
72
|
|
|
74
|
-
var apiProxy = proxy('/api', {target: 'http://www.example.org'})
|
|
73
|
+
var apiProxy = proxy('/api', { target: 'http://www.example.org' })
|
|
75
74
|
// \____/ \_____________________________/
|
|
76
75
|
// | |
|
|
77
76
|
// context options
|
|
78
77
|
|
|
79
78
|
// 'apiProxy' is now ready to be used as middleware in a server.
|
|
80
79
|
```
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
80
|
+
|
|
81
|
+
- **context**: Determine which requests should be proxied to the target host.
|
|
82
|
+
(more on [context matching](#context-matching))
|
|
83
|
+
- **options.target**: target host to proxy to. _(protocol + host)_
|
|
84
84
|
|
|
85
85
|
(full list of [`http-proxy-middleware` configuration options](#options))
|
|
86
86
|
|
|
87
87
|
#### proxy(uri [, config])
|
|
88
88
|
|
|
89
|
-
```
|
|
89
|
+
```javascript
|
|
90
90
|
// shorthand syntax for the example above:
|
|
91
|
-
var apiProxy = proxy('http://www.example.org/api')
|
|
92
|
-
|
|
91
|
+
var apiProxy = proxy('http://www.example.org/api')
|
|
93
92
|
```
|
|
93
|
+
|
|
94
94
|
More about the [shorthand configuration](#shorthand).
|
|
95
95
|
|
|
96
96
|
## Example
|
|
@@ -99,32 +99,32 @@ An example with `express` server.
|
|
|
99
99
|
|
|
100
100
|
```javascript
|
|
101
101
|
// include dependencies
|
|
102
|
-
var express = require('express')
|
|
103
|
-
var proxy = require('http-proxy-middleware')
|
|
102
|
+
var express = require('express')
|
|
103
|
+
var proxy = require('http-proxy-middleware')
|
|
104
104
|
|
|
105
105
|
// proxy middleware options
|
|
106
106
|
var options = {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
107
|
+
target: 'http://www.example.org', // target host
|
|
108
|
+
changeOrigin: true, // needed for virtual hosted sites
|
|
109
|
+
ws: true, // proxy websockets
|
|
110
|
+
pathRewrite: {
|
|
111
|
+
'^/api/old-path': '/api/new-path', // rewrite path
|
|
112
|
+
'^/api/remove/path': '/path' // remove base path
|
|
113
|
+
},
|
|
114
|
+
router: {
|
|
115
|
+
// when request.headers.host == 'dev.localhost:3000',
|
|
116
|
+
// override target 'http://www.example.org' to 'http://localhost:8000'
|
|
117
|
+
'dev.localhost:3000': 'http://localhost:8000'
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
120
|
|
|
121
121
|
// create the proxy (without context)
|
|
122
|
-
var exampleProxy = proxy(options)
|
|
122
|
+
var exampleProxy = proxy(options)
|
|
123
123
|
|
|
124
124
|
// mount `exampleProxy` in web server
|
|
125
|
-
var app = express()
|
|
126
|
-
|
|
127
|
-
|
|
125
|
+
var app = express()
|
|
126
|
+
app.use('/api', exampleProxy)
|
|
127
|
+
app.listen(3000)
|
|
128
128
|
```
|
|
129
129
|
|
|
130
130
|
## Context matching
|
|
@@ -140,294 +140,308 @@ Providing an alternative way to decide which requests should be proxied; In case
|
|
|
140
140
|
scheme authority path query fragment
|
|
141
141
|
```
|
|
142
142
|
|
|
143
|
-
|
|
144
|
-
- `proxy({...})` - matches any path, all requests will be proxied.
|
|
145
|
-
- `proxy('/', {...})` - matches any path, all requests will be proxied.
|
|
146
|
-
- `proxy('/api', {...})` - matches paths starting with `/api`
|
|
147
|
-
|
|
148
|
-
* **multiple path matching**
|
|
149
|
-
- `proxy(['/api', '/ajax', '/someotherpath'], {...})`
|
|
150
|
-
|
|
151
|
-
* **wildcard path matching**
|
|
152
|
-
|
|
153
|
-
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.
|
|
154
|
-
- `proxy('**', {...})` matches any path, all requests will be proxied.
|
|
155
|
-
- `proxy('**/*.html', {...})` matches any path which ends with `.html`
|
|
156
|
-
- `proxy('/*.html', {...})` matches paths directly under path-absolute
|
|
157
|
-
- `proxy('/api/**/*.html', {...})` matches requests ending with `.html` in the path of `/api`
|
|
158
|
-
- `proxy(['/api/**', '/ajax/**'], {...})` combine multiple patterns
|
|
159
|
-
- `proxy(['/api/**', '!**/bad.json'], {...})` exclusion
|
|
160
|
-
|
|
161
|
-
* **custom matching**
|
|
162
|
-
|
|
163
|
-
For full control you can provide a custom function to determine which requests should be proxied or not.
|
|
164
|
-
```javascript
|
|
165
|
-
/**
|
|
166
|
-
* @return {Boolean}
|
|
167
|
-
*/
|
|
168
|
-
var filter = function (pathname, req) {
|
|
169
|
-
return (pathname.match('^/api') && req.method === 'GET');
|
|
170
|
-
};
|
|
171
|
-
|
|
172
|
-
var apiProxy = proxy(filter, {target: 'http://www.example.org'})
|
|
173
|
-
```
|
|
143
|
+
- **path matching**
|
|
174
144
|
|
|
175
|
-
|
|
145
|
+
- `proxy({...})` - matches any path, all requests will be proxied.
|
|
146
|
+
- `proxy('/', {...})` - matches any path, all requests will be proxied.
|
|
147
|
+
- `proxy('/api', {...})` - matches paths starting with `/api`
|
|
176
148
|
|
|
177
|
-
|
|
149
|
+
- **multiple path matching**
|
|
178
150
|
|
|
179
|
-
|
|
180
|
-
```javascript
|
|
181
|
-
// rewrite path
|
|
182
|
-
pathRewrite: {'^/old/api' : '/new/api'}
|
|
183
|
-
|
|
184
|
-
// remove path
|
|
185
|
-
pathRewrite: {'^/remove/api' : ''}
|
|
186
|
-
|
|
187
|
-
// add base path
|
|
188
|
-
pathRewrite: {'^/' : '/basepath/'}
|
|
189
|
-
|
|
190
|
-
// custom rewriting
|
|
191
|
-
pathRewrite: function (path, req) { return path.replace('/api', '/base/api') }
|
|
192
|
-
```
|
|
151
|
+
- `proxy(['/api', '/ajax', '/someotherpath'], {...})`
|
|
193
152
|
|
|
194
|
-
|
|
195
|
-
```javascript
|
|
196
|
-
// Use `host` and/or `path` to match requests. First match will be used.
|
|
197
|
-
// The order of the configuration matters.
|
|
198
|
-
router: {
|
|
199
|
-
'integration.localhost:3000' : 'http://localhost:8001', // host only
|
|
200
|
-
'staging.localhost:3000' : 'http://localhost:8002', // host only
|
|
201
|
-
'localhost:3000/api' : 'http://localhost:8003', // host + path
|
|
202
|
-
'/rest' : 'http://localhost:8004' // path only
|
|
203
|
-
}
|
|
153
|
+
- **wildcard path matching**
|
|
204
154
|
|
|
205
|
-
|
|
206
|
-
router: function(req) {
|
|
207
|
-
return 'http://localhost:8004';
|
|
208
|
-
}
|
|
209
|
-
```
|
|
155
|
+
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.
|
|
210
156
|
|
|
211
|
-
|
|
157
|
+
- `proxy('**', {...})` matches any path, all requests will be proxied.
|
|
158
|
+
- `proxy('**/*.html', {...})` matches any path which ends with `.html`
|
|
159
|
+
- `proxy('/*.html', {...})` matches paths directly under path-absolute
|
|
160
|
+
- `proxy('/api/**/*.html', {...})` matches requests ending with `.html` in the path of `/api`
|
|
161
|
+
- `proxy(['/api/**', '/ajax/**'], {...})` combine multiple patterns
|
|
162
|
+
- `proxy(['/api/**', '!**/bad.json'], {...})` exclusion
|
|
212
163
|
|
|
213
|
-
|
|
214
|
-
```javascript
|
|
215
|
-
// simple replace
|
|
216
|
-
function logProvider(provider) {
|
|
217
|
-
// replace the default console log provider.
|
|
218
|
-
return require('winston');
|
|
219
|
-
}
|
|
220
|
-
```
|
|
164
|
+
**Note**: In multiple path matching, you cannot use string paths and wildcard paths together.
|
|
221
165
|
|
|
222
|
-
|
|
223
|
-
// verbose replacement
|
|
224
|
-
function logProvider(provider) {
|
|
225
|
-
var logger = new (require('winston').Logger)();
|
|
226
|
-
|
|
227
|
-
var myCustomProvider = {
|
|
228
|
-
log: logger.log,
|
|
229
|
-
debug: logger.debug,
|
|
230
|
-
info: logger.info,
|
|
231
|
-
warn: logger.warn,
|
|
232
|
-
error: logger.error
|
|
233
|
-
}
|
|
234
|
-
return myCustomProvider;
|
|
235
|
-
}
|
|
236
|
-
```
|
|
237
|
-
* (DEPRECATED) **option.proxyHost**: Use `option.changeOrigin = true` instead.
|
|
238
|
-
* (DEPRECATED) **option.proxyTable**: Use `option.router` instead.
|
|
166
|
+
- **custom matching**
|
|
239
167
|
|
|
168
|
+
For full control you can provide a custom function to determine which requests should be proxied or not.
|
|
240
169
|
|
|
241
|
-
|
|
170
|
+
```javascript
|
|
171
|
+
/**
|
|
172
|
+
* @return {Boolean}
|
|
173
|
+
*/
|
|
174
|
+
var filter = function(pathname, req) {
|
|
175
|
+
return pathname.match('^/api') && req.method === 'GET'
|
|
176
|
+
}
|
|
242
177
|
|
|
243
|
-
|
|
178
|
+
var apiProxy = proxy(filter, { target: 'http://www.example.org' })
|
|
179
|
+
```
|
|
244
180
|
|
|
245
|
-
|
|
246
|
-
```javascript
|
|
247
|
-
function onError(err, req, res) {
|
|
248
|
-
res.writeHead(500, {
|
|
249
|
-
'Content-Type': 'text/plain'
|
|
250
|
-
});
|
|
251
|
-
res.end('Something went wrong. And we are reporting a custom error message.');
|
|
252
|
-
}
|
|
253
|
-
```
|
|
181
|
+
## Options
|
|
254
182
|
|
|
255
|
-
|
|
256
|
-
```javascript
|
|
257
|
-
function onProxyRes(proxyRes, req, res) {
|
|
258
|
-
proxyRes.headers['x-added'] = 'foobar'; // add new header to response
|
|
259
|
-
delete proxyRes.headers['x-removed']; // remove header from response
|
|
260
|
-
}
|
|
261
|
-
```
|
|
183
|
+
### http-proxy-middleware options
|
|
262
184
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
185
|
+
- **option.pathRewrite**: object/function, rewrite target's url path. Object-keys will be used as _RegExp_ to match paths.
|
|
186
|
+
|
|
187
|
+
```javascript
|
|
188
|
+
// rewrite path
|
|
189
|
+
pathRewrite: {'^/old/api' : '/new/api'}
|
|
190
|
+
|
|
191
|
+
// remove path
|
|
192
|
+
pathRewrite: {'^/remove/api' : ''}
|
|
193
|
+
|
|
194
|
+
// add base path
|
|
195
|
+
pathRewrite: {'^/' : '/basepath/'}
|
|
196
|
+
|
|
197
|
+
// custom rewriting
|
|
198
|
+
pathRewrite: function (path, req) { return path.replace('/api', '/base/api') }
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
- **option.router**: object/function, re-target `option.target` for specific requests.
|
|
202
|
+
|
|
203
|
+
```javascript
|
|
204
|
+
// Use `host` and/or `path` to match requests. First match will be used.
|
|
205
|
+
// The order of the configuration matters.
|
|
206
|
+
router: {
|
|
207
|
+
'integration.localhost:3000' : 'http://localhost:8001', // host only
|
|
208
|
+
'staging.localhost:3000' : 'http://localhost:8002', // host only
|
|
209
|
+
'localhost:3000/api' : 'http://localhost:8003', // host + path
|
|
210
|
+
'/rest' : 'http://localhost:8004' // path only
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Custom router function
|
|
214
|
+
router: function(req) {
|
|
215
|
+
return 'http://localhost:8004';
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
- **option.logLevel**: string, ['debug', 'info', 'warn', 'error', 'silent']. Default: `'info'`
|
|
220
|
+
|
|
221
|
+
- **option.logProvider**: function, modify or replace log provider. Default: `console`.
|
|
222
|
+
|
|
223
|
+
```javascript
|
|
224
|
+
// simple replace
|
|
225
|
+
function logProvider(provider) {
|
|
226
|
+
// replace the default console log provider.
|
|
227
|
+
return require('winston')
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
```javascript
|
|
232
|
+
// verbose replacement
|
|
233
|
+
function logProvider(provider) {
|
|
234
|
+
var logger = new (require('winston')).Logger()
|
|
235
|
+
|
|
236
|
+
var myCustomProvider = {
|
|
237
|
+
log: logger.log,
|
|
238
|
+
debug: logger.debug,
|
|
239
|
+
info: logger.info,
|
|
240
|
+
warn: logger.warn,
|
|
241
|
+
error: logger.error
|
|
269
242
|
}
|
|
270
|
-
|
|
243
|
+
return myCustomProvider
|
|
244
|
+
}
|
|
245
|
+
```
|
|
271
246
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
function onProxyReqWs(proxyReq, req, socket, options, head) {
|
|
275
|
-
// add custom header
|
|
276
|
-
proxyReq.setHeader('X-Special-Proxy-Header', 'foobar');
|
|
277
|
-
}
|
|
278
|
-
```
|
|
247
|
+
- (DEPRECATED) **option.proxyHost**: Use `option.changeOrigin = true` instead.
|
|
248
|
+
- (DEPRECATED) **option.proxyTable**: Use `option.router` instead.
|
|
279
249
|
|
|
280
|
-
|
|
281
|
-
```javascript
|
|
282
|
-
function onOpen(proxySocket) {
|
|
283
|
-
// listen for messages coming FROM the target here
|
|
284
|
-
proxySocket.on('data', hybiParseAndLogMessage);
|
|
285
|
-
}
|
|
286
|
-
```
|
|
250
|
+
### http-proxy events
|
|
287
251
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
252
|
+
Subscribe to [http-proxy events](https://github.com/nodejitsu/node-http-proxy#listening-for-proxy-events):
|
|
253
|
+
|
|
254
|
+
- **option.onError**: function, subscribe to http-proxy's `error` event for custom error handling.
|
|
255
|
+
|
|
256
|
+
```javascript
|
|
257
|
+
function onError(err, req, res) {
|
|
258
|
+
res.writeHead(500, {
|
|
259
|
+
'Content-Type': 'text/plain'
|
|
260
|
+
})
|
|
261
|
+
res.end(
|
|
262
|
+
'Something went wrong. And we are reporting a custom error message.'
|
|
263
|
+
)
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
- **option.onProxyRes**: function, subscribe to http-proxy's `proxyRes` event.
|
|
268
|
+
|
|
269
|
+
```javascript
|
|
270
|
+
function onProxyRes(proxyRes, req, res) {
|
|
271
|
+
proxyRes.headers['x-added'] = 'foobar' // add new header to response
|
|
272
|
+
delete proxyRes.headers['x-removed'] // remove header from response
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
- **option.onProxyReq**: function, subscribe to http-proxy's `proxyReq` event.
|
|
277
|
+
|
|
278
|
+
```javascript
|
|
279
|
+
function onProxyReq(proxyReq, req, res) {
|
|
280
|
+
// add custom header to request
|
|
281
|
+
proxyReq.setHeader('x-added', 'foobar')
|
|
282
|
+
// or log the req
|
|
283
|
+
}
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
- **option.onProxyReqWs**: function, subscribe to http-proxy's `proxyReqWs` event.
|
|
287
|
+
|
|
288
|
+
```javascript
|
|
289
|
+
function onProxyReqWs(proxyReq, req, socket, options, head) {
|
|
290
|
+
// add custom header
|
|
291
|
+
proxyReq.setHeader('X-Special-Proxy-Header', 'foobar')
|
|
292
|
+
}
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
- **option.onOpen**: function, subscribe to http-proxy's `open` event.
|
|
296
|
+
|
|
297
|
+
```javascript
|
|
298
|
+
function onOpen(proxySocket) {
|
|
299
|
+
// listen for messages coming FROM the target here
|
|
300
|
+
proxySocket.on('data', hybiParseAndLogMessage)
|
|
301
|
+
}
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
- **option.onClose**: function, subscribe to http-proxy's `close` event.
|
|
305
|
+
```javascript
|
|
306
|
+
function onClose(res, socket, head) {
|
|
307
|
+
// view disconnected websocket connections
|
|
308
|
+
console.log('Client disconnected')
|
|
309
|
+
}
|
|
310
|
+
```
|
|
295
311
|
|
|
296
312
|
### http-proxy options
|
|
297
313
|
|
|
298
314
|
The following options are provided by the underlying [http-proxy](https://github.com/nodejitsu/node-http-proxy#options) library.
|
|
299
315
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
```
|
|
323
|
-
cookieDomainRewrite: {
|
|
324
|
-
"unchanged.domain": "unchanged.domain",
|
|
325
|
-
"old.domain": "new.domain",
|
|
326
|
-
"*": ""
|
|
327
|
-
}
|
|
328
|
-
```
|
|
329
|
-
* **option.cookiePathRewrite**: rewrites path of `set-cookie` headers. Possible values:
|
|
330
|
-
* `false` (default): disable cookie rewriting
|
|
331
|
-
* String: new path, for example `cookiePathRewrite: "/newPath/"`. To remove the path, use `cookiePathRewrite: ""`. To set path to root use `cookiePathRewrite: "/"`.
|
|
332
|
-
* Object: mapping of paths to new paths, use `"*"` to match all paths.
|
|
333
|
-
For example, to keep one path unchanged, rewrite one path and remove other paths:
|
|
334
|
-
```
|
|
335
|
-
cookiePathRewrite: {
|
|
336
|
-
"/unchanged.path/": "/unchanged.path/",
|
|
337
|
-
"/old.path/": "/new.path/",
|
|
338
|
-
"*": ""
|
|
339
|
-
}
|
|
340
|
-
```
|
|
341
|
-
* **option.headers**: object, adds [request headers](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Request_fields). (Example: `{host:'www.example.org'}`)
|
|
342
|
-
* **option.proxyTimeout**: timeout (in millis) when proxy receives no response from target
|
|
343
|
-
* **option.timeout**: timeout (in millis) for incoming requests
|
|
344
|
-
* **option.followRedirects**: true/false, Default: false - specify whether you want to follow redirects
|
|
345
|
-
* **option.selfHandleResponse** true/false, if set to true, none of the webOutgoing passes are called and it's your responsibility to appropriately return the response by listening and acting on the `proxyRes` event
|
|
346
|
-
* **option.buffer**: stream of data to send as the request body. Maybe you have some middleware that consumes the request stream before proxying it on e.g. If you read the body of a request into a field called 'req.rawbody' you could restream this field in the buffer option:
|
|
347
|
-
|
|
316
|
+
- **option.target**: url string to be parsed with the url module
|
|
317
|
+
- **option.forward**: url string to be parsed with the url module
|
|
318
|
+
- **option.agent**: object to be passed to http(s).request (see Node's [https agent](http://nodejs.org/api/https.html#https_class_https_agent) and [http agent](http://nodejs.org/api/http.html#http_class_http_agent) objects)
|
|
319
|
+
- **option.ssl**: object to be passed to https.createServer()
|
|
320
|
+
- **option.ws**: true/false: if you want to proxy websockets
|
|
321
|
+
- **option.xfwd**: true/false, adds x-forward headers
|
|
322
|
+
- **option.secure**: true/false, if you want to verify the SSL Certs
|
|
323
|
+
- **option.toProxy**: true/false, passes the absolute URL as the `path` (useful for proxying to proxies)
|
|
324
|
+
- **option.prependPath**: true/false, Default: true - specify whether you want to prepend the target's path to the proxy path
|
|
325
|
+
- **option.ignorePath**: true/false, Default: false - specify whether you want to ignore the proxy path of the incoming request (note: you will have to append / manually if required).
|
|
326
|
+
- **option.localAddress** : Local interface string to bind for outgoing connections
|
|
327
|
+
- **option.changeOrigin**: true/false, Default: false - changes the origin of the host header to the target URL
|
|
328
|
+
- **option.preserveHeaderKeyCase**: true/false, Default: false - specify whether you want to keep letter case of response header key
|
|
329
|
+
- **option.auth** : Basic authentication i.e. 'user:password' to compute an Authorization header.
|
|
330
|
+
- **option.hostRewrite**: rewrites the location hostname on (301/302/307/308) redirects.
|
|
331
|
+
- **option.autoRewrite**: rewrites the location host/port on (301/302/307/308) redirects based on requested host/port. Default: false.
|
|
332
|
+
- **option.protocolRewrite**: rewrites the location protocol on (301/302/307/308) redirects to 'http' or 'https'. Default: null.
|
|
333
|
+
- **option.cookieDomainRewrite**: rewrites domain of `set-cookie` headers. Possible values:
|
|
334
|
+
- `false` (default): disable cookie rewriting
|
|
335
|
+
- String: new domain, for example `cookieDomainRewrite: "new.domain"`. To remove the domain, use `cookieDomainRewrite: ""`.
|
|
336
|
+
- Object: mapping of domains to new domains, use `"*"` to match all domains.
|
|
337
|
+
For example keep one domain unchanged, rewrite one domain and remove other domains:
|
|
348
338
|
```
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
339
|
+
cookieDomainRewrite: {
|
|
340
|
+
"unchanged.domain": "unchanged.domain",
|
|
341
|
+
"old.domain": "new.domain",
|
|
342
|
+
"*": ""
|
|
343
|
+
}
|
|
344
|
+
```
|
|
345
|
+
- **option.cookiePathRewrite**: rewrites path of `set-cookie` headers. Possible values:
|
|
346
|
+
- `false` (default): disable cookie rewriting
|
|
347
|
+
- String: new path, for example `cookiePathRewrite: "/newPath/"`. To remove the path, use `cookiePathRewrite: ""`. To set path to root use `cookiePathRewrite: "/"`.
|
|
348
|
+
- Object: mapping of paths to new paths, use `"*"` to match all paths.
|
|
349
|
+
For example, to keep one path unchanged, rewrite one path and remove other paths:
|
|
350
|
+
```
|
|
351
|
+
cookiePathRewrite: {
|
|
352
|
+
"/unchanged.path/": "/unchanged.path/",
|
|
353
|
+
"/old.path/": "/new.path/",
|
|
354
|
+
"*": ""
|
|
355
|
+
}
|
|
356
|
+
```
|
|
357
|
+
- **option.headers**: object, adds [request headers](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Request_fields). (Example: `{host:'www.example.org'}`)
|
|
358
|
+
- **option.proxyTimeout**: timeout (in millis) when proxy receives no response from target
|
|
359
|
+
- **option.timeout**: timeout (in millis) for incoming requests
|
|
360
|
+
- **option.followRedirects**: true/false, Default: false - specify whether you want to follow redirects
|
|
361
|
+
- **option.selfHandleResponse** true/false, if set to true, none of the webOutgoing passes are called and it's your responsibility to appropriately return the response by listening and acting on the `proxyRes` event
|
|
362
|
+
- **option.buffer**: stream of data to send as the request body. Maybe you have some middleware that consumes the request stream before proxying it on e.g. If you read the body of a request into a field called 'req.rawbody' you could restream this field in the buffer option:
|
|
354
363
|
|
|
355
|
-
|
|
364
|
+
```
|
|
365
|
+
'use strict';
|
|
356
366
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
}, next);
|
|
367
|
+
const streamify = require('stream-array');
|
|
368
|
+
const HttpProxy = require('http-proxy');
|
|
369
|
+
const proxy = new HttpProxy();
|
|
361
370
|
|
|
362
|
-
|
|
363
|
-
```
|
|
371
|
+
module.exports = (req, res, next) => {
|
|
364
372
|
|
|
373
|
+
proxy.web(req, res, {
|
|
374
|
+
target: 'http://localhost:4003/',
|
|
375
|
+
buffer: streamify(req.rawBody)
|
|
376
|
+
}, next);
|
|
365
377
|
|
|
378
|
+
};
|
|
379
|
+
```
|
|
366
380
|
|
|
367
381
|
## Shorthand
|
|
368
382
|
|
|
369
383
|
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.
|
|
370
384
|
|
|
371
385
|
```javascript
|
|
372
|
-
proxy('http://www.example.org:8000/api')
|
|
386
|
+
proxy('http://www.example.org:8000/api')
|
|
373
387
|
// proxy('/api', {target: 'http://www.example.org:8000'});
|
|
374
388
|
|
|
375
|
-
|
|
376
|
-
proxy('http://www.example.org:8000/api/books/*/**.json');
|
|
389
|
+
proxy('http://www.example.org:8000/api/books/*/**.json')
|
|
377
390
|
// proxy('/api/books/*/**.json', {target: 'http://www.example.org:8000'});
|
|
378
391
|
|
|
379
|
-
|
|
380
|
-
proxy('http://www.example.org:8000/api', {changeOrigin:true});
|
|
392
|
+
proxy('http://www.example.org:8000/api', { changeOrigin: true })
|
|
381
393
|
// proxy('/api', {target: 'http://www.example.org:8000', changeOrigin: true});
|
|
382
394
|
```
|
|
383
395
|
|
|
384
396
|
### app.use(path, proxy)
|
|
385
397
|
|
|
386
|
-
If you want to use the server's `app.use` `path` parameter to match requests;
|
|
398
|
+
If you want to use the server's `app.use` `path` parameter to match requests;
|
|
387
399
|
Create and mount the proxy without the http-proxy-middleware `context` parameter:
|
|
400
|
+
|
|
388
401
|
```javascript
|
|
389
|
-
app.use('/api', proxy({target:'http://www.example.org', changeOrigin:true}))
|
|
402
|
+
app.use('/api', proxy({ target: 'http://www.example.org', changeOrigin: true }))
|
|
390
403
|
```
|
|
391
404
|
|
|
392
405
|
`app.use` documentation:
|
|
393
|
-
|
|
394
|
-
|
|
406
|
+
|
|
407
|
+
- express: http://expressjs.com/en/4x/api.html#app.use
|
|
408
|
+
- connect: https://github.com/senchalabs/connect#mount-middleware
|
|
395
409
|
|
|
396
410
|
## WebSocket
|
|
397
411
|
|
|
398
412
|
```javascript
|
|
399
413
|
// verbose api
|
|
400
|
-
proxy('/', {target:'http://echo.websocket.org', ws:true})
|
|
414
|
+
proxy('/', { target: 'http://echo.websocket.org', ws: true })
|
|
401
415
|
|
|
402
416
|
// shorthand
|
|
403
|
-
proxy('http://echo.websocket.org', {ws:true})
|
|
417
|
+
proxy('http://echo.websocket.org', { ws: true })
|
|
404
418
|
|
|
405
419
|
// shorter shorthand
|
|
406
|
-
proxy('ws://echo.websocket.org')
|
|
420
|
+
proxy('ws://echo.websocket.org')
|
|
407
421
|
```
|
|
408
422
|
|
|
409
423
|
### External WebSocket upgrade
|
|
410
424
|
|
|
411
425
|
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.
|
|
426
|
+
|
|
412
427
|
```javascript
|
|
413
|
-
var wsProxy = proxy('ws://echo.websocket.org', {changeOrigin:true})
|
|
428
|
+
var wsProxy = proxy('ws://echo.websocket.org', { changeOrigin: true })
|
|
414
429
|
|
|
415
|
-
var app = express()
|
|
416
|
-
|
|
430
|
+
var app = express()
|
|
431
|
+
app.use(wsProxy)
|
|
417
432
|
|
|
418
|
-
var server = app.listen(3000)
|
|
419
|
-
|
|
433
|
+
var server = app.listen(3000)
|
|
434
|
+
server.on('upgrade', wsProxy.upgrade) // <-- subscribe to http 'upgrade'
|
|
420
435
|
```
|
|
421
436
|
|
|
422
|
-
|
|
423
437
|
## Working examples
|
|
424
438
|
|
|
425
439
|
View and play around with [working examples](https://github.com/chimurai/http-proxy-middleware/tree/master/examples).
|
|
426
440
|
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
441
|
+
- Browser-Sync ([example source](https://github.com/chimurai/http-proxy-middleware/tree/master/examples/browser-sync/index.js))
|
|
442
|
+
- express ([example source](https://github.com/chimurai/http-proxy-middleware/tree/master/examples/express/index.js))
|
|
443
|
+
- connect ([example source](https://github.com/chimurai/http-proxy-middleware/tree/master/examples/connect/index.js))
|
|
444
|
+
- WebSocket ([example source](https://github.com/chimurai/http-proxy-middleware/tree/master/examples/websocket/index.js))
|
|
431
445
|
|
|
432
446
|
## Recipes
|
|
433
447
|
|
|
@@ -436,14 +450,15 @@ View the [recipes](https://github.com/chimurai/http-proxy-middleware/tree/master
|
|
|
436
450
|
## Compatible servers
|
|
437
451
|
|
|
438
452
|
`http-proxy-middleware` is compatible with the following servers:
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
453
|
+
|
|
454
|
+
- [connect](https://www.npmjs.com/package/connect)
|
|
455
|
+
- [express](https://www.npmjs.com/package/express)
|
|
456
|
+
- [browser-sync](https://www.npmjs.com/package/browser-sync)
|
|
457
|
+
- [lite-server](https://www.npmjs.com/package/lite-server)
|
|
458
|
+
- [grunt-contrib-connect](https://www.npmjs.com/package/grunt-contrib-connect)
|
|
459
|
+
- [grunt-browser-sync](https://www.npmjs.com/package/grunt-browser-sync)
|
|
460
|
+
- [gulp-connect](https://www.npmjs.com/package/gulp-connect)
|
|
461
|
+
- [gulp-webserver](https://www.npmjs.com/package/gulp-webserver)
|
|
447
462
|
|
|
448
463
|
Sample implementations can be found in the [server recipes](https://github.com/chimurai/http-proxy-middleware/tree/master/recipes/servers.md).
|
|
449
464
|
|
|
@@ -469,7 +484,6 @@ $ npm run cover
|
|
|
469
484
|
|
|
470
485
|
- [View changelog](https://github.com/chimurai/http-proxy-middleware/blob/master/CHANGELOG.md)
|
|
471
486
|
|
|
472
|
-
|
|
473
487
|
## License
|
|
474
488
|
|
|
475
489
|
The MIT License (MIT)
|