Skip to content

Commit

Permalink
Merge 71215bc into 6a01ba8
Browse files Browse the repository at this point in the history
  • Loading branch information
przbab committed Aug 26, 2020
2 parents 6a01ba8 + 71215bc commit f0b0572
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 2 deletions.
14 changes: 12 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,27 @@ function removeTrailingSlashes(opts) {
}

let path;
let querystring = '';

// We have already done a redirect and we will continue if we are in chained mode
if (opts.chained && ctx.status === 301) {
path = getPath(ctx.response.get('Location'), ctx.querystring);
const location = ctx.response.get('Location') || '';

// We can't use ctx.querystring because it may not be up to date
const parsedLocation = location.match(/\?(.*)$/);
if (parsedLocation && parsedLocation[1]) {
querystring = parsedLocation[1];
}

path = getPath(location, querystring);
} else if (ctx.status !== 301) {
querystring = ctx.querystring;
path = getPath(ctx.originalUrl, ctx.querystring);
}

if (path && haveSlash(path)) {
path = path.slice(0, -1);
const query = ctx.querystring.length ? '?' + ctx.querystring : '';
const query = querystring.length ? '?' + querystring : '';

ctx.status = 301;
ctx.redirect(path + query);
Expand Down
36 changes: 36 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,42 @@ describe('koa-remove-trailing-slashes', () => {
expect(mock.ctx.status).toBe(301);
});

it('should correctly chain redirect if path has trailing slash and query params', async () => {
const mock = createMock('/fOo/?baz=1', 'baz=1');

// Mock that something has made a redirect before us
mock.ctx.status = 301;
mock.ctx.body = 'Redirecting to …';
mock.ctx.response = {
get() {
return '/foo/?bar=1';
}
};

await removeTrailingSlashes()(mock.ctx, mock.next);

expect(mock.redirectMock.calls[0].arguments[0]).toEqual('/foo?bar=1');
expect(mock.ctx.status).toBe(301);
});

it('should not use old query params when processing chain redirects', async () => {
const mock = createMock('/fOo/?baz=1', 'baz=1');

// Mock that something has made a redirect before us
mock.ctx.status = 301;
mock.ctx.body = 'Redirecting to …';
mock.ctx.response = {
get() {
return '/foo/barrr/';
}
};

await removeTrailingSlashes()(mock.ctx, mock.next);

expect(mock.redirectMock.calls[0].arguments[0]).toEqual('/foo/barrr');
expect(mock.ctx.status).toBe(301);
});

it('should redirect on url and path has trailing slash', async () => {
const mock = createMock('/foo/');
await removeTrailingSlashes()(mock.ctx, mock.next);
Expand Down

0 comments on commit f0b0572

Please sign in to comment.