diff --git a/core/server/web/shared/middlewares/custom-redirects.js b/core/server/web/shared/middlewares/custom-redirects.js index 50d2ca133b..2e594941e2 100644 --- a/core/server/web/shared/middlewares/custom-redirects.js +++ b/core/server/web/shared/middlewares/custom-redirects.js @@ -54,17 +54,19 @@ _private.registerRoutes = () => { customRedirectsRouter.get(new RegExp(redirect.from, options), function (req, res) { const maxAge = redirect.permanent ? config.get('caching:customRedirects:maxAge') : 0; const toURL = url.parse(redirect.to); - const currentURL = url.parse(req.originalUrl); + const currentURL = url.parse(req.url); - // if the URL points to an external website, remove Ghost's base path - /** @see https://github.com/TryGhost/Ghost/issues/10776 */ - const currentPath = (toURL.hostname) - ? currentURL.pathname.replace(urlUtils.getSubdir(), '') - : currentURL.pathname; - - toURL.pathname = currentPath.replace(new RegExp(redirect.from, options), toURL.pathname); + toURL.pathname = currentURL.pathname.replace(new RegExp(redirect.from, options), toURL.pathname); toURL.search = currentURL.search; + /** + * Only if the URL is internal should we prepend the Ghost subdirectory + * @see https://github.com/TryGhost/Ghost/issues/10776 + */ + if (!toURL.hostname) { + toURL.pathname = urlUtils.urlJoin(urlUtils.getSubdir(), toURL.pathname); + } + res.set({ 'Cache-Control': `public, max-age=${maxAge}` }); diff --git a/test/regression/site/frontend_spec.js b/test/regression/site/frontend_spec.js index 568a1b23f4..f5fdaa4b13 100644 --- a/test/regression/site/frontend_spec.js +++ b/test/regression/site/frontend_spec.js @@ -789,7 +789,7 @@ describe('Frontend Routing', function () { configUtils.set('url', 'http://localhost:2370/blog/'); urlUtils.stubUrlUtilsFromConfig(); - return ghost({forceStart: true}) + return ghost({forceStart: true, subdir: true}) .then(function (_ghostServer) { ghostServer = _ghostServer; request = supertest.agent(config.get('server:host') + ':' + config.get('server:port')); @@ -811,6 +811,15 @@ describe('Frontend Routing', function () { doEnd(done)(err, res); }); }); + it('should work with regex "from" redirects', function (done) { + request.get('/blog/capture1/whatever') + .expect(302) + .expect('Cache-Control', testUtils.cacheRules.public) + .end(function (err, res) { + res.headers.location.should.eql('/blog/whatever'); + doEnd(done)(err, res); + }); + }); }); describe('external url redirect', function () { diff --git a/test/utils/fixtures/data/redirects.json b/test/utils/fixtures/data/redirects.json index 17787633a3..85f0b3c5ea 100644 --- a/test/utils/fixtures/data/redirects.json +++ b/test/utils/fixtures/data/redirects.json @@ -24,6 +24,10 @@ "from": "^/resources\\/download(\\/?)$", "to": "/shubal-stearns" }, + { + "from": "^\/(?:capture1|capture2)\/([A-Za-z0-9\\-]+)", + "to": "/$1" + }, { "from": "^\\/[0-9]{4}\\/[0-9]{2}\\/([a-z0-9\\-]+)(\\.html)?(\\/)?$", "to": "/$1"