Skip to content

Commit 7c2c31f

Browse files
authored
feat: async pathRewrite (#397)
Allow the path rewriter function to be async
1 parent 483911a commit 7c2c31f

File tree

5 files changed

+61
-4
lines changed

5 files changed

+61
-4
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,14 @@ Providing an alternative way to decide which requests should be proxied; In case
199199

200200
// custom rewriting
201201
pathRewrite: function (path, req) { return path.replace('/api', '/base/api') }
202+
203+
// custom rewriting, returning Promise
204+
pathRewrite: async function (path, req) {
205+
var should_add_something = await httpRequestToDecideSomething(path);
206+
if (should_add_something) path += "something";
207+
return path;
208+
}
209+
202210
```
203211

204212
- **option.router**: object/function, re-target `option.target` for specific requests.

src/http-proxy-middleware.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ export class HttpProxyMiddleware {
116116
// 1. option.router
117117
// 2. option.pathRewrite
118118
await this.applyRouter(req, newProxyOptions);
119-
this.applyPathRewrite(req, this.pathRewriter);
119+
await this.applyPathRewrite(req, this.pathRewriter);
120120

121121
// debug logging for both http(s) and websockets
122122
if (this.proxyOptions.logLevel === 'debug') {
@@ -157,9 +157,9 @@ export class HttpProxyMiddleware {
157157
};
158158

159159
// rewrite path
160-
private applyPathRewrite = (req: IRequest, pathRewriter) => {
160+
private applyPathRewrite = async (req: IRequest, pathRewriter) => {
161161
if (pathRewriter) {
162-
const path = pathRewriter(req.url, req);
162+
const path = await pathRewriter(req.url, req);
163163

164164
if (typeof path === 'string') {
165165
req.url = path;

src/types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ export type Filter =
1818
export interface Options extends httpProxy.ServerOptions {
1919
pathRewrite?:
2020
| { [regexp: string]: string }
21-
| ((path: string, req: IRequest) => string);
21+
| ((path: string, req: IRequest) => string)
22+
| ((path: string, req: IRequest) => Promise<string>);
2223
router?:
2324
| { [hostOrPath: string]: string }
2425
| ((req: IRequest) => string)

test/types.spec.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ describe('http-proxy-middleware TypeScript Types', () => {
5858
options = { pathRewrite: (path, req) => '/path' };
5959
expect(options).toBeDefined();
6060
});
61+
62+
it('should have pathRewrite Type with async function', () => {
63+
options = { pathRewrite: async (path, req) => '/path' };
64+
expect(options).toBeDefined();
65+
});
6166
});
6267

6368
describe('router', () => {

test/unit/path-rewriter.spec.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,44 @@ describe('Path rewriting', () => {
102102

103103
expect(rewriter(rewriteFn)).toBe('/123/789');
104104
});
105+
106+
// Same tests as the above three, but async
107+
108+
it('is async and should return unmodified path', () => {
109+
const rewriteFn = async path => {
110+
const promise = new Promise((resolve, reject) => {
111+
resolve(path);
112+
});
113+
const changed = await promise;
114+
return changed;
115+
};
116+
117+
expect(rewriter(rewriteFn)).resolves.toBe('/123/456');
118+
});
119+
120+
it('is async and should return alternative path', () => {
121+
const rewriteFn = async path => {
122+
const promise = new Promise((resolve, reject) => {
123+
resolve('/foo/bar');
124+
});
125+
const changed = await promise;
126+
return changed;
127+
};
128+
129+
expect(rewriter(rewriteFn)).resolves.toBe('/foo/bar');
130+
});
131+
132+
it('is async and should return replaced path', () => {
133+
const rewriteFn = async path => {
134+
const promise = new Promise((resolve, reject) => {
135+
resolve(path.replace('/456', '/789'));
136+
});
137+
const changed = await promise;
138+
return changed;
139+
};
140+
141+
expect(rewriter(rewriteFn)).resolves.toBe('/123/789');
142+
});
105143
});
106144

107145
describe('Invalid configuration', () => {
@@ -136,5 +174,10 @@ describe('Path rewriting', () => {
136174
// tslint:disable-next-line: no-empty
137175
expect(badFn(() => {})).not.toThrowError(Error);
138176
});
177+
178+
it('should not throw when async function config is provided', () => {
179+
// tslint:disable-next-line: no-empty
180+
expect(badFn(async () => {})).not.toThrowError(Error);
181+
});
139182
});
140183
});

0 commit comments

Comments
 (0)