diff --git a/lib/response.js b/lib/response.js index 0b9c355d4..df329d766 100644 --- a/lib/response.js +++ b/lib/response.js @@ -295,9 +295,23 @@ function patch(Response) { */ Response.prototype.send = function send(code, body, headers) { var self = this; - var args = Array.prototype.slice.call(arguments); - args.push(true); // Append format = true to __send invocation - return self.__send.apply(self, args); + var sendArgs; + + if (typeof code === 'number') { + sendArgs = { + code: code, + body: body, + headers: headers + }; + } else { + sendArgs = { + body: code, + headers: body + }; + } + + sendArgs.format = true; + return self.__send(sendArgs); }; /** @@ -317,9 +331,23 @@ function patch(Response) { */ Response.prototype.sendRaw = function sendRaw(code, body, headers) { var self = this; - var args = Array.prototype.slice.call(arguments); - args.push(false); // Append format = false to __send invocation - return self.__send.apply(self, args); + var sendArgs; + + if (typeof code === 'number') { + sendArgs = { + code: code, + body: body, + headers: headers + }; + } else { + sendArgs = { + body: code, + headers: body + }; + } + + sendArgs.format = false; + return self.__send(sendArgs); }; // eslint-disable-next-line jsdoc/check-param-names @@ -331,51 +359,20 @@ function patch(Response) { * providing headers. * * @private - * @param {Number} [code] - http status code - * @param {Object | Buffer | String | Error} [body] - the content to send - * @param {Object} [headers] - any add'l headers to set - * @param {Boolean} [format] - When false, skip formatting - * @returns {Object} returns the response object + * @param {Object} opts - an option sobject + * @param {Object | Buffer | String | Error} opts.body - the content to send + * @param {Boolean} opts.format - When false, skip formatting + * @param {Number} [opts.code] - http status code + * @param {Object} [opts.headers] - any add'l headers to set + * @returns {Object} - returns the response object */ - Response.prototype.__send = function __send() { + Response.prototype.__send = function __send(opts) { var self = this; var isHead = self.req.method === 'HEAD'; var log = self.log; - var code, body, headers, format; - - // derive arguments from types, one by one - var index = 0; - // Check to see if the first argument is a status code - if (typeof arguments[index] === 'number') { - code = arguments[index++]; - } - - // Check to see if the next argument is a body - if ( - typeof arguments[index] === 'object' || - typeof arguments[index] === 'string' - ) { - body = arguments[index++]; - } - - // Check to see if the next argument is a collection of headers - if (typeof arguments[index] === 'object') { - headers = arguments[index++]; - } - - // Check to see if the next argument is the format boolean - if (typeof arguments[index] === 'boolean') { - format = arguments[index++]; - } - - // Ensure the function was provided with arguments of the proper types, - // if we reach this line and there are still arguments, either one of - // the optional arguments was of an invalid type or we were provided - // with too many arguments - assert( - arguments[index] === undefined, - 'Unknown argument: ' + arguments[index] + '\nProvided: ' + arguments - ); + var code = opts.code; + var body = opts.body; + var headers = opts.headers || {}; // Now lets try to derive values for optional arguments that we were not // provided, otherwise we choose sane defaults. @@ -397,7 +394,6 @@ function patch(Response) { // Set sane defaults for optional arguments if they were not provided // and we failed to derive their values code = code || self.statusCode || 200; - headers = headers || {}; // Populate our response object with the derived arguments self.statusCode = code; @@ -429,7 +425,7 @@ function patch(Response) { // if no formatting, assert that the value to be written is a string // or a buffer, then send it. - if (format === false) { + if (opts.format === false) { assert.ok( typeof body === 'string' || Buffer.isBuffer(body), 'res.sendRaw() accepts only strings or buffers' diff --git a/test/response.test.js b/test/response.test.js index 0876228fe..8f77f32b1 100644 --- a/test/response.test.js +++ b/test/response.test.js @@ -636,3 +636,54 @@ test('should support multiple set-cookie headers', function(t) { t.end(); }); }); + +test('GH-1607: should send bools with explicit status code', function(t) { + SERVER.get('/bool/:value', function(req, res, next) { + res.send(200, req.params.value === 'true' ? true : false); + return next(); + }); + + STRING_CLIENT.get(join(LOCALHOST, '/bool/false'), function( + err, + req, + res, + data + ) { + t.equal(data, 'false'); + + STRING_CLIENT.get(join(LOCALHOST, '/bool/true'), function( + err2, + req2, + res2, + data2 + ) { + t.equal(data2, 'true'); + t.end(); + }); + }); +}); + +test('GH-1607: should send numbers with explicit status code', function(t) { + SERVER.get('/zero', function(req, res, next) { + res.send(200, 0); + return next(); + }); + + SERVER.get('/one', function(req, res, next) { + res.send(200, 1); + return next(); + }); + + STRING_CLIENT.get(join(LOCALHOST, '/zero'), function(err, req, res, data) { + t.equal(data, '0'); + STRING_CLIENT.get(join(LOCALHOST, '/one'), function( + err2, + req2, + res2, + data2 + ) { + t.equal(data2, '1'); + t.end(); + }); + }); +});