diff --git a/History.md b/History.md index 73fc46b26f..bb37e9d9cd 100644 --- a/History.md +++ b/History.md @@ -1,3 +1,10 @@ +unreleased +========================= +* breaking: + * `res.status()` accepts only integers, and input must be greater than 99 and less than 999 + * will throw a `RangeError: Invalid status code: ${code}. Status code must be greater than 99 and less than 1000.` for inputs outside this range + * will throw a `TypeError: Invalid status code: ${code}. Status code must be an integer.` for non integer inputs + 5.0.0-beta.3 / 2024-03-25 ========================= diff --git a/lib/response.js b/lib/response.js index 14743817a9..b83a56214b 100644 --- a/lib/response.js +++ b/lib/response.js @@ -15,7 +15,6 @@ var Buffer = require('safe-buffer').Buffer var contentDisposition = require('content-disposition'); var createError = require('http-errors') -var deprecate = require('depd')('express'); var encodeUrl = require('encodeurl'); var escapeHtml = require('escape-html'); var http = require('http'); @@ -57,17 +56,43 @@ module.exports = res var schemaAndHostRegExp = /^(?:[a-zA-Z][a-zA-Z0-9+.-]*:)?\/\/[^\\\/\?]+/; /** - * Set status `code`. + * Set the HTTP status code for the response. * - * @param {Number} code - * @return {ServerResponse} + * Expects an integer value between 100 and 999 inclusive. + * Throws an error if the provided status code is not an integer or if it's outside the allowable range. + * + * @param {number} code - The HTTP status code to set. + * @return {ServerResponse} - Returns itself for chaining methods. + * @throws {TypeError} If `code` is not an integer. + * @throws {RangeError} If `code` is outside the range 100 to 999. * @public */ res.status = function status(code) { - if ((typeof code === 'string' || Math.floor(code) !== code) && code > 99 && code < 1000) { - deprecate('res.status(' + JSON.stringify(code) + '): use res.status(' + Math.floor(code) + ') instead') + // Check if the status code is not an integer + if (!Number.isInteger(code)) { + throw new TypeError(`Invalid status code: ${code}. Status code must be an integer.`); } + // Check if the status code is outside of Node's valid range + if (code < 100 || code > 999) { + throw new RangeError(`Invalid status code: ${code}. Status code must be greater than 99 and less than 1000.`); + } + + this.statusCode = code; + return this; +}; + + +res.status = function status(code) { + // Check if the status code is not an integer + if (!Number.isInteger(code)) { + throw new TypeError(`Invalid status code: ${code}. Status code must be an integer.`); + } + // Check if the status code is outside of Node's valid range + if (code < 100 || code > 999) { + throw new RangeError(`Invalid status code: ${code}. Status code must be greater than 99 and less than 1000.`); + } + this.statusCode = code; return this; }; @@ -182,7 +207,7 @@ res.send = function send(body) { } // freshness - if (req.fresh) this.statusCode = 304; + if (req.fresh) this.status(304); // strip irrelevant headers if (204 === this.statusCode || 304 === this.statusCode) { @@ -314,7 +339,7 @@ res.jsonp = function jsonp(obj) { res.sendStatus = function sendStatus(statusCode) { var body = statuses.message[statusCode] || String(statusCode) - this.statusCode = statusCode; + this.status(statusCode); this.type('txt'); return this.send(body); @@ -847,7 +872,7 @@ res.redirect = function redirect(url) { }); // Respond - this.statusCode = status; + this.status(status); this.set('Content-Length', Buffer.byteLength(body)); if (this.req.method === 'HEAD') { diff --git a/test/res.status.js b/test/res.status.js index d2fc6a28c1..64cfc8304c 100644 --- a/test/res.status.js +++ b/test/res.status.js @@ -9,11 +9,7 @@ var isIoJs = process.release describe('res', function () { describe('.status(code)', function () { - // This test fails in node 4.0.0 - // https://github.com/expressjs/express/pull/2237/checks - // As this will all be removed when https://github.com/expressjs/express/pull/4212 - // lands I am skipping for now and we can delete with that PR - describe.skip('when "code" is undefined', function () { + describe('when "code" is undefined', function () { it('should raise error for invalid status code', function (done) { var app = express() @@ -33,7 +29,7 @@ describe('res', function () { }) }) - describe.skip('when "code" is null', function () { + describe('when "code" is null', function () { it('should raise error for invalid status code', function (done) { var app = express() @@ -109,41 +105,35 @@ describe('res', function () { }) }) - describe('when "code" is "410"', function () { - it('should set the response status code to 410', function (done) { + describe('when "code" is 700', function () { + it('should set the response status code to 700', function (done) { var app = express() app.use(function (req, res) { - res.status('410').end() + res.status(700).end() }) request(app) .get('/') - .expect(410, done) + .expect(700, done) }) }) - describe.skip('when "code" is 410.1', function () { - it('should set the response status code to 410', function (done) { + describe('when "code" is 200.00', function () { + it('should set the response status code to 200', function (done) { var app = express() app.use(function (req, res) { - res.status(410.1).end() + res.status(200.00).end() }) request(app) .get('/') - .expect(410, function (err) { - if (isIoJs) { - done(err ? null : new Error('expected error')) - } else { - done(err) - } - }) + .expect(200, done) }) }) - describe.skip('when "code" is 1000', function () { + describe('when "code" is 1000', function () { it('should raise error for invalid status code', function (done) { var app = express() @@ -163,7 +153,7 @@ describe('res', function () { }) }) - describe.skip('when "code" is 99', function () { + describe('when "code" is 99', function () { it('should raise error for invalid status code', function (done) { var app = express() @@ -183,7 +173,7 @@ describe('res', function () { }) }) - describe.skip('when "code" is -401', function () { + describe('when "code" is -401', function () { it('should raise error for invalid status code', function (done) { var app = express() @@ -202,5 +192,89 @@ describe('res', function () { }) }) }) + + describe('invalid status codes', function() { + + it('should throw if status code is < 100', function(done) { + var app = express(); + app.use(function(req, res){ + res.status(99).end(); + }); + + request(app) + .get('/') + .expect(500, /RangeError: Invalid status code/, done) + + }) + + it('should throw if status code is > 999', function(done) { + var app = express(); + app.use(function(req, res){ + res.status(1000).end(); + }); + + request(app) + .get('/') + .expect(500, /RangeError: Invalid status code/, done) + + }) + + it('should throw if status code is undefined', function(done) { + var app = express(); + app.use(function(req, res){ + res.status(undefined).end(); + }); + + request(app) + .get('/') + .expect(500, /TypeError: Invalid status code/, done) + + }) + + it('should throw if status code is null', function(done) { + var app = express(); + app.use(function(req, res){ + res.status(null).end(); + }); + + request(app) + .get('/') + .expect(500, /TypeError: Invalid status code/, done) + + }) + + it('should throw if status code is a float', function(done) { + var app = express(); + app.use(function(req, res){ + res.status(200.1).end(); + }); + + request(app) + .get('/') + .expect(500, /TypeError: Invalid status code/, done) + }) + + it('should throw if status code is a string', function(done) { + var app = express(); + app.use(function(req, res){ + res.status('200').end(); + }); + + request(app) + .get('/') + .expect(500, /TypeError: Invalid status code/, done) + }) + + it('should throw if status code is NaN', function(done) { + var app = express(); + app.use(function(req, res){ + res.status(NaN).end(); + }); + + request(app) + .get('/') + .expect(500, /TypeError: Invalid status code/, done) + }) + }) }) })