From 3424222597346fbedc1b832e095eecdc53edc3bd Mon Sep 17 00:00:00 2001 From: Prathamesh Gawas Date: Thu, 13 Oct 2022 16:11:20 +0530 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Fixed=20redirects=20with=20speci?= =?UTF-8?q?al=20characters=20(#15533)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit closes: https://github.com/TryGhost/Ghost/issues/15267 - This was because the URLs were not being encoded and matched correctly - it is solved by encoding the URL before adding to the router. --- .../lib/DynamicRedirectManager.js | 7 +++++++ .../test/DynamicRedirectManager.test.js | 20 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/ghost/express-dynamic-redirects/lib/DynamicRedirectManager.js b/ghost/express-dynamic-redirects/lib/DynamicRedirectManager.js index b184f16a34..9ec8d734e9 100644 --- a/ghost/express-dynamic-redirects/lib/DynamicRedirectManager.js +++ b/ghost/express-dynamic-redirects/lib/DynamicRedirectManager.js @@ -94,6 +94,13 @@ class DynamicRedirectManager { */ addRedirect(from, to, options = {}) { try { + // encode "from" only if it's not a regex + try { + new RegExp(from); + } catch (e) { + from = encodeURI(from); + } + const fromRegex = this.buildRegex(from); const redirectId = from; diff --git a/ghost/express-dynamic-redirects/test/DynamicRedirectManager.test.js b/ghost/express-dynamic-redirects/test/DynamicRedirectManager.test.js index a05bb61bca..1ad0ea06a8 100644 --- a/ghost/express-dynamic-redirects/test/DynamicRedirectManager.test.js +++ b/ghost/express-dynamic-redirects/test/DynamicRedirectManager.test.js @@ -363,6 +363,26 @@ describe('DynamicRedirectManager', function () { should.equal(location, 'https://ghost.org/docs'); }); }); + + describe('Url with special character redirect', function () { + it('redirects urls with special characters', function () { + const from = '/joloonii-surgaltuud/а-анлал/'; + const to = '/joloonii-angilal/а-ангилал'; + + manager.addRedirect(from, to); + + req.url = from; + + manager.handleRequest(req, res, function next() { + should.fail(true, false, 'next should NOT have been called'); + }); + + // NOTE: max-age is "0" because it's not a permanent redirect + should.equal(headers['Cache-Control'], 'public, max-age=0'); + should.equal(status, 302); + should.equal(location, '/joloonii-angilal/а-ангилал'); + }); + }); }); describe('with subdirectory configuration', function () {