0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-10 23:36:14 -05:00

🐛 Fixed custom redirects for subdirectory setups

no-issue

This issue only occurs when using custom redirects with a subdirectory
setup, and the path to be redirected from is expressed as a regex, and
the url that is being redirected to is not an external url.

The issue has a few components:

- Redirect paths as a regex generally use the ^ to ensure that they
  match the beginning of the path.

- The path that the regex is matched against conditionally excludes the
  subdirectory, specifically, the subdirectory is excluded for external
  urls

These combined means you end up with a regex like /^\/custom-redirect/
and a path like /subdir/custom-redirect, these will not match/replace
correctly, and you'll end in an infinite redirect loop.

The fix here is to *always* remove the subdirectory when testing regex's
and then conditionally adding it back *only* for the redirect, and only
if it is an internal redirect
This commit is contained in:
Fabien O'Carroll 2020-06-15 13:35:48 +02:00
parent 5f00619d1a
commit c5b8dab523
3 changed files with 24 additions and 9 deletions

View file

@ -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}`
});

View file

@ -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 () {

View file

@ -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"