http-proxy-middleware 3.0.0-beta.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/dist/errors.js +1 -1
- package/dist/get-plugins.js +2 -3
- package/dist/handlers/fix-request-body.d.ts +1 -1
- package/dist/handlers/response-interceptor.d.ts +1 -1
- package/dist/http-proxy-middleware.js +3 -4
- package/dist/legacy/options-adapter.js +11 -5
- package/dist/path-filter.d.ts +1 -1
- package/dist/path-filter.js +1 -1
- package/dist/plugins/default/error-response-plugin.js +1 -1
- package/dist/plugins/default/logger-plugin.js +4 -6
- package/dist/types.d.ts +6 -5
- package/package.json +28 -28
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://github.com/chimurai/http-proxy-middleware/actions/workflows/ci.yml?query=branch%3Amaster)
|
|
4
4
|
[](https://coveralls.io/r/chimurai/http-proxy-middleware)
|
|
5
|
-
[](https://snyk.io/test/github/chimurai/http-proxy-middleware)
|
|
6
6
|
[](https://www.npmjs.com/package/http-proxy-middleware)
|
|
7
7
|
|
|
8
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) and [many more](#compatible-servers).
|
|
@@ -39,7 +39,7 @@ app.use(
|
|
|
39
39
|
createProxyMiddleware({
|
|
40
40
|
target: 'http://www.example.org/secret',
|
|
41
41
|
changeOrigin: true,
|
|
42
|
-
})
|
|
42
|
+
}),
|
|
43
43
|
);
|
|
44
44
|
|
|
45
45
|
app.listen(3000);
|
|
@@ -61,7 +61,7 @@ app.use(
|
|
|
61
61
|
createProxyMiddleware({
|
|
62
62
|
target: 'http://www.example.org/api',
|
|
63
63
|
changeOrigin: true,
|
|
64
|
-
})
|
|
64
|
+
}),
|
|
65
65
|
);
|
|
66
66
|
|
|
67
67
|
app.listen(3000);
|
|
@@ -164,7 +164,7 @@ app.use(
|
|
|
164
164
|
target: 'http://www.example.org/api',
|
|
165
165
|
changeOrigin: true,
|
|
166
166
|
pathFilter: '/api/proxy-only-this-path',
|
|
167
|
-
})
|
|
167
|
+
}),
|
|
168
168
|
);
|
|
169
169
|
```
|
|
170
170
|
|
|
@@ -489,7 +489,7 @@ The following options are provided by the underlying [http-proxy](https://github
|
|
|
489
489
|
target: 'http://127.0.0.1:4003/',
|
|
490
490
|
buffer: streamify(req.rawBody),
|
|
491
491
|
},
|
|
492
|
-
next
|
|
492
|
+
next,
|
|
493
493
|
);
|
|
494
494
|
};
|
|
495
495
|
```
|
package/dist/errors.js
CHANGED
|
@@ -7,4 +7,4 @@ var ERRORS;
|
|
|
7
7
|
ERRORS["ERR_CONTEXT_MATCHER_GENERIC"] = "[HPM] Invalid context. Expecting something like: \"/api\" or [\"/api\", \"/ajax\"]";
|
|
8
8
|
ERRORS["ERR_CONTEXT_MATCHER_INVALID_ARRAY"] = "[HPM] Invalid pathFilter. Expecting something like: [\"/api\", \"/ajax\"] or [\"/api/**\", \"!**.html\"]";
|
|
9
9
|
ERRORS["ERR_PATH_REWRITER_CONFIG"] = "[HPM] Invalid pathRewrite config. Expecting object with pathRewrite config or a rewrite function";
|
|
10
|
-
})(ERRORS
|
|
10
|
+
})(ERRORS || (exports.ERRORS = ERRORS = {}));
|
package/dist/get-plugins.js
CHANGED
|
@@ -3,13 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.getPlugins = void 0;
|
|
4
4
|
const default_1 = require("./plugins/default");
|
|
5
5
|
function getPlugins(options) {
|
|
6
|
-
var _a, _b;
|
|
7
6
|
// don't load default errorResponsePlugin if user has specified their own
|
|
8
|
-
const maybeErrorResponsePlugin = !!
|
|
7
|
+
const maybeErrorResponsePlugin = !!options.on?.error ? [] : [default_1.errorResponsePlugin];
|
|
9
8
|
const defaultPlugins = !!options.ejectPlugins
|
|
10
9
|
? [] // no default plugins when ejecting
|
|
11
10
|
: [default_1.debugProxyErrorsPlugin, default_1.proxyEventsPlugin, default_1.loggerPlugin, ...maybeErrorResponsePlugin];
|
|
12
|
-
const userPlugins =
|
|
11
|
+
const userPlugins = options.plugins ?? [];
|
|
13
12
|
return [...defaultPlugins, ...userPlugins];
|
|
14
13
|
}
|
|
15
14
|
exports.getPlugins = getPlugins;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
/// <reference types="node" />
|
|
3
3
|
import type * as http from 'http';
|
|
4
|
-
|
|
4
|
+
type Interceptor<TReq = http.IncomingMessage, TRes = http.ServerResponse> = (buffer: Buffer, proxyRes: TReq, req: TReq, res: TRes) => Promise<Buffer | string>;
|
|
5
5
|
/**
|
|
6
6
|
* Intercept responses from upstream.
|
|
7
7
|
* Automatically decompress (deflate, gzip, brotli).
|
|
@@ -14,8 +14,7 @@ class HttpProxyMiddleware {
|
|
|
14
14
|
this.wsInternalSubscribed = false;
|
|
15
15
|
this.serverOnCloseSubscribed = false;
|
|
16
16
|
// https://github.com/Microsoft/TypeScript/wiki/'this'-in-TypeScript#red-flags-for-this
|
|
17
|
-
this.middleware = async (req, res, next) => {
|
|
18
|
-
var _a, _b;
|
|
17
|
+
this.middleware = (async (req, res, next) => {
|
|
19
18
|
if (this.shouldProxy(this.proxyOptions.pathFilter, req)) {
|
|
20
19
|
try {
|
|
21
20
|
const activeProxyOptions = await this.prepareProxyRequest(req);
|
|
@@ -37,7 +36,7 @@ class HttpProxyMiddleware {
|
|
|
37
36
|
* req.socket: node >= 13
|
|
38
37
|
* req.connection: node < 13 (Remove this when node 12/13 support is dropped)
|
|
39
38
|
*/
|
|
40
|
-
const server = (
|
|
39
|
+
const server = (req.socket ?? req.connection)?.server;
|
|
41
40
|
if (server && !this.serverOnCloseSubscribed) {
|
|
42
41
|
server.on('close', () => {
|
|
43
42
|
(0, debug_1.Debug)('server close signal received: closing proxy server');
|
|
@@ -49,7 +48,7 @@ class HttpProxyMiddleware {
|
|
|
49
48
|
// use initial request to access the server object to subscribe to http upgrade event
|
|
50
49
|
this.catchUpgradeRequest(server);
|
|
51
50
|
}
|
|
52
|
-
};
|
|
51
|
+
});
|
|
53
52
|
this.catchUpgradeRequest = (server) => {
|
|
54
53
|
if (!this.wsInternalSubscribed) {
|
|
55
54
|
(0, debug_1.Debug)('subscribing to server upgrade event');
|
|
@@ -18,12 +18,15 @@ const proxyEventMap = {
|
|
|
18
18
|
* Convert {@link LegacyOptions legacy Options} to new {@link Options}
|
|
19
19
|
*/
|
|
20
20
|
function legacyOptionsAdapter(legacyContext, legacyOptions) {
|
|
21
|
-
let options;
|
|
21
|
+
let options = {};
|
|
22
22
|
let logger;
|
|
23
23
|
// https://github.com/chimurai/http-proxy-middleware/pull/716
|
|
24
24
|
if (typeof legacyContext === 'string' && !!url.parse(legacyContext).host) {
|
|
25
25
|
throw new Error(`Shorthand syntax is removed from legacyCreateProxyMiddleware().
|
|
26
|
-
Please use "legacyCreateProxyMiddleware({ target: 'http://www.example.org' })" instead
|
|
26
|
+
Please use "legacyCreateProxyMiddleware({ target: 'http://www.example.org' })" instead.
|
|
27
|
+
|
|
28
|
+
More details: https://github.com/chimurai/http-proxy-middleware/blob/master/MIGRATION.md#removed-shorthand-usage
|
|
29
|
+
`);
|
|
27
30
|
}
|
|
28
31
|
// detect old "context" argument and convert to "options.pathFilter"
|
|
29
32
|
// https://github.com/chimurai/http-proxy-middleware/pull/722/files#diff-a2a171449d862fe29692ce031981047d7ab755ae7f84c707aef80701b3ea0c80L4
|
|
@@ -37,13 +40,16 @@ function legacyOptionsAdapter(legacyContext, legacyOptions) {
|
|
|
37
40
|
pathFilter: '${legacyContext}',
|
|
38
41
|
}
|
|
39
42
|
|
|
40
|
-
More details: https://github.com/chimurai/http-proxy-middleware/blob/master/MIGRATION.md
|
|
43
|
+
More details: https://github.com/chimurai/http-proxy-middleware/blob/master/MIGRATION.md#removed-context-argument
|
|
41
44
|
`);
|
|
42
45
|
}
|
|
43
46
|
else if (legacyContext && !legacyOptions) {
|
|
44
47
|
options = { ...legacyContext };
|
|
45
48
|
logger = getLegacyLogger(options);
|
|
46
49
|
}
|
|
50
|
+
else {
|
|
51
|
+
logger = getLegacyLogger({});
|
|
52
|
+
}
|
|
47
53
|
// map old event names to new event names
|
|
48
54
|
// https://github.com/chimurai/http-proxy-middleware/pull/745/files#diff-c54113cf61ec99691748a3890bfbeb00e10efb3f0a76f03a0fd9ec49072e410aL48-L53
|
|
49
55
|
Object.entries(proxyEventMap).forEach(([legacyEventName, proxyEventName]) => {
|
|
@@ -59,7 +65,7 @@ function legacyOptionsAdapter(legacyContext, legacyOptions) {
|
|
|
59
65
|
},
|
|
60
66
|
}
|
|
61
67
|
|
|
62
|
-
More details: https://github.com/chimurai/http-proxy-middleware/blob/master/MIGRATION.md
|
|
68
|
+
More details: https://github.com/chimurai/http-proxy-middleware/blob/master/MIGRATION.md#refactored-proxy-events
|
|
63
69
|
`);
|
|
64
70
|
}
|
|
65
71
|
});
|
|
@@ -77,7 +83,7 @@ function legacyOptionsAdapter(legacyContext, legacyOptions) {
|
|
|
77
83
|
logger: console,
|
|
78
84
|
}
|
|
79
85
|
|
|
80
|
-
More details: https://github.com/chimurai/http-proxy-middleware/blob/master/MIGRATION.md
|
|
86
|
+
More details: https://github.com/chimurai/http-proxy-middleware/blob/master/MIGRATION.md#removed-logprovider-and-loglevel-options
|
|
81
87
|
`);
|
|
82
88
|
}
|
|
83
89
|
return options;
|
package/dist/path-filter.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import type { Filter } from './types';
|
|
3
3
|
import type * as http from 'http';
|
|
4
|
-
export declare function matchPathFilter<TReq = http.IncomingMessage>(pathFilter: Filter<TReq
|
|
4
|
+
export declare function matchPathFilter<TReq = http.IncomingMessage>(pathFilter: Filter<TReq> | undefined, uri: string | undefined, req: http.IncomingMessage): boolean;
|
package/dist/path-filter.js
CHANGED
|
@@ -39,7 +39,7 @@ exports.matchPathFilter = matchPathFilter;
|
|
|
39
39
|
*/
|
|
40
40
|
function matchSingleStringPath(pathFilter, uri) {
|
|
41
41
|
const pathname = getUrlPathName(uri);
|
|
42
|
-
return pathname
|
|
42
|
+
return pathname?.indexOf(pathFilter) === 0;
|
|
43
43
|
}
|
|
44
44
|
function matchSingleGlobPath(pattern, uri) {
|
|
45
45
|
const pathname = getUrlPathName(uri);
|
|
@@ -8,7 +8,7 @@ const errorResponsePlugin = (proxyServer, options) => {
|
|
|
8
8
|
if (!req && !res) {
|
|
9
9
|
throw err; // "Error: Must provide a proper URL as target"
|
|
10
10
|
}
|
|
11
|
-
if (
|
|
11
|
+
if ('writeHead' in res && !res.headersSent) {
|
|
12
12
|
const statusCode = (0, status_code_1.getStatusCode)(err.code);
|
|
13
13
|
res.writeHead(statusCode);
|
|
14
14
|
}
|
|
@@ -5,10 +5,9 @@ const logger_1 = require("../../logger");
|
|
|
5
5
|
const loggerPlugin = (proxyServer, options) => {
|
|
6
6
|
const logger = (0, logger_1.getLogger)(options);
|
|
7
7
|
proxyServer.on('error', (err, req, res, target) => {
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const targetHref = `${target === null || target === void 0 ? void 0 : target.href}`; // target is undefined when websocket errors
|
|
8
|
+
const hostname = req?.headers?.host;
|
|
9
|
+
const requestHref = `${hostname}${req?.url}`;
|
|
10
|
+
const targetHref = `${target?.href}`; // target is undefined when websocket errors
|
|
12
11
|
const errorMessage = '[HPM] Error occurred while proxying request %s to %s [%s] (%s)';
|
|
13
12
|
const errReference = 'https://nodejs.org/api/errors.html#errors_common_system_errors'; // link to Node Common Systems Errors page
|
|
14
13
|
logger.error(errorMessage, requestHref, targetHref, err.code || err, errReference);
|
|
@@ -21,10 +20,9 @@ const loggerPlugin = (proxyServer, options) => {
|
|
|
21
20
|
* ```
|
|
22
21
|
*/
|
|
23
22
|
proxyServer.on('proxyRes', (proxyRes, req, res) => {
|
|
24
|
-
var _a;
|
|
25
23
|
// BrowserSync uses req.originalUrl
|
|
26
24
|
// Next.js doesn't have req.baseUrl
|
|
27
|
-
const originalUrl =
|
|
25
|
+
const originalUrl = req.originalUrl ?? `${req.baseUrl || ''}${req.url}`;
|
|
28
26
|
const exchange = `[HPM] ${req.method} ${originalUrl} -> ${proxyRes.req.protocol}//${proxyRes.req.host}${proxyRes.req.path} [${proxyRes.statusCode}]`;
|
|
29
27
|
logger.info(exchange);
|
|
30
28
|
});
|
package/dist/types.d.ts
CHANGED
|
@@ -5,15 +5,16 @@
|
|
|
5
5
|
/// <reference types="node" />
|
|
6
6
|
/// <reference types="node" />
|
|
7
7
|
/// <reference types="node" />
|
|
8
|
+
/// <reference types="node" />
|
|
8
9
|
import type * as http from 'http';
|
|
9
10
|
import type * as httpProxy from 'http-proxy';
|
|
10
11
|
import type * as net from 'net';
|
|
11
|
-
export
|
|
12
|
+
export type NextFunction<T = (err?: any) => void> = T;
|
|
12
13
|
export interface RequestHandler<TReq = http.IncomingMessage, TRes = http.ServerResponse, TNext = NextFunction> {
|
|
13
14
|
(req: TReq, res: TRes, next?: TNext): void | Promise<void>;
|
|
14
|
-
upgrade
|
|
15
|
+
upgrade: (req: http.IncomingMessage, socket: net.Socket, head: Buffer) => void;
|
|
15
16
|
}
|
|
16
|
-
export
|
|
17
|
+
export type Filter<TReq = http.IncomingMessage> = string | string[] | ((pathname: string, req: TReq) => boolean);
|
|
17
18
|
export interface Plugin<TReq = http.IncomingMessage, TRes = http.ServerResponse> {
|
|
18
19
|
(proxyServer: httpProxy<TReq, TRes>, options: Options<TReq, TRes>): void;
|
|
19
20
|
}
|
|
@@ -28,7 +29,7 @@ export interface OnProxyEvent<TReq = http.IncomingMessage, TRes = http.ServerRes
|
|
|
28
29
|
end?: httpProxy.EndCallback<TReq, TRes>;
|
|
29
30
|
econnreset?: httpProxy.EconnresetCallback<Error, TReq, TRes>;
|
|
30
31
|
}
|
|
31
|
-
export
|
|
32
|
+
export type Logger = Pick<Console, 'info' | 'warn' | 'error'>;
|
|
32
33
|
export interface Options<TReq = http.IncomingMessage, TRes = http.ServerResponse> extends httpProxy.ServerOptions {
|
|
33
34
|
/**
|
|
34
35
|
* Narrow down requests to proxy or not.
|
|
@@ -52,7 +53,7 @@ export interface Options<TReq = http.IncomingMessage, TRes = http.ServerResponse
|
|
|
52
53
|
*/
|
|
53
54
|
pathRewrite?: {
|
|
54
55
|
[regexp: string]: string;
|
|
55
|
-
} | ((path: string, req: TReq) => string) | ((path: string, req: TReq) => Promise<string>);
|
|
56
|
+
} | ((path: string, req: TReq) => string | undefined) | ((path: string, req: TReq) => Promise<string>);
|
|
56
57
|
/**
|
|
57
58
|
* Access the internal http-proxy server instance to customize behavior
|
|
58
59
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "http-proxy-middleware",
|
|
3
|
-
"version": "3.0.0
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "The one-liner node.js proxy middleware for connect, express, next.js and more",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"build": "tsc --build",
|
|
19
19
|
"test": "jest",
|
|
20
20
|
"coverage": "jest --coverage",
|
|
21
|
-
"prepare": "husky
|
|
21
|
+
"prepare": "husky",
|
|
22
22
|
"prepack": "yarn clean && yarn test && yarn build",
|
|
23
23
|
"spellcheck": "npx --yes cspell --show-context --show-suggestions '**/*.*'"
|
|
24
24
|
},
|
|
@@ -51,36 +51,36 @@
|
|
|
51
51
|
},
|
|
52
52
|
"homepage": "https://github.com/chimurai/http-proxy-middleware#readme",
|
|
53
53
|
"devDependencies": {
|
|
54
|
-
"@commitlint/cli": "17.
|
|
55
|
-
"@commitlint/config-conventional": "17.
|
|
56
|
-
"@types/debug": "4.1.
|
|
57
|
-
"@types/express": "4.17.
|
|
58
|
-
"@types/is-glob": "4.0.
|
|
59
|
-
"@types/jest": "29.
|
|
60
|
-
"@types/micromatch": "4.0.
|
|
61
|
-
"@types/node": "
|
|
54
|
+
"@commitlint/cli": "17.7.1",
|
|
55
|
+
"@commitlint/config-conventional": "17.7.0",
|
|
56
|
+
"@types/debug": "4.1.12",
|
|
57
|
+
"@types/express": "4.17.21",
|
|
58
|
+
"@types/is-glob": "4.0.4",
|
|
59
|
+
"@types/jest": "29.5.12",
|
|
60
|
+
"@types/micromatch": "4.0.6",
|
|
61
|
+
"@types/node": "20.11.30",
|
|
62
62
|
"@types/supertest": "2.0.12",
|
|
63
|
-
"@types/ws": "8.5.
|
|
64
|
-
"@typescript-eslint/eslint-plugin": "
|
|
65
|
-
"@typescript-eslint/parser": "
|
|
63
|
+
"@types/ws": "8.5.10",
|
|
64
|
+
"@typescript-eslint/eslint-plugin": "7.4.0",
|
|
65
|
+
"@typescript-eslint/parser": "7.4.0",
|
|
66
66
|
"body-parser": "1.20.2",
|
|
67
|
-
"browser-sync": "
|
|
67
|
+
"browser-sync": "3.0.2",
|
|
68
68
|
"connect": "3.7.0",
|
|
69
|
-
"eslint": "8.
|
|
70
|
-
"eslint-config-prettier": "
|
|
71
|
-
"eslint-plugin-prettier": "
|
|
72
|
-
"express": "4.
|
|
69
|
+
"eslint": "8.57.0",
|
|
70
|
+
"eslint-config-prettier": "9.1.0",
|
|
71
|
+
"eslint-plugin-prettier": "5.1.3",
|
|
72
|
+
"express": "4.19.2",
|
|
73
73
|
"get-port": "5.1.1",
|
|
74
|
-
"husky": "
|
|
75
|
-
"jest": "29.
|
|
76
|
-
"lint-staged": "
|
|
77
|
-
"mockttp": "3.
|
|
74
|
+
"husky": "9.0.11",
|
|
75
|
+
"jest": "29.7.0",
|
|
76
|
+
"lint-staged": "15.2.2",
|
|
77
|
+
"mockttp": "3.10.1",
|
|
78
78
|
"open": "8.4.2",
|
|
79
|
-
"prettier": "2.
|
|
80
|
-
"supertest": "6.3.
|
|
81
|
-
"ts-jest": "29.
|
|
82
|
-
"typescript": "4.
|
|
83
|
-
"ws": "8.
|
|
79
|
+
"prettier": "3.2.5",
|
|
80
|
+
"supertest": "6.3.4",
|
|
81
|
+
"ts-jest": "29.1.2",
|
|
82
|
+
"typescript": "5.4.3",
|
|
83
|
+
"ws": "8.16.0"
|
|
84
84
|
},
|
|
85
85
|
"dependencies": {
|
|
86
86
|
"@types/http-proxy": "^1.17.10",
|
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
"micromatch": "^4.0.5"
|
|
92
92
|
},
|
|
93
93
|
"engines": {
|
|
94
|
-
"node": ">=
|
|
94
|
+
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
|
95
95
|
},
|
|
96
96
|
"commitlint": {
|
|
97
97
|
"extends": [
|