0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-04-08 02:52:39 -05:00

🎨Added case insensitive support for redirects (#9755)

no issue

- e.g. "/^\\/case-insensitive/i
- Adds tests for case sensitive redirects
- Needs a doc update on release!
This commit is contained in:
Jesse Houwing 2018-09-24 18:57:05 +02:00 committed by Katharina Irrgang
parent bc4b637e30
commit e3234bce6c
4 changed files with 73 additions and 3 deletions

View file

@ -22,12 +22,23 @@ _private.registerRoutes = () => {
validation.validateRedirects(redirects);
redirects.forEach((redirect) => {
/**
* Detect case insensitive modifier when regex is enclosed by
* / ... /i
*/
let options = '';
if (redirect.from.match(/^\/.*\/i$/)) {
redirect.from = redirect.from.slice(1, -2);
options = 'i';
}
/**
* always delete trailing slashes, doesn't matter if regex or not
* Example:
* - you define /my-blog-post-1/ as from property
* - /my-blog-post-1 or /my-blog-post-1/ should work
*/
if (redirect.from.match(/\/$/)) {
redirect.from = redirect.from.slice(0, -1);
}
@ -37,7 +48,7 @@ _private.registerRoutes = () => {
}
debug('register', redirect.from);
customRedirectsRouter.get(new RegExp(redirect.from), function customRedirect(req, res) {
customRedirectsRouter.get(new RegExp(redirect.from, options), function (req, res) {
const maxAge = redirect.permanent ? config.get('caching:customRedirects:maxAge') : 0,
parsedUrl = url.parse(req.originalUrl);
@ -46,7 +57,7 @@ _private.registerRoutes = () => {
});
res.redirect(redirect.permanent ? 301 : 302, url.format({
pathname: parsedUrl.pathname.replace(new RegExp(redirect.from), redirect.to),
pathname: parsedUrl.pathname.replace(new RegExp(redirect.from, options), redirect.to),
search: parsedUrl.search
}));
});

View file

@ -73,7 +73,7 @@ describe('Redirects API', function () {
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('463');
res.headers['content-length'].should.eql('648');
done();
});

View file

@ -715,6 +715,36 @@ describe('Frontend Routing', function () {
});
});
it('with case insensitive', function (done) {
request.get('/CaSe-InSeNsItIvE')
.expect(302)
.expect('Cache-Control', testUtils.cacheRules.public)
.end(function (err, res) {
res.headers.location.should.eql('/redirected-insensitive');
doEnd(done)(err, res);
});
});
it('with case sensitive', function (done) {
request.get('/Case-Sensitive')
.expect(302)
.expect('Cache-Control', testUtils.cacheRules.public)
.end(function (err, res) {
res.headers.location.should.eql('/redirected-sensitive');
doEnd(done)(err, res);
});
});
it('defaults to case sensitive', function (done) {
request.get('/Default-Sensitive')
.expect(302)
.expect('Cache-Control', testUtils.cacheRules.public)
.end(function (err, res) {
res.headers.location.should.eql('/redirected-default');
doEnd(done)(err, res);
});
});
it('should not redirect', function (done) {
request.get('/post/a-nice-blog-post/')
.end(function (err, res) {
@ -723,6 +753,24 @@ describe('Frontend Routing', function () {
doEnd(done)(err, res);
});
});
it('should not redirect with case sensitive', function (done) {
request.get('/casE-sensitivE')
.end(function (err, res) {
res.headers.location.should.not.eql('/redirected-sensitive');
res.statusCode.should.not.eql(302);
doEnd(done)(err, res);
});
});
it('should not redirect with default case sensitive', function (done) {
request.get('/defaulT-sensitivE')
.end(function (err, res) {
res.headers.location.should.not.eql('/redirected-default');
res.statusCode.should.not.eql(302);
doEnd(done)(err, res);
});
});
});
describe('2 case', function () {

View file

@ -31,5 +31,16 @@
{
"from": "^/prefix/([a-z0-9\\-]+)?",
"to": "/blog/$1"
},
{
"from": "/^\\/case-insensitive/i",
"to": "/redirected-insensitive"
},{
"from": "^\\/Case-Sensitive",
"to": "/redirected-sensitive"
},
{
"from": "^\\/Default-Sensitive",
"to": "/redirected-default"
}
]