@ohos-ports/http-proxy-middleware 0.0.0-stage → 4.2.0-beta.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.
Files changed (67) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +670 -2
  3. package/dist/configuration.d.ts +3 -0
  4. package/dist/configuration.js +6 -0
  5. package/dist/debug.d.ts +5 -0
  6. package/dist/debug.js +5 -0
  7. package/dist/errors.d.ts +4 -0
  8. package/dist/errors.js +15 -0
  9. package/dist/factory-hono.d.ts +28 -0
  10. package/dist/factory-hono.js +45 -0
  11. package/dist/factory.d.ts +79 -0
  12. package/dist/factory.js +81 -0
  13. package/dist/get-plugins.d.ts +3 -0
  14. package/dist/get-plugins.js +10 -0
  15. package/dist/handlers/fix-request-body-utils/stringify-form-data.d.ts +12 -0
  16. package/dist/handlers/fix-request-body-utils/stringify-form-data.js +46 -0
  17. package/dist/handlers/fix-request-body.d.ts +22 -0
  18. package/dist/handlers/fix-request-body.js +78 -0
  19. package/dist/handlers/index.d.ts +1 -0
  20. package/dist/handlers/index.js +1 -0
  21. package/dist/handlers/public.d.ts +2 -0
  22. package/dist/handlers/public.js +2 -0
  23. package/dist/handlers/response-interceptor.d.ts +27 -0
  24. package/dist/handlers/response-interceptor.js +145 -0
  25. package/dist/http-proxy-middleware.d.ts +31 -0
  26. package/dist/http-proxy-middleware.js +183 -0
  27. package/dist/index-hono.d.ts +10 -0
  28. package/dist/index-hono.js +10 -0
  29. package/dist/index.d.ts +4 -0
  30. package/dist/index.js +3 -0
  31. package/dist/logger.d.ts +2 -0
  32. package/dist/logger.js +21 -0
  33. package/dist/path-filter.d.ts +3 -0
  34. package/dist/path-filter.js +76 -0
  35. package/dist/path-rewriter.d.ts +6 -0
  36. package/dist/path-rewriter.js +59 -0
  37. package/dist/plugins/default/debug-proxy-errors-plugin.d.ts +6 -0
  38. package/dist/plugins/default/debug-proxy-errors-plugin.js +77 -0
  39. package/dist/plugins/default/error-response-plugin.d.ts +2 -0
  40. package/dist/plugins/default/error-response-plugin.js +28 -0
  41. package/dist/plugins/default/index.d.ts +4 -0
  42. package/dist/plugins/default/index.js +4 -0
  43. package/dist/plugins/default/logger-plugin.d.ts +2 -0
  44. package/dist/plugins/default/logger-plugin.js +57 -0
  45. package/dist/plugins/default/proxy-events.d.ts +22 -0
  46. package/dist/plugins/default/proxy-events.js +42 -0
  47. package/dist/plugins/define-plugin.d.ts +25 -0
  48. package/dist/plugins/define-plugin.js +25 -0
  49. package/dist/plugins/index.d.ts +2 -0
  50. package/dist/plugins/index.js +4 -0
  51. package/dist/router.d.ts +3 -0
  52. package/dist/router.js +60 -0
  53. package/dist/status-code.d.ts +1 -0
  54. package/dist/status-code.js +23 -0
  55. package/dist/types.d.ts +139 -0
  56. package/dist/types.js +1 -0
  57. package/dist/utils/create-url.d.ts +9 -0
  58. package/dist/utils/create-url.js +17 -0
  59. package/dist/utils/function.d.ts +1 -0
  60. package/dist/utils/function.js +4 -0
  61. package/dist/utils/ipv6.d.ts +20 -0
  62. package/dist/utils/ipv6.js +66 -0
  63. package/dist/utils/logger-plugin.d.ts +7 -0
  64. package/dist/utils/logger-plugin.js +7 -0
  65. package/dist/utils/sanitize.d.ts +1 -0
  66. package/dist/utils/sanitize.js +3 -0
  67. package/package.json +120 -4
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Steven Chim
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
package/README.md CHANGED
@@ -1,3 +1,671 @@
1
- # Temporary Holding Version
1
+ # http-proxy-middleware
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ [![GitHub Workflow Status (with branch)](https://img.shields.io/github/actions/workflow/status/chimurai/http-proxy-middleware/ci.yml?branch=master&logo=github-actions&logoColor=white&style=flat-square)](https://github.com/chimurai/http-proxy-middleware/actions/workflows/ci.yml?query=branch%3Amaster)
4
+ [![Coveralls](https://img.shields.io/coveralls/chimurai/http-proxy-middleware.svg?style=flat-square&logo=coveralls)](https://coveralls.io/r/chimurai/http-proxy-middleware)
5
+ [![Known Vulnerabilities](https://snyk.io/test/github/chimurai/http-proxy-middleware/badge.svg)](https://snyk.io/test/github/chimurai/http-proxy-middleware)
6
+ [![npm](https://img.shields.io/npm/v/http-proxy-middleware?color=%23CC3534&style=flat-square&logo=npm)](https://www.npmjs.com/package/http-proxy-middleware)
7
+
8
+ Node.js proxying made simple. Configure proxy middleware with ease for [connect](https://github.com/senchalabs/connect), [express](https://github.com/expressjs/express), [next.js](https://github.com/vercel/next.js), [hono](https://github.com/honojs/hono) and [many more](#compatible-servers).
9
+
10
+ Powered by [`httpxy`](https://github.com/unjs/httpxy). A maintained version of [http-proxy](https://github.com/http-party/node-http-proxy).
11
+
12
+ ## ⚠️ Note <!-- omit in toc -->
13
+
14
+ This page is showing documentation for version **v4.x.x** ([release notes](https://github.com/chimurai/http-proxy-middleware/releases))
15
+
16
+ For older documentation:
17
+
18
+ - [v3.0.5](https://github.com/chimurai/http-proxy-middleware/tree/v3.0.5#readme)
19
+ - [v2.0.4](https://github.com/chimurai/http-proxy-middleware/tree/v2.0.4#readme)
20
+ - [v0.21.0](https://github.com/chimurai/http-proxy-middleware/tree/v0.21.0#readme)
21
+
22
+ ## TL;DR <!-- omit in toc -->
23
+
24
+ Proxy `/api` requests to `http://www.example.org`
25
+
26
+ :bulb: **Tip:** Set the option `changeOrigin` to `true` for [name-based virtual hosted sites](http://en.wikipedia.org/wiki/Virtual_hosting#Name-based).
27
+
28
+ ```typescript
29
+ // typescript
30
+ import express from 'express';
31
+ import type { NextFunction, Request, Response } from 'express';
32
+ import { createProxyMiddleware } from 'http-proxy-middleware';
33
+ import type { Filter, Options, RequestHandler } from 'http-proxy-middleware';
34
+
35
+ const app = express();
36
+
37
+ const proxyMiddleware = createProxyMiddleware<Request, Response>({
38
+ target: 'http://www.example.org/api',
39
+ changeOrigin: true,
40
+ });
41
+
42
+ app.use('/api', proxyMiddleware);
43
+
44
+ app.listen(3000);
45
+
46
+ // proxy and keep the same base path "/api"
47
+ // http://127.0.0.1:3000/api/foo/bar -> http://www.example.org/api/foo/bar
48
+ ```
49
+
50
+ _All_ `httpxy` [options](https://github.com/unjs/httpxy#options) can be used, along with some extra `http-proxy-middleware` [options](#options).
51
+
52
+ ## Table of Contents <!-- omit in toc -->
53
+
54
+ <!-- // spell-checker:disable -->
55
+
56
+ - [Install](#install)
57
+ - [Basic usage](#basic-usage)
58
+ - [Express Server Example](#express-server-example)
59
+ - [app.use(path, proxy)](#appusepath-proxy)
60
+ - [Options](#options)
61
+ - [`pathFilter` (string, \[\]string, glob, \[\]glob, function)](#pathfilter-string-string-glob-glob-function)
62
+ - [`pathRewrite` (object/function)](#pathrewrite-objectfunction)
63
+ - [`router` (object/function)](#router-objectfunction)
64
+ - [`plugins` (Array)](#plugins-array)
65
+ - [`ejectPlugins` (boolean) default: `false`](#ejectplugins-boolean-default-false)
66
+ - [`definePlugin` helper](#defineplugin-helper)
67
+ - [`logger` (Object)](#logger-object)
68
+ - [`httpxy` events](#httpxy-events)
69
+ - [`httpxy` options](#httpxy-options)
70
+ - [WebSocket](#websocket)
71
+ - [External WebSocket upgrade](#external-websocket-upgrade)
72
+ - [Intercept and manipulate requests](#intercept-and-manipulate-requests)
73
+ - [Intercept and manipulate responses](#intercept-and-manipulate-responses)
74
+ - [Node.js 17+: ECONNREFUSED issue with IPv6 and localhost (#705)](#nodejs-17-econnrefused-issue-with-ipv6-and-localhost-705)
75
+ - [Debugging](#debugging)
76
+ - [Working examples](#working-examples)
77
+ - [Recipes](#recipes)
78
+ - [Compatible servers](#compatible-servers)
79
+ - [Tests](#tests)
80
+ - [Changelog](#changelog)
81
+ - [License](#license)
82
+
83
+ <!-- // spell-checker:enable -->
84
+
85
+ ## Install
86
+
87
+ ```shell
88
+ npm install --save-dev http-proxy-middleware
89
+ ```
90
+
91
+ ## Basic usage
92
+
93
+ Create and configure a proxy middleware with: `createProxyMiddleware(config)`.
94
+
95
+ ```javascript
96
+ import { createProxyMiddleware } from 'http-proxy-middleware';
97
+
98
+ const apiProxy = createProxyMiddleware({
99
+ target: 'http://www.example.org',
100
+ changeOrigin: true,
101
+ });
102
+
103
+ // 'apiProxy' is now ready to be used as middleware in a server.
104
+ ```
105
+
106
+ - **options.target**: target host to proxy to. _(protocol + host)_
107
+ - **options.changeOrigin**: for virtual hosted sites
108
+
109
+ - see full list of [`http-proxy-middleware` configuration options](#options)
110
+
111
+ ## Express Server Example
112
+
113
+ An example with `express` server.
114
+
115
+ ```javascript
116
+ // include dependencies
117
+ import express from 'express';
118
+ import { createProxyMiddleware } from 'http-proxy-middleware';
119
+
120
+ const app = express();
121
+
122
+ // create the proxy
123
+ /** @type {import('http-proxy-middleware').RequestHandler<import('express').Request, import('express').Response>} */
124
+ const exampleProxy = createProxyMiddleware({
125
+ target: 'http://www.example.org/api', // target host with the same base path
126
+ changeOrigin: true, // needed for virtual hosted sites
127
+ });
128
+
129
+ // mount `exampleProxy` in web server
130
+ app.use('/api', exampleProxy);
131
+ app.listen(3000);
132
+ ```
133
+
134
+ ### app.use(path, proxy)
135
+
136
+ If you want to use the server's `app.use` `path` parameter to match requests.
137
+ Use `pathFilter` option to further include/exclude requests which you want to proxy.
138
+
139
+ ```javascript
140
+ app.use(
141
+ createProxyMiddleware({
142
+ target: 'http://www.example.org/api',
143
+ changeOrigin: true,
144
+ pathFilter: '/api/proxy-only-this-path',
145
+ }),
146
+ );
147
+ ```
148
+
149
+ `app.use` documentation:
150
+
151
+ - express: <http://expressjs.com/en/4x/api.html#app.use>
152
+ - connect: <https://github.com/senchalabs/connect#mount-middleware>
153
+ - polka: <https://github.com/lukeed/polka#usebase-fn>
154
+
155
+ ## Options
156
+
157
+ http-proxy-middleware options:
158
+
159
+ ### `pathFilter` (string, []string, glob, []glob, function)
160
+
161
+ 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.
162
+
163
+ - **path matching**
164
+ - `createProxyMiddleware({...})` - matches any path, all requests will be proxied when `pathFilter` is not configured.
165
+ - `createProxyMiddleware({ pathFilter: '/api', ...})` - matches paths starting with `/api`
166
+
167
+ - **multiple path matching**
168
+ - `createProxyMiddleware({ pathFilter: ['/api', '/ajax', '/someotherpath'], ...})`
169
+
170
+ - **wildcard path matching**
171
+
172
+ 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.
173
+ - `createProxyMiddleware({ pathFilter: '**', ...})` matches any path, all requests will be proxied.
174
+ - `createProxyMiddleware({ pathFilter: '**/*.html', ...})` matches any path which ends with `.html`
175
+ - `createProxyMiddleware({ pathFilter: '/*.html', ...})` matches paths directly under path-absolute
176
+ - `createProxyMiddleware({ pathFilter: '/api/**/*.html', ...})` matches requests ending with `.html` in the path of `/api`
177
+ - `createProxyMiddleware({ pathFilter: ['/api/**', '/ajax/**'], ...})` combine multiple patterns
178
+ - `createProxyMiddleware({ pathFilter: ['/api/**', '!**/bad.json'], ...})` exclusion
179
+
180
+ **Note**: In multiple path matching, you cannot use string paths and wildcard paths together.
181
+
182
+ - **custom matching**
183
+
184
+ For full control you can provide a custom function to determine which requests should be proxied or not.
185
+
186
+ ```javascript
187
+ /**
188
+ * @return {Boolean}
189
+ */
190
+ const pathFilter = function (path, req) {
191
+ return path.match('^/api') && req.method === 'GET';
192
+ };
193
+
194
+ const apiProxy = createProxyMiddleware({
195
+ target: 'http://www.example.org',
196
+ pathFilter: pathFilter,
197
+ });
198
+ ```
199
+
200
+ ### `pathRewrite` (object/function)
201
+
202
+ Rewrite target's url path. Object-keys will be used as _RegExp_ to match paths.
203
+
204
+ ```javascript
205
+ // rewrite path
206
+ pathRewrite: {'^/old/api' : '/new/api'}
207
+
208
+ // remove path
209
+ pathRewrite: {'^/remove/api' : ''}
210
+
211
+ // add base path
212
+ pathRewrite: {'^/' : '/basepath/'}
213
+
214
+ // custom rewriting
215
+ pathRewrite: function (path, req, res, options) { return path.replace('/api', '/base/api') }
216
+
217
+ // custom rewriting, returning Promise
218
+ pathRewrite: async function (path, req, res, options) {
219
+ const should_add_something = await httpRequestToDecideSomething(path);
220
+ if (should_add_something) path += "something";
221
+ return path;
222
+ }
223
+
224
+ // `res` is undefined in WebSocket upgrade flows.
225
+ ```
226
+
227
+ ### `router` (object/function)
228
+
229
+ Re-target `option.target` for specific requests.
230
+
231
+ ```javascript
232
+ // Use `host` and/or `path` to match requests. First match will be used.
233
+ // The order of the configuration matters.
234
+ router: {
235
+ 'integration.localhost:3000' : 'http://127.0.0.1:8001', // host only
236
+ 'staging.localhost:3000' : 'http://127.0.0.1:8002', // host only
237
+ 'localhost:3000/api' : 'http://127.0.0.1:8003', // host + path
238
+ '/rest' : 'http://127.0.0.1:8004' // path only
239
+ }
240
+
241
+ // Custom router function (string target)
242
+ router: function(req, res, options) {
243
+ return 'http://127.0.0.1:8004';
244
+ }
245
+
246
+ // Custom router function (target object)
247
+ router: function(req, res, options) {
248
+ return {
249
+ protocol: 'https:', // The : is required
250
+ host: '127.0.0.1',
251
+ port: 8004
252
+ };
253
+ }
254
+
255
+ // Asynchronous router function which returns promise
256
+ router: async function(req, res, options) {
257
+ const url = await doSomeIO();
258
+ return url;
259
+ }
260
+
261
+ // NOTE: `res` is undefined in WebSocket upgrade flows.
262
+ ```
263
+
264
+ ### `plugins` (Array)
265
+
266
+ ```js
267
+ const simpleRequestLogger = (proxyServer, options) => {
268
+ proxyServer.on('proxyReq', (proxyReq, req, res) => {
269
+ console.log(`[HPM] [${req.method}] ${req.url}`); // outputs: [HPM] GET /users
270
+ });
271
+ },
272
+
273
+ const config = {
274
+ target: `http://example.org`,
275
+ changeOrigin: true,
276
+ plugins: [simpleRequestLogger],
277
+ };
278
+ ```
279
+
280
+ ### `ejectPlugins` (boolean) default: `false`
281
+
282
+ If you're not satisfied with the pre-configured plugins, you can eject them by configuring `ejectPlugins: true`.
283
+
284
+ NOTE: register your own error handlers to prevent server from crashing.
285
+
286
+ ```js
287
+ // eject default plugins and manually add them back
288
+ import {
289
+ debugProxyErrorsPlugin, // subscribe to proxy errors to prevent server from crashing
290
+ errorResponsePlugin, // return 5xx response on proxy error
291
+ loggerPlugin, // log proxy events to a logger (ie. console)
292
+ proxyEventsPlugin, // implements the "on:" option
293
+ } from 'http-proxy-middleware';
294
+
295
+ createProxyMiddleware({
296
+ target: `http://example.org`,
297
+ changeOrigin: true,
298
+ ejectPlugins: true,
299
+ plugins: [debugProxyErrorsPlugin, loggerPlugin, errorResponsePlugin, proxyEventsPlugin],
300
+ });
301
+ ```
302
+
303
+ ## `definePlugin` helper
304
+
305
+ Create your own `http-proxy-middleware` plugin.
306
+
307
+ (Default plugins are created with `definePlugin`)
308
+
309
+ ```ts
310
+ import { createProxyMiddleware, definePlugin } from 'http-proxy-middleware';
311
+
312
+ const myPlugin = definePlugin((proxyServer, options) => {
313
+ // plugin implementation
314
+ });
315
+
316
+ // use configure and use plugin
317
+ createProxyMiddleware({
318
+ target: `http://example.org`,
319
+ plugins: [myPlugin],
320
+ });
321
+ ```
322
+
323
+ ### `logger` (Object)
324
+
325
+ Configure a logger to output information from http-proxy-middleware: ie. `console`, `winston`, `pino`, `bunyan`, `log4js`, etc...
326
+
327
+ Only `info`, `warn`, `error` are used internally for compatibility across different loggers.
328
+
329
+ If you use `winston`, make sure to enable interpolation: <https://github.com/winstonjs/winston#string-interpolation>
330
+
331
+ See also logger recipes ([recipes/logger.md](https://github.com/chimurai/http-proxy-middleware/blob/master/recipes/logger.md)) for more details.
332
+
333
+ ```javascript
334
+ createProxyMiddleware({
335
+ logger: console,
336
+ });
337
+ ```
338
+
339
+ ## `httpxy` events
340
+
341
+ Subscribe to [httpxy events](https://github.com/unjs/httpxy#events) with the `on` option:
342
+
343
+ ```js
344
+ createProxyMiddleware({
345
+ target: 'http://www.example.org',
346
+ on: {
347
+ proxyReq: (proxyReq, req, res) => {
348
+ /* handle proxyReq */
349
+ },
350
+ proxyRes: (proxyRes, req, res) => {
351
+ /* handle proxyRes */
352
+ },
353
+ error: (err, req, res) => {
354
+ /* handle error */
355
+ },
356
+ },
357
+ });
358
+ ```
359
+
360
+ - **option.on.error**: function, subscribe to httpxy's `error` event for custom error handling.
361
+
362
+ ```javascript
363
+ function onError(err, req, res, target) {
364
+ res.writeHead(500, {
365
+ 'Content-Type': 'text/plain',
366
+ });
367
+ res.end('Something went wrong. And we are reporting a custom error message.');
368
+ }
369
+ ```
370
+
371
+ - **option.on.proxyRes**: function, subscribe to httpxy's `proxyRes` event.
372
+
373
+ ```javascript
374
+ function onProxyRes(proxyRes, req, res) {
375
+ proxyRes.headers['x-added'] = 'foobar'; // add new header to response
376
+ delete proxyRes.headers['x-removed']; // remove header from response
377
+ }
378
+ ```
379
+
380
+ - **option.on.proxyReq**: function, subscribe to httpxy's `proxyReq` event.
381
+
382
+ ```javascript
383
+ function onProxyReq(proxyReq, req, res) {
384
+ // add custom header to request
385
+ proxyReq.setHeader('x-added', 'foobar');
386
+ // or log the req
387
+ }
388
+ ```
389
+
390
+ - **option.on.proxyReqWs**: function, subscribe to httpxy's `proxyReqWs` event.
391
+
392
+ ```javascript
393
+ function onProxyReqWs(proxyReq, req, socket, options, head) {
394
+ // add custom header
395
+ proxyReq.setHeader('X-Special-Proxy-Header', 'foobar');
396
+ }
397
+ ```
398
+
399
+ - **option.on.open**: function, subscribe to httpxy's `open` event.
400
+
401
+ ```javascript
402
+ function onOpen(proxySocket) {
403
+ // listen for messages coming FROM the target here
404
+ proxySocket.on('data', hybridParseAndLogMessage);
405
+ }
406
+ ```
407
+
408
+ - **option.on.close**: function, subscribe to httpxy's `close` event.
409
+
410
+ ```javascript
411
+ function onClose(res, socket, head) {
412
+ // view disconnected websocket connections
413
+ console.log('Client disconnected');
414
+ }
415
+ ```
416
+
417
+ ## `httpxy` options
418
+
419
+ The following options are provided by the underlying [httpxy](https://github.com/unjs/httpxy#options) library.
420
+
421
+ - **option.target**: url string to be parsed with the url module
422
+ - **option.forward**: url string to be parsed with the url module
423
+ - **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)
424
+ - **option.ssl**: object to be passed to https.createServer()
425
+ - **option.ws**: true/false: if you want to proxy websockets
426
+ - **option.xfwd**: true/false, adds x-forward headers
427
+ - **option.secure**: true/false, if you want to verify the SSL Certs
428
+ - **option.toProxy**: true/false, passes the absolute URL as the `path` (useful for proxying to proxies)
429
+ - **option.prependPath**: true/false, Default: true - specify whether you want to prepend the target's path to the proxy path
430
+ - **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).
431
+ - **option.localAddress** : Local interface string to bind for outgoing connections
432
+ - **option.changeOrigin**: true/false, Default: false - changes the origin of the host header to the target URL
433
+ - **option.preserveHeaderKeyCase**: true/false, Default: false - specify whether you want to keep letter case of response header key
434
+ - **option.auth** : Basic authentication i.e. 'user:password' to compute an Authorization header.
435
+ - **option.hostRewrite**: rewrites the location hostname on (301/302/307/308) redirects.
436
+ - **option.autoRewrite**: rewrites the location host/port on (301/302/307/308) redirects based on requested host/port. Default: false.
437
+ - **option.protocolRewrite**: rewrites the location protocol on (301/302/307/308) redirects to 'http' or 'https'. Default: null.
438
+ - **option.cookieDomainRewrite**: rewrites domain of `set-cookie` headers. Possible values:
439
+ - `false` (default): disable cookie rewriting
440
+ - String: new domain, for example `cookieDomainRewrite: "new.domain"`. To remove the domain, use `cookieDomainRewrite: ""`.
441
+ - Object: mapping of domains to new domains, use `"*"` to match all domains.
442
+ For example keep one domain unchanged, rewrite one domain and remove other domains:
443
+
444
+ ```jsonc
445
+ cookieDomainRewrite: {
446
+ "unchanged.domain": "unchanged.domain",
447
+ "old.domain": "new.domain",
448
+ "*": ""
449
+ }
450
+ ```
451
+
452
+ - **option.cookiePathRewrite**: rewrites path of `set-cookie` headers. Possible values:
453
+ - `false` (default): disable cookie rewriting
454
+ - String: new path, for example `cookiePathRewrite: "/newPath/"`. To remove the path, use `cookiePathRewrite: ""`. To set path to root use `cookiePathRewrite: "/"`.
455
+ - Object: mapping of paths to new paths, use `"*"` to match all paths.
456
+ For example, to keep one path unchanged, rewrite one path and remove other paths:
457
+
458
+ ```jsonc
459
+ cookiePathRewrite: {
460
+ "/unchanged.path/": "/unchanged.path/",
461
+ "/old.path/": "/new.path/",
462
+ "*": ""
463
+ }
464
+ ```
465
+
466
+ - **option.headers**: object, adds [request headers](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Request_fields). (Example: `{host:'www.example.org'}`)
467
+ - **option.proxyTimeout**: timeout (in millis) when proxy receives no response from target
468
+ - **option.timeout**: timeout (in millis) for incoming requests
469
+ - **option.followRedirects**: true/false, Default: false - specify whether you want to follow redirects
470
+ - **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
471
+ - **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:
472
+
473
+ ```javascript
474
+ import { createProxyServer } from 'httpxy';
475
+ import streamify from 'stream-array';
476
+
477
+ const proxy = createProxyServer();
478
+
479
+ export default function proxyWithBody(req, res, next) {
480
+ proxy.web(
481
+ req,
482
+ res,
483
+ {
484
+ target: 'http://127.0.0.1:4003/',
485
+ buffer: streamify(req.rawBody),
486
+ },
487
+ next,
488
+ );
489
+ }
490
+ ```
491
+
492
+ ## WebSocket
493
+
494
+ See [recipes/websocket.md](recipes/websocket.md) for more examples.
495
+
496
+ ```javascript
497
+ // verbose api
498
+ createProxyMiddleware({ pathFilter: '/', target: 'http://echo.websocket.org', ws: true });
499
+ ```
500
+
501
+ ### External WebSocket upgrade
502
+
503
+ In the previous WebSocket examples, http-proxy-middleware relies on an 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.
504
+
505
+ When the same middleware instance is attached to multiple servers and `ws: true` is used, each server needs its own initial HTTP request before upgrades are auto-subscribed.
506
+
507
+ ```javascript
508
+ const wsProxy = createProxyMiddleware({ target: 'ws://echo.websocket.org', changeOrigin: true });
509
+
510
+ const app = express();
511
+ app.use(wsProxy);
512
+
513
+ const server = app.listen(3000);
514
+ server.on('upgrade', wsProxy.upgrade); // <-- subscribe to http 'upgrade'
515
+ ```
516
+
517
+ ## Intercept and manipulate requests
518
+
519
+ Intercept requests from downstream by defining `onProxyReq` in `createProxyMiddleware`.
520
+
521
+ Currently the only pre-provided request interceptor is `fixRequestBody`, which is used to fix proxied POST requests when `bodyParser` is applied before this middleware.
522
+
523
+ Example:
524
+
525
+ ```javascript
526
+ import { createProxyMiddleware, fixRequestBody } from 'http-proxy-middleware';
527
+
528
+ const proxy = createProxyMiddleware({
529
+ /**
530
+ * Fix bodyParser
531
+ **/
532
+ on: {
533
+ proxyReq: fixRequestBody,
534
+ },
535
+ });
536
+ ```
537
+
538
+ ## Intercept and manipulate responses
539
+
540
+ Intercept responses from upstream with `responseInterceptor`. (Make sure to set `selfHandleResponse: true`)
541
+
542
+ Responses which are compressed with `brotli`, `gzip` and `deflate` will be decompressed automatically. The response will be returned as `buffer` ([docs](https://nodejs.org/api/buffer.html)) which you can manipulate.
543
+
544
+ With `buffer`, response manipulation is not limited to text responses (html/css/js, etc...); image manipulation will be possible too. ([example](https://github.com/chimurai/http-proxy-middleware/blob/master/recipes/response-interceptor.md#manipulate-image-response))
545
+
546
+ NOTE: `responseInterceptor` disables streaming of target's response.
547
+
548
+ Example:
549
+
550
+ ```javascript
551
+ import { createProxyMiddleware, responseInterceptor } from 'http-proxy-middleware';
552
+
553
+ const proxy = createProxyMiddleware({
554
+ /**
555
+ * IMPORTANT: avoid res.end being called automatically
556
+ **/
557
+ selfHandleResponse: true, // res.end() will be called internally by responseInterceptor()
558
+
559
+ /**
560
+ * Intercept response and replace 'Hello' with 'Goodbye'
561
+ **/
562
+ on: {
563
+ proxyRes: responseInterceptor(async (responseBuffer, proxyRes, req, res) => {
564
+ const response = responseBuffer.toString('utf8'); // convert buffer to string
565
+ return response.replace('Hello', 'Goodbye'); // manipulate response and return the result
566
+ }),
567
+ },
568
+ });
569
+ ```
570
+
571
+ Check out [interception recipes](https://github.com/chimurai/http-proxy-middleware/blob/master/recipes/response-interceptor.md) for more examples.
572
+
573
+ ## Node.js 17+: ECONNREFUSED issue with IPv6 and localhost ([#705](https://github.com/chimurai/http-proxy-middleware/issues/705))
574
+
575
+ Node.js 17+ no longer prefers IPv4 over IPv6 for DNS lookups.
576
+ E.g. It's **not** guaranteed that `localhost` will be resolved to `127.0.0.1` – it might just as well be `::1` (or some other IP address).
577
+
578
+ If your target server only accepts IPv4 connections, trying to proxy to `localhost` will fail if resolved to `::1` (IPv6).
579
+
580
+ Ways to solve it:
581
+
582
+ - Change `target: "http://localhost"` to `target: "http://127.0.0.1"` (IPv4).
583
+ - Change the target server to (also) accept IPv6 connections.
584
+ - Add this flag when running `node`: `node index.js --dns-result-order=ipv4first`. (Not recommended.)
585
+
586
+ Additional IPv6 notes:
587
+
588
+ - Unspecified IPv6 host `http://[::]:port` is normalized to loopback (`::1`) to reach local listeners.
589
+
590
+ > Note: There’s a thing called [Happy Eyeballs](https://en.wikipedia.org/wiki/Happy_Eyeballs) which means connecting to both IPv4 and IPv6 in parallel, which Node.js doesn’t have, but explains why for example `curl` can connect.
591
+
592
+ ## Debugging
593
+
594
+ Configure the `DEBUG` environment variable enable debug logging.
595
+
596
+ See [`debug`](https://github.com/debug-js/debug#readme) project for more options.
597
+
598
+ ```shell
599
+ DEBUG=http-proxy-middleware* node server.js
600
+
601
+ $ http-proxy-middleware proxy created +0ms
602
+ $ http-proxy-middleware proxying request to target: 'http://www.example.org' +359ms
603
+ ```
604
+
605
+ ## Working examples
606
+
607
+ View and play around with [working examples](https://github.com/chimurai/http-proxy-middleware/tree/master/examples).
608
+
609
+ - Browser-Sync ([example source](https://github.com/chimurai/http-proxy-middleware/tree/master/examples/browser-sync/index.js))
610
+ - express ([example source](https://github.com/chimurai/http-proxy-middleware/tree/master/examples/express/index.js))
611
+ - connect ([example source](https://github.com/chimurai/http-proxy-middleware/tree/master/examples/connect/index.js))
612
+ - WebSocket ([example source](https://github.com/chimurai/http-proxy-middleware/tree/master/examples/websocket/index.js))
613
+ - Response Manipulation ([example source](https://github.com/chimurai/http-proxy-middleware/blob/master/examples/response-interceptor/index.js))
614
+
615
+ ## Recipes
616
+
617
+ View the [recipes](https://github.com/chimurai/http-proxy-middleware/tree/master/recipes) for common use cases.
618
+
619
+ ## Compatible servers
620
+
621
+ `http-proxy-middleware` is compatible with the following servers:
622
+
623
+ - [connect](https://www.npmjs.com/package/connect)
624
+ - [express](https://www.npmjs.com/package/express)
625
+ - [hono](https://www.npmjs.com/package/@hono/node-server)
626
+ - [next.js](https://www.npmjs.com/package/next)
627
+ - [fastify](https://www.npmjs.com/package/fastify)
628
+ - [browser-sync](https://www.npmjs.com/package/browser-sync)
629
+ - [lite-server](https://www.npmjs.com/package/lite-server)
630
+ - [polka](https://github.com/lukeed/polka)
631
+ - [grunt-contrib-connect](https://www.npmjs.com/package/grunt-contrib-connect)
632
+ - [grunt-browser-sync](https://www.npmjs.com/package/grunt-browser-sync)
633
+ - [gulp-connect](https://www.npmjs.com/package/gulp-connect)
634
+ - [gulp-webserver](https://www.npmjs.com/package/gulp-webserver)
635
+
636
+ Sample implementations can be found in the [server recipes](https://github.com/chimurai/http-proxy-middleware/tree/master/recipes/servers.md).
637
+
638
+ ## Tests
639
+
640
+ Run the test suite:
641
+
642
+ ```bash
643
+ # install dependencies
644
+ $ yarn
645
+
646
+ # linting
647
+ $ yarn lint
648
+ $ yarn lint:fix
649
+
650
+ # building (compile typescript to js)
651
+ $ yarn build
652
+
653
+ # unit tests
654
+ $ yarn test
655
+
656
+ # code coverage
657
+ $ yarn coverage
658
+
659
+ # check spelling mistakes
660
+ $ yarn spellcheck
661
+ ```
662
+
663
+ ## Changelog
664
+
665
+ - [View changelog](https://github.com/chimurai/http-proxy-middleware/blob/master/CHANGELOG.md)
666
+
667
+ ## License
668
+
669
+ The MIT License (MIT)
670
+
671
+ Copyright (c) 2015-2026 Steven Chim