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:
parent
5f00619d1a
commit
c5b8dab523
3 changed files with 24 additions and 9 deletions
|
@ -54,17 +54,19 @@ _private.registerRoutes = () => {
|
||||||
customRedirectsRouter.get(new RegExp(redirect.from, options), function (req, res) {
|
customRedirectsRouter.get(new RegExp(redirect.from, options), function (req, res) {
|
||||||
const maxAge = redirect.permanent ? config.get('caching:customRedirects:maxAge') : 0;
|
const maxAge = redirect.permanent ? config.get('caching:customRedirects:maxAge') : 0;
|
||||||
const toURL = url.parse(redirect.to);
|
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
|
toURL.pathname = currentURL.pathname.replace(new RegExp(redirect.from, options), toURL.pathname);
|
||||||
/** @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.search = currentURL.search;
|
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({
|
res.set({
|
||||||
'Cache-Control': `public, max-age=${maxAge}`
|
'Cache-Control': `public, max-age=${maxAge}`
|
||||||
});
|
});
|
||||||
|
|
|
@ -789,7 +789,7 @@ describe('Frontend Routing', function () {
|
||||||
configUtils.set('url', 'http://localhost:2370/blog/');
|
configUtils.set('url', 'http://localhost:2370/blog/');
|
||||||
urlUtils.stubUrlUtilsFromConfig();
|
urlUtils.stubUrlUtilsFromConfig();
|
||||||
|
|
||||||
return ghost({forceStart: true})
|
return ghost({forceStart: true, subdir: true})
|
||||||
.then(function (_ghostServer) {
|
.then(function (_ghostServer) {
|
||||||
ghostServer = _ghostServer;
|
ghostServer = _ghostServer;
|
||||||
request = supertest.agent(config.get('server:host') + ':' + config.get('server:port'));
|
request = supertest.agent(config.get('server:host') + ':' + config.get('server:port'));
|
||||||
|
@ -811,6 +811,15 @@ describe('Frontend Routing', function () {
|
||||||
doEnd(done)(err, res);
|
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 () {
|
describe('external url redirect', function () {
|
||||||
|
|
|
@ -24,6 +24,10 @@
|
||||||
"from": "^/resources\\/download(\\/?)$",
|
"from": "^/resources\\/download(\\/?)$",
|
||||||
"to": "/shubal-stearns"
|
"to": "/shubal-stearns"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"from": "^\/(?:capture1|capture2)\/([A-Za-z0-9\\-]+)",
|
||||||
|
"to": "/$1"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"from": "^\\/[0-9]{4}\\/[0-9]{2}\\/([a-z0-9\\-]+)(\\.html)?(\\/)?$",
|
"from": "^\\/[0-9]{4}\\/[0-9]{2}\\/([a-z0-9\\-]+)(\\.html)?(\\/)?$",
|
||||||
"to": "/$1"
|
"to": "/$1"
|
||||||
|
|
Loading…
Add table
Reference in a new issue