diff --git a/__tests__/response/redirect.js b/__tests__/response/redirect.js index ec7c43f94..0d257c8be 100644 --- a/__tests__/response/redirect.js +++ b/__tests__/response/redirect.js @@ -9,7 +9,14 @@ describe('ctx.redirect(url)', () => { it('should redirect to the given url', () => { const ctx = context() ctx.redirect('http://google.com') - assert.strictEqual(ctx.response.header.location, 'http://google.com') + assert.strictEqual(ctx.response.header.location, 'http://google.com/') + assert.strictEqual(ctx.status, 302) + }) + + it('should formatting url before redirect', () => { + const ctx = context() + ctx.redirect('http://google.com\\@apple.com') + assert.strictEqual(ctx.response.header.location, 'http://google.com/@apple.com') assert.strictEqual(ctx.status, 302) }) @@ -61,7 +68,7 @@ describe('ctx.redirect(url)', () => { describe('when html is accepted', () => { it('should respond with html', () => { const ctx = context() - const url = 'http://google.com' + const url = 'http://google.com/' ctx.header.accept = 'text/html' ctx.redirect(url) assert.strictEqual(ctx.response.header['content-type'], 'text/html; charset=utf-8') @@ -85,7 +92,7 @@ describe('ctx.redirect(url)', () => { const url = 'http://google.com' ctx.header.accept = 'text/plain' ctx.redirect(url) - assert.strictEqual(ctx.body, `Redirecting to ${url}.`) + assert.strictEqual(ctx.body, `Redirecting to ${url}/.`) }) }) @@ -97,7 +104,7 @@ describe('ctx.redirect(url)', () => { ctx.header.accept = 'text/plain' ctx.redirect('http://google.com') assert.strictEqual(ctx.status, 301) - assert.strictEqual(ctx.body, `Redirecting to ${url}.`) + assert.strictEqual(ctx.body, `Redirecting to ${url}/.`) }) }) @@ -109,7 +116,7 @@ describe('ctx.redirect(url)', () => { ctx.header.accept = 'text/plain' ctx.redirect('http://google.com') assert.strictEqual(ctx.status, 302) - assert.strictEqual(ctx.body, `Redirecting to ${url}.`) + assert.strictEqual(ctx.body, `Redirecting to ${url}/.`) }) }) @@ -121,7 +128,7 @@ describe('ctx.redirect(url)', () => { ctx.header.accept = 'text/plain' ctx.redirect('http://google.com') assert.strictEqual(ctx.status, 302) - assert.strictEqual(ctx.body, `Redirecting to ${url}.`) + assert.strictEqual(ctx.body, `Redirecting to ${url}/.`) assert.strictEqual(ctx.type, 'text/plain') }) }) diff --git a/lib/response.js b/lib/response.js index 94fd6faa3..fbfe303e3 100644 --- a/lib/response.js +++ b/lib/response.js @@ -266,6 +266,10 @@ module.exports = { redirect (url, alt) { // location if (url === 'back') url = this.ctx.get('Referrer') || alt || '/' + if (url.startsWith('https://') || url.startsWith('http://')) { + // formatting url again avoid security escapes + url = new URL(url).toString() + } this.set('Location', encodeUrl(url)) // status