From 364f5989fafefbb68ac75b10b25d61d629930f82 Mon Sep 17 00:00:00 2001 From: efr00 Date: Wed, 12 Apr 2023 15:08:05 +0200 Subject: [PATCH 1/3] feat: add disableInternalRewriteLocationHeader option --- README.md | 10 +++++++++- index.js | 3 ++- test/test.js | 31 +++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5d357b3..7998a7d 100644 --- a/README.md +++ b/README.md @@ -163,13 +163,21 @@ configuration passed to the route. Object with [reply options](https://github.com/fastify/fastify-reply-from#replyfromsource-opts) for `@fastify/reply-from`. +### `disableInternalRewriteLocationHeader` +By default, `@fastify/http-proxy` will rewrite the `location` header when a request redirects to a relative path. +In other words, the [prefix](https://github.com/fastify/fastify-http-proxy#prefix) will be added to the relative path. + +If you want to preserve the original path, this option will disable this internal operation. Default: `false`. + +Note that the [rewriteHeaders](https://github.com/fastify/fastify-reply-from#rewriteheadersheaders-request) option of [`@fastify/reply-from`](http://npm.im/fastify-reply-from) will retrieve headers modified (reminder: only `location` is updated among all headers) in parameter but with this option, the headers are unchanged. + ### `httpMethods` An array that contains the types of the methods. Default: `['DELETE', 'GET', 'HEAD', 'PATCH', 'POST', 'PUT', 'OPTIONS']`. ### `websocket` This module has _partial_ support for forwarding websockets by passing a -`websocket` boolean option. +`websocket` boolean option. A few things are missing: diff --git a/index.js b/index.js index 4ff9d18..b4f118f 100644 --- a/index.js +++ b/index.js @@ -234,6 +234,7 @@ async function fastifyHttpProxy (fastify, opts) { fromOpts.base = opts.upstream fromOpts.prefix = undefined + const disableInternalRewriteLocationHeader = opts.disableInternalRewriteLocationHeader || false const oldRewriteHeaders = (opts.replyOptions || {}).rewriteHeaders const replyOpts = Object.assign({}, opts.replyOptions, { rewriteHeaders @@ -249,7 +250,7 @@ async function fastifyHttpProxy (fastify, opts) { function rewriteHeaders (headers, req) { const location = headers.location - if (location && !isExternalUrl(location)) { + if (location && !isExternalUrl(location) && !disableInternalRewriteLocationHeader) { headers.location = location.replace(rewritePrefix, fastify.prefix) } if (oldRewriteHeaders) { diff --git a/test/test.js b/test/test.js index 6935d7d..28db751 100644 --- a/test/test.js +++ b/test/test.js @@ -29,6 +29,11 @@ async function run () { throw new Error('kaboom') }) + origin.post('/redirect-to-relative-url', async (request, reply) => { + reply.header('location', '/relative-url') + return { status: 'ok' } + }) + origin.get('/api2/a', async (request, reply) => { return 'this is /api2/a' }) @@ -567,6 +572,32 @@ async function run () { t.equal(location, '/api/something') }) + test('location headers is preserved when disableInternalRewriteLocationHeader option is defined', async t => { + const proxyServer = Fastify() + + proxyServer.register(proxy, { + upstream: `http://localhost:${origin.server.address().port}`, + prefix: '/my-prefix', + disableInternalRewriteLocationHeader: true + }) + + await proxyServer.listen({ port: 0 }) + + t.teardown(() => { + proxyServer.close() + }) + + const { + headers: { location } + } = await got( + `http://localhost:${proxyServer.server.address().port}/my-prefix/redirect-to-relative-url`, + { + method: 'POST' + } + ) + t.equal(location, '/relative-url') + }) + test('passes onResponse option to reply.from() calls', async t => { const proxyServer = Fastify() From 4a8a9e6565e2581558ea94a0c3052a28df8f2de9 Mon Sep 17 00:00:00 2001 From: efr00 Date: Wed, 12 Apr 2023 15:36:44 +0200 Subject: [PATCH 2/3] fix: revert an unnecessary line change in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7998a7d..977b76c 100644 --- a/README.md +++ b/README.md @@ -177,7 +177,7 @@ An array that contains the types of the methods. Default: `['DELETE', 'GET', 'HE ### `websocket` This module has _partial_ support for forwarding websockets by passing a -`websocket` boolean option. +`websocket` boolean option. A few things are missing: From 1066392a2164042126137022abcde13947054d4c Mon Sep 17 00:00:00 2001 From: efr00 Date: Mon, 17 Apr 2023 12:30:39 +0200 Subject: [PATCH 3/3] refactor: use the positive option instead of the negative option --- README.md | 4 ++-- index.js | 4 ++-- test/test.js | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 977b76c..cacf757 100644 --- a/README.md +++ b/README.md @@ -163,11 +163,11 @@ configuration passed to the route. Object with [reply options](https://github.com/fastify/fastify-reply-from#replyfromsource-opts) for `@fastify/reply-from`. -### `disableInternalRewriteLocationHeader` +### `internalRewriteLocationHeader` By default, `@fastify/http-proxy` will rewrite the `location` header when a request redirects to a relative path. In other words, the [prefix](https://github.com/fastify/fastify-http-proxy#prefix) will be added to the relative path. -If you want to preserve the original path, this option will disable this internal operation. Default: `false`. +If you want to preserve the original path, this option will disable this internal operation. Default: `true`. Note that the [rewriteHeaders](https://github.com/fastify/fastify-reply-from#rewriteheadersheaders-request) option of [`@fastify/reply-from`](http://npm.im/fastify-reply-from) will retrieve headers modified (reminder: only `location` is updated among all headers) in parameter but with this option, the headers are unchanged. diff --git a/index.js b/index.js index b4f118f..34aaffd 100644 --- a/index.js +++ b/index.js @@ -234,7 +234,7 @@ async function fastifyHttpProxy (fastify, opts) { fromOpts.base = opts.upstream fromOpts.prefix = undefined - const disableInternalRewriteLocationHeader = opts.disableInternalRewriteLocationHeader || false + const internalRewriteLocationHeader = opts.internalRewriteLocationHeader ?? true const oldRewriteHeaders = (opts.replyOptions || {}).rewriteHeaders const replyOpts = Object.assign({}, opts.replyOptions, { rewriteHeaders @@ -250,7 +250,7 @@ async function fastifyHttpProxy (fastify, opts) { function rewriteHeaders (headers, req) { const location = headers.location - if (location && !isExternalUrl(location) && !disableInternalRewriteLocationHeader) { + if (location && !isExternalUrl(location) && internalRewriteLocationHeader) { headers.location = location.replace(rewritePrefix, fastify.prefix) } if (oldRewriteHeaders) { diff --git a/test/test.js b/test/test.js index 28db751..5d56c39 100644 --- a/test/test.js +++ b/test/test.js @@ -572,13 +572,13 @@ async function run () { t.equal(location, '/api/something') }) - test('location headers is preserved when disableInternalRewriteLocationHeader option is defined', async t => { + test('location headers is preserved when internalRewriteLocationHeader option is false', async t => { const proxyServer = Fastify() proxyServer.register(proxy, { upstream: `http://localhost:${origin.server.address().port}`, prefix: '/my-prefix', - disableInternalRewriteLocationHeader: true + internalRewriteLocationHeader: false }) await proxyServer.listen({ port: 0 })