From 5be8454f74077dcb6e7a6f12089b03f58fe38c72 Mon Sep 17 00:00:00 2001 From: Seth Carter Date: Thu, 13 Feb 2020 10:50:06 -0600 Subject: [PATCH 1/8] Allow the path rewriter function to be async. --- src/http-proxy-middleware.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/http-proxy-middleware.ts b/src/http-proxy-middleware.ts index ca113327..c6fe7598 100644 --- a/src/http-proxy-middleware.ts +++ b/src/http-proxy-middleware.ts @@ -116,7 +116,7 @@ export class HttpProxyMiddleware { // 1. option.router // 2. option.pathRewrite await this.applyRouter(req, newProxyOptions); - this.applyPathRewrite(req, this.pathRewriter); + await this.applyPathRewrite(req, this.pathRewriter); // debug logging for both http(s) and websockets if (this.proxyOptions.logLevel === 'debug') { @@ -157,9 +157,9 @@ export class HttpProxyMiddleware { }; // rewrite path - private applyPathRewrite = (req: IRequest, pathRewriter) => { + private applyPathRewrite = async (req: IRequest, pathRewriter) => { if (pathRewriter) { - const path = pathRewriter(req.url, req); + const path = await pathRewriter(req.url, req); if (typeof path === 'string') { req.url = path; From c3c29ca4095a50d02df34add34d2c4b94553942d Mon Sep 17 00:00:00 2001 From: Seth Carter Date: Thu, 13 Feb 2020 20:10:12 -0600 Subject: [PATCH 2/8] Comply with testing and documentation requirements --- README.md | 8 ++++++ test/types.spec.ts | 5 ++++ test/unit/path-rewriter.spec.ts | 47 ++++++++++++++++++++++++++++++--- 3 files changed, 57 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9bfd3a27..8b7841de 100644 --- a/README.md +++ b/README.md @@ -199,6 +199,14 @@ Providing an alternative way to decide which requests should be proxied; In case // custom rewriting pathRewrite: function (path, req) { return path.replace('/api', '/base/api') } + + // custom rewriting, returning Promise + pathRewrite: async function (path, req) { + var should_add_something = await httpRequestToDecideSomething(path); + if (should_add_something) path += "something"; + return path; + } + ``` - **option.router**: object/function, re-target `option.target` for specific requests. diff --git a/test/types.spec.ts b/test/types.spec.ts index 64a0fdba..671ae47e 100644 --- a/test/types.spec.ts +++ b/test/types.spec.ts @@ -58,6 +58,11 @@ describe('http-proxy-middleware TypeScript Types', () => { options = { pathRewrite: (path, req) => '/path' }; expect(options).toBeDefined(); }); + + it('should have pathRewrite Type with async function', () => { + options = { pathRewrite: async (path, req) => '/path' }; + expect(options).toBeDefined(); + }); }); describe('router', () => { diff --git a/test/unit/path-rewriter.spec.ts b/test/unit/path-rewriter.spec.ts index f42d7a88..d2005c5c 100644 --- a/test/unit/path-rewriter.spec.ts +++ b/test/unit/path-rewriter.spec.ts @@ -84,7 +84,7 @@ describe('Path rewriting', () => { return path; }; - expect(rewriter(rewriteFn)).toBe('/123/456'); + expect(rewriter(rewriteFn)).resolves.toBe('/123/456'); }); it('should return alternative path', () => { @@ -92,7 +92,7 @@ describe('Path rewriting', () => { return '/foo/bar'; }; - expect(rewriter(rewriteFn)).toBe('/foo/bar'); + expect(rewriter(rewriteFn)).resolves.toBe('/foo/bar'); }); it('should return replaced path', () => { @@ -100,7 +100,43 @@ describe('Path rewriting', () => { return path.replace('/456', '/789'); }; - expect(rewriter(rewriteFn)).toBe('/123/789'); + expect(rewriter(rewriteFn)).resolves.toBe('/123/789'); + }); + + // Same tests as the above three, but async + + it('is async and should return unmodified path', () => { + const rewriteFn = async path => { + var promise = new Promise(function (resolve, reject) { + resolve(path); + }); + return await promise; + }; + + expect(rewriter(rewriteFn)).resolves.toBe('/123/456'); + }); + + it('is async and should return alternative path', () => { + const rewriteFn = async path => { + var promise = new Promise(function (resolve, reject) { + resolve('/foo/bar'); + }) + return await promise; + }; + + expect(rewriter(rewriteFn)).resolves.toBe('/foo/bar'); + }); + + it('is async and should return replaced path', () => { + const rewriteFn = async path => { + var promise = new Promise(function (resolve, reject) + { + resolve(path.replace('/456','/789')); + }) + return await promise; + }; + + expect(rewriter(rewriteFn)).resolves.toBe('/123/789'); }); }); @@ -136,5 +172,10 @@ describe('Path rewriting', () => { // tslint:disable-next-line: no-empty expect(badFn(() => {})).not.toThrowError(Error); }); + + it('should not throw when async function config is provided', () => { + // tslint:disable-next-line: no-empty + expect(badFn(async () => {})).not.toThrowError(Error); + }) }); }); From db4ae23b60c6318337970f88ba3a581e448df43f Mon Sep 17 00:00:00 2001 From: Seth Carter Date: Thu, 13 Feb 2020 20:28:21 -0600 Subject: [PATCH 3/8] Comply with linting rules. --- test/unit/path-rewriter.spec.ts | 15 +++++++-------- yarn.lock | 2 +- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/test/unit/path-rewriter.spec.ts b/test/unit/path-rewriter.spec.ts index d2005c5c..61be01db 100644 --- a/test/unit/path-rewriter.spec.ts +++ b/test/unit/path-rewriter.spec.ts @@ -107,7 +107,7 @@ describe('Path rewriting', () => { it('is async and should return unmodified path', () => { const rewriteFn = async path => { - var promise = new Promise(function (resolve, reject) { + var promise = new Promise(function(resolve, reject) { resolve(path); }); return await promise; @@ -118,9 +118,9 @@ describe('Path rewriting', () => { it('is async and should return alternative path', () => { const rewriteFn = async path => { - var promise = new Promise(function (resolve, reject) { + var promise = new Promise(function(resolve, reject) { resolve('/foo/bar'); - }) + }); return await promise; }; @@ -129,10 +129,9 @@ describe('Path rewriting', () => { it('is async and should return replaced path', () => { const rewriteFn = async path => { - var promise = new Promise(function (resolve, reject) - { - resolve(path.replace('/456','/789')); - }) + var promise = new Promise(function(resolve, reject) { + resolve(path.replace('/456', '/789')); + }); return await promise; }; @@ -176,6 +175,6 @@ describe('Path rewriting', () => { it('should not throw when async function config is provided', () => { // tslint:disable-next-line: no-empty expect(badFn(async () => {})).not.toThrowError(Error); - }) + }); }); }); diff --git a/yarn.lock b/yarn.lock index f8575bb9..6722e3d4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4557,7 +4557,7 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= -prettier@^1.19.1: +prettier@1.19.1: version "1.19.1" resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== From 8bfb8e31a82eb00deb7009729c13bd3007e27a38 Mon Sep 17 00:00:00 2001 From: Seth Carter Date: Thu, 13 Feb 2020 20:33:49 -0600 Subject: [PATCH 4/8] Additional linting compliance. --- test/unit/path-rewriter.spec.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/unit/path-rewriter.spec.ts b/test/unit/path-rewriter.spec.ts index 61be01db..6fa9698a 100644 --- a/test/unit/path-rewriter.spec.ts +++ b/test/unit/path-rewriter.spec.ts @@ -107,7 +107,7 @@ describe('Path rewriting', () => { it('is async and should return unmodified path', () => { const rewriteFn = async path => { - var promise = new Promise(function(resolve, reject) { + const promise = new Promise((resolve, reject) => { resolve(path); }); return await promise; @@ -118,7 +118,7 @@ describe('Path rewriting', () => { it('is async and should return alternative path', () => { const rewriteFn = async path => { - var promise = new Promise(function(resolve, reject) { + const promise = new Promise((resolve, reject) => { resolve('/foo/bar'); }); return await promise; @@ -129,7 +129,7 @@ describe('Path rewriting', () => { it('is async and should return replaced path', () => { const rewriteFn = async path => { - var promise = new Promise(function(resolve, reject) { + const promise = new Promise((resolve, reject) => { resolve(path.replace('/456', '/789')); }); return await promise; From 3afde0375eb9e94ec930d4d317fff1187dc49a39 Mon Sep 17 00:00:00 2001 From: Seth Carter Date: Thu, 13 Feb 2020 20:37:27 -0600 Subject: [PATCH 5/8] Additional linting compliance. (2) --- test/unit/path-rewriter.spec.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/test/unit/path-rewriter.spec.ts b/test/unit/path-rewriter.spec.ts index 6fa9698a..c50cb360 100644 --- a/test/unit/path-rewriter.spec.ts +++ b/test/unit/path-rewriter.spec.ts @@ -110,7 +110,8 @@ describe('Path rewriting', () => { const promise = new Promise((resolve, reject) => { resolve(path); }); - return await promise; + const changed = await promise; + return changed; }; expect(rewriter(rewriteFn)).resolves.toBe('/123/456'); @@ -121,7 +122,8 @@ describe('Path rewriting', () => { const promise = new Promise((resolve, reject) => { resolve('/foo/bar'); }); - return await promise; + const changed = await promise; + return changed; }; expect(rewriter(rewriteFn)).resolves.toBe('/foo/bar'); @@ -132,7 +134,8 @@ describe('Path rewriting', () => { const promise = new Promise((resolve, reject) => { resolve(path.replace('/456', '/789')); }); - return await promise; + const changed = await promise; + return changed; }; expect(rewriter(rewriteFn)).resolves.toBe('/123/789'); From ba27b53e8c34a43529729019dca6027c3aeae581 Mon Sep 17 00:00:00 2001 From: Seth Carter Date: Thu, 13 Feb 2020 20:46:15 -0600 Subject: [PATCH 6/8] Only use "resolves" for functions returning a Promise. --- test/unit/path-rewriter.spec.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/unit/path-rewriter.spec.ts b/test/unit/path-rewriter.spec.ts index c50cb360..b848782d 100644 --- a/test/unit/path-rewriter.spec.ts +++ b/test/unit/path-rewriter.spec.ts @@ -84,7 +84,7 @@ describe('Path rewriting', () => { return path; }; - expect(rewriter(rewriteFn)).resolves.toBe('/123/456'); + expect(rewriter(rewriteFn)).toBe('/123/456'); }); it('should return alternative path', () => { @@ -92,7 +92,7 @@ describe('Path rewriting', () => { return '/foo/bar'; }; - expect(rewriter(rewriteFn)).resolves.toBe('/foo/bar'); + expect(rewriter(rewriteFn)).toBe('/foo/bar'); }); it('should return replaced path', () => { @@ -100,7 +100,7 @@ describe('Path rewriting', () => { return path.replace('/456', '/789'); }; - expect(rewriter(rewriteFn)).resolves.toBe('/123/789'); + expect(rewriter(rewriteFn)).toBe('/123/789'); }); // Same tests as the above three, but async From 5ba502b516cc6586dbe465d7880c2228d1546d32 Mon Sep 17 00:00:00 2001 From: Seth Carter Date: Thu, 13 Feb 2020 20:54:04 -0600 Subject: [PATCH 7/8] Update types.ts with Promise as acceptable return from pathRewrite function. --- src/types.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/types.ts b/src/types.ts index 7aef997e..06ff4f1d 100644 --- a/src/types.ts +++ b/src/types.ts @@ -18,7 +18,8 @@ export type Filter = export interface Options extends httpProxy.ServerOptions { pathRewrite?: | { [regexp: string]: string } - | ((path: string, req: IRequest) => string); + | ((path: string, req: IRequest) => string) + | ((path: string, req: IRequest) => Promise); router?: | { [hostOrPath: string]: string } | ((req: IRequest) => string) From 478d9bb4155b00a4f2d1ff9d35e1bce93eed7baf Mon Sep 17 00:00:00 2001 From: Seth Carter Date: Fri, 14 Feb 2020 11:32:53 -0600 Subject: [PATCH 8/8] Undo change to yarn.lock --- yarn.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn.lock b/yarn.lock index 6722e3d4..f8575bb9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4557,7 +4557,7 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= -prettier@1.19.1: +prettier@^1.19.1: version "1.19.1" resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==