Skip to content

Commit 4698f17

Browse files
committed
Send complete HTML document in redirect & error responses
1 parent e631b7e commit 4698f17

File tree

3 files changed

+37
-11
lines changed

3 files changed

+37
-11
lines changed

HISTORY.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
unreleased
2+
==========
3+
4+
* Send complete HTML document in redirect & error responses
5+
16
0.14.2 / 2017-01-23
27
===================
38

index.js

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,8 @@ SendStream.prototype.error = function error (status, error) {
278278
}
279279

280280
var res = this.res
281-
var msg = statuses[status]
281+
var msg = statuses[status] || String(status)
282+
var doc = createHtmlDocument('Error', escapeHtml(msg))
282283

283284
// clear existing headers
284285
clearHeaders(res)
@@ -290,10 +291,10 @@ SendStream.prototype.error = function error (status, error) {
290291

291292
// send basic response
292293
res.statusCode = status
293-
res.setHeader('Content-Type', 'text/plain; charset=UTF-8')
294-
res.setHeader('Content-Length', Buffer.byteLength(msg))
294+
res.setHeader('Content-Type', 'text/html; charset=UTF-8')
295+
res.setHeader('Content-Length', Buffer.byteLength(doc))
295296
res.setHeader('X-Content-Type-Options', 'nosniff')
296-
res.end(msg)
297+
res.end(doc)
297298
}
298299

299300
/**
@@ -446,16 +447,17 @@ SendStream.prototype.redirect = function redirect (path) {
446447
}
447448

448449
var loc = encodeUrl(collapseLeadingSlashes(path + '/'))
449-
var msg = 'Redirecting to <a href="' + escapeHtml(loc) + '">' + escapeHtml(loc) + '</a>\n'
450+
var doc = createHtmlDocument('Redirecting', 'Redirecting to <a href="' + escapeHtml(loc) + '">' +
451+
escapeHtml(loc) + '</a>')
450452
var res = this.res
451453

452454
// redirect
453455
res.statusCode = 301
454456
res.setHeader('Content-Type', 'text/html; charset=UTF-8')
455-
res.setHeader('Content-Length', Buffer.byteLength(msg))
457+
res.setHeader('Content-Length', Buffer.byteLength(doc))
456458
res.setHeader('X-Content-Type-Options', 'nosniff')
457459
res.setHeader('Location', loc)
458-
res.end(msg)
460+
res.end(doc)
459461
}
460462

461463
/**
@@ -892,6 +894,26 @@ function contentRange (type, size, range) {
892894
return type + ' ' + (range ? range.start + '-' + range.end : '*') + '/' + size
893895
}
894896

897+
/**
898+
* Create a minimal HTML document.
899+
*
900+
* @param {string} title
901+
* @param {string} body
902+
* @private
903+
*/
904+
905+
function createHtmlDocument (title, body) {
906+
return '<!DOCTYPE html>\n' +
907+
'<html lang="en">\n' +
908+
'<head>\n' +
909+
'<meta charset="utf-8">\n' +
910+
'<title>' + title + '</title>\n' +
911+
'</head>\n' +
912+
'<body>\n' +
913+
'<pre>' + body + '</pre>\n' +
914+
'</body>\n'
915+
}
916+
895917
/**
896918
* decodeURIComponent.
897919
*

test/send.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,6 @@ describe('send(file).pipe(res)', function () {
171171

172172
request(app)
173173
.get('/name.txt')
174-
.expect('Content-Type', /plain/)
175174
.expect(404, done)
176175
})
177176

@@ -340,7 +339,7 @@ describe('send(file).pipe(res)', function () {
340339
.get('/pets')
341340
.expect('Location', '/pets/')
342341
.expect('Content-Type', /html/)
343-
.expect(301, 'Redirecting to <a href="/pets/">/pets/</a>\n', done)
342+
.expect(301, />Redirecting to <a href="\/pets\/">\/pets\/<\/a></, done)
344343
})
345344

346345
it('should not redirect to protocol-relative locations', function (done) {
@@ -360,15 +359,15 @@ describe('send(file).pipe(res)', function () {
360359
.get('/snow')
361360
.expect('Location', '/snow%20%E2%98%83/')
362361
.expect('Content-Type', /html/)
363-
.expect(301, 'Redirecting to <a href="/snow%20%E2%98%83/">/snow%20%E2%98%83/</a>\n', done)
362+
.expect(301, />Redirecting to <a href="\/snow%20%E2%98%83\/">\/snow%20%E2%98%83\/<\/a></, done)
364363
})
365364
})
366365

367366
describe('when no "error" listeners are present', function () {
368367
it('should respond to errors directly', function (done) {
369368
request(createServer({root: fixtures}))
370369
.get('/foobar')
371-
.expect(404, 'Not Found', done)
370+
.expect(404, />Not Found</, done)
372371
})
373372
})
374373

0 commit comments

Comments
 (0)