mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-28 14:03:48 +03:00
🐛 Fixed regex match replacement when dealing with external URLs (#11781)
refs #10898 - Execute string replacement on external paths - Take non-top-level base URLs into consideration (to avoid #10776 dups) - Added tests for all of the above cases
This commit is contained in:
parent
e6dbf4ce47
commit
4fcc31015b
@ -4,6 +4,7 @@ const url = require('url');
|
||||
const path = require('path');
|
||||
const debug = require('ghost-ignition').debug('web:shared:mw:custom-redirects');
|
||||
const config = require('../../../config');
|
||||
const urlUtils = require('../../../lib/url-utils');
|
||||
const errors = require('@tryghost/errors');
|
||||
const {logging, i18n} = require('../../../lib/common');
|
||||
const redirectsService = require('../../../../frontend/services/redirects');
|
||||
@ -51,13 +52,17 @@ _private.registerRoutes = () => {
|
||||
debug('register', redirect.from);
|
||||
customRedirectsRouter.get(new RegExp(redirect.from, options), function (req, res) {
|
||||
const maxAge = redirect.permanent ? config.get('caching:customRedirects:maxAge') : 0;
|
||||
const fromURL = url.parse(req.originalUrl);
|
||||
const toURL = url.parse(redirect.to);
|
||||
const currentURL = url.parse(req.originalUrl);
|
||||
|
||||
toURL.pathname = (toURL.hostname)
|
||||
? toURL.pathname
|
||||
: fromURL.pathname.replace(new RegExp(redirect.from, options), toURL.pathname);
|
||||
toURL.search = fromURL.search;
|
||||
// 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.search = currentURL.search;
|
||||
|
||||
res.set({
|
||||
'Cache-Control': `public, max-age=${maxAge}`
|
||||
|
@ -60,10 +60,10 @@ describe('Redirects API', function () {
|
||||
.then((res) => {
|
||||
res.headers['content-disposition'].should.eql('Attachment; filename="redirects.json"');
|
||||
res.headers['content-type'].should.eql('application/json; charset=utf-8');
|
||||
res.headers['content-length'].should.eql('698');
|
||||
res.headers['content-length'].should.eql('756');
|
||||
|
||||
res.body.should.not.be.empty();
|
||||
res.body.length.should.equal(12);
|
||||
res.body.length.should.equal(13);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -60,10 +60,10 @@ describe('Redirects API', function () {
|
||||
.then((res) => {
|
||||
res.headers['content-disposition'].should.eql('Attachment; filename="redirects.json"');
|
||||
res.headers['content-type'].should.eql('application/json; charset=utf-8');
|
||||
res.headers['content-length'].should.eql('698');
|
||||
res.headers['content-length'].should.eql('756');
|
||||
|
||||
res.body.should.not.be.empty();
|
||||
res.body.length.should.equal(12);
|
||||
res.body.length.should.equal(13);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -60,10 +60,10 @@ describe('Redirects API', function () {
|
||||
.then((res) => {
|
||||
res.headers['content-disposition'].should.eql('Attachment; filename="redirects.json"');
|
||||
res.headers['content-type'].should.eql('application/json; charset=utf-8');
|
||||
res.headers['content-length'].should.eql('698');
|
||||
res.headers['content-length'].should.eql('756');
|
||||
|
||||
res.body.should.not.be.empty();
|
||||
res.body.length.should.equal(12);
|
||||
res.body.length.should.equal(13);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -769,6 +769,60 @@ describe('Frontend Routing', function () {
|
||||
doEnd(done)(err, res);
|
||||
});
|
||||
});
|
||||
|
||||
it('with capturing group', function (done) {
|
||||
request.get('/external-url/docs')
|
||||
.expect(302)
|
||||
.expect('Cache-Control', testUtils.cacheRules.public)
|
||||
.end(function (err, res) {
|
||||
res.headers.location.should.eql('https://ghost.org/docs');
|
||||
doEnd(done)(err, res);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Subdirectory redirects (use redirects.json from test/utils/fixtures/data)', function () {
|
||||
var ghostServer;
|
||||
|
||||
before(function () {
|
||||
configUtils.set('url', 'http://localhost:2370/blog/');
|
||||
urlUtils.stubUrlUtilsFromConfig();
|
||||
|
||||
return ghost({forceStart: true})
|
||||
.then(function (_ghostServer) {
|
||||
ghostServer = _ghostServer;
|
||||
request = supertest.agent(config.get('server:host') + ':' + config.get('server:port'));
|
||||
});
|
||||
});
|
||||
|
||||
after(function () {
|
||||
configUtils.restore();
|
||||
urlUtils.restore();
|
||||
});
|
||||
|
||||
describe('internal url redirect', function () {
|
||||
it('shold include the subdirectory', function (done) {
|
||||
request.get('/blog/my-old-blog-post/')
|
||||
.expect(302)
|
||||
.expect('Cache-Control', testUtils.cacheRules.public)
|
||||
.end(function (err, res) {
|
||||
res.headers.location.should.eql('/blog/revamped-url/');
|
||||
doEnd(done)(err, res);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('external url redirect', function () {
|
||||
it('shold not include the subdirectory', function (done) {
|
||||
request.get('/blog/external-url/docs')
|
||||
.expect(302)
|
||||
.expect('Cache-Control', testUtils.cacheRules.public)
|
||||
.end(function (err, res) {
|
||||
res.headers.location.should.eql('https://ghost.org/docs');
|
||||
doEnd(done)(err, res);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -46,5 +46,9 @@
|
||||
{
|
||||
"from": "/external-url",
|
||||
"to": "https://ghost.org"
|
||||
},
|
||||
{
|
||||
"from": "/external-url/(.*)",
|
||||
"to": "https://ghost.org/$1"
|
||||
}
|
||||
]
|
||||
|
Loading…
Reference in New Issue
Block a user