diff --git a/doc/api/http.md b/doc/api/http.md index 928ed0d972b..a4ed90269d6 100644 --- a/doc/api/http.md +++ b/doc/api/http.md @@ -911,7 +911,7 @@ added: v0.9.12 The number of milliseconds of inactivity before a socket is presumed to have timed out. -A value of 0 will disable the timeout behavior on incoming connections. +A value of `0` will disable the timeout behavior on incoming connections. *Note*: The socket timeout logic is set up on connection, so changing this value only affects new connections to the server, not any existing connections. @@ -929,7 +929,9 @@ will be destroyed. If the server receives new data before the keep-alive timeout has fired, it will reset the regular inactivity timeout, i.e., [`server.timeout`][]. -A value of 0 will disable the keep-alive timeout behavior on incoming connections. +A value of `0` will disable the keep-alive timeout behavior on incoming connections. +A value of `0` makes the http server behave similarly to Node.js versions prior to 8.0.0, +which did not have a keep-alive timeout. *Note*: The socket timeout logic is set up on connection, so changing this value only affects new connections to the server, not any existing connections. diff --git a/lib/assert.js b/lib/assert.js index b26cd1db5e7..4da17b18c51 100644 --- a/lib/assert.js +++ b/lib/assert.js @@ -320,7 +320,15 @@ assert.ifError = function ifError(err) { if (err) throw err; }; // Expose a strict only variant of assert function strict(value, message) { - if (!value) innerFail(value, true, message, '==', strict); + if (!value) { + innerFail({ + actual: value, + expected: true, + message, + operator: '==', + stackStartFn: strict + }); + } } assert.strict = Object.assign(strict, assert, { equal: assert.strictEqual, diff --git a/lib/internal/http.js b/lib/internal/http.js index 71e32498f35..2b9c948aeef 100644 --- a/lib/internal/http.js +++ b/lib/internal/http.js @@ -1,20 +1,21 @@ 'use strict'; -const timers = require('timers'); +const { setUnrefTimeout } = require('internal/timers'); var dateCache; function utcDate() { if (!dateCache) { const d = new Date(); dateCache = d.toUTCString(); - timers.enroll(utcDate, 1000 - d.getMilliseconds()); - timers._unrefActive(utcDate); + + setUnrefTimeout(resetCache, 1000 - d.getMilliseconds()); } return dateCache; } -utcDate._onTimeout = function() { + +function resetCache() { dateCache = undefined; -}; +} function ondrain() { if (this._httpMessage) this._httpMessage.emit('drain'); diff --git a/lib/util.js b/lib/util.js index 0d75e43f08d..e0cdc2c28f8 100644 --- a/lib/util.js +++ b/lib/util.js @@ -1056,9 +1056,12 @@ function error(...args) { } function _errnoException(err, syscall, original) { - if (typeof err !== 'number' || err >= 0 || !Number.isSafeInteger(err)) { - throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'err', - 'negative number'); + if (typeof err !== 'number') { + throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'err', 'number', err); + } + if (err >= 0 || !Number.isSafeInteger(err)) { + throw new errors.RangeError('ERR_OUT_OF_RANGE', 'err', + 'a negative integer', err); } const name = errname(err); var message = `${syscall} ${name}`; @@ -1093,10 +1096,6 @@ function _exceptionWithHostPort(err, return ex; } -// process.versions needs a custom function as some values are lazy-evaluated. -process.versions[inspect.custom] = - () => exports.format(JSON.parse(JSON.stringify(process.versions))); - function callbackifyOnRejected(reason, cb) { // `!reason` guard inspired by bluebird (Ref: https://goo.gl/t5IS6M). // Because `null` is a special error value in callbacks which means "no error diff --git a/test/parallel/test-accessor-properties.js b/test/parallel/test-accessor-properties.js index 478b1c55e93..13535ceda96 100644 --- a/test/parallel/test-accessor-properties.js +++ b/test/parallel/test-accessor-properties.js @@ -1,6 +1,6 @@ 'use strict'; -require('../common'); +const common = require('../common'); // This tests that the accessor properties do not raise assertions // when called with incompatible receivers. @@ -12,9 +12,6 @@ const assert = require('assert'); const TTY = process.binding('tty_wrap').TTY; const UDP = process.binding('udp_wrap').UDP; -// There are accessor properties in crypto too -const crypto = process.binding('crypto'); - { // Should throw instead of raise assertions assert.throws(() => { @@ -33,15 +30,6 @@ const crypto = process.binding('crypto'); UDP.prototype.fd; }, TypeError); - assert.throws(() => { - crypto.SecureContext.prototype._external; - }, TypeError); - - assert.throws(() => { - crypto.Connection.prototype._external; - }, TypeError); - - // Should not throw for Object.getOwnPropertyDescriptor assert.strictEqual( typeof Object.getOwnPropertyDescriptor(TTY.prototype, 'bytesRead'), @@ -63,15 +51,28 @@ const crypto = process.binding('crypto'); 'object' ); - assert.strictEqual( - typeof Object.getOwnPropertyDescriptor( - crypto.SecureContext.prototype, '_external'), - 'object' - ); - - assert.strictEqual( - typeof Object.getOwnPropertyDescriptor( - crypto.Connection.prototype, '_external'), - 'object' - ); + if (common.hasCrypto) { // eslint-disable-line crypto-check + // There are accessor properties in crypto too + const crypto = process.binding('crypto'); + + assert.throws(() => { + crypto.SecureContext.prototype._external; + }, TypeError); + + assert.throws(() => { + crypto.Connection.prototype._external; + }, TypeError); + + assert.strictEqual( + typeof Object.getOwnPropertyDescriptor( + crypto.SecureContext.prototype, '_external'), + 'object' + ); + + assert.strictEqual( + typeof Object.getOwnPropertyDescriptor( + crypto.Connection.prototype, '_external'), + 'object' + ); + } } diff --git a/test/parallel/test-assert.js b/test/parallel/test-assert.js index c7bbd9249da..862bccaacc7 100644 --- a/test/parallel/test-assert.js +++ b/test/parallel/test-assert.js @@ -753,6 +753,14 @@ common.expectsError( assert.equal(Object.keys(assert).length, Object.keys(a).length); /* eslint-enable no-restricted-properties */ assert(7); + common.expectsError( + () => assert(), + { + code: 'ERR_ASSERTION', + type: assert.AssertionError, + message: 'undefined == true' + } + ); } common.expectsError( diff --git a/test/parallel/test-child-process-fork-net2.js b/test/parallel/test-child-process-fork-net2.js index 2686daccb28..dad6b0b2d0e 100644 --- a/test/parallel/test-child-process-fork-net2.js +++ b/test/parallel/test-child-process-fork-net2.js @@ -33,7 +33,7 @@ if (process.argv[2] === 'child') { process.on('message', function(m, socket) { if (!socket) return; - console.error('[%d] got socket', id, m); + console.error(`[${id}] got socket ${m}`); // will call .end('end') or .write('write'); socket[m](m); @@ -41,11 +41,11 @@ if (process.argv[2] === 'child') { socket.resume(); socket.on('data', function() { - console.error('[%d] socket.data', id, m); + console.error(`[${id}] socket.data ${m}`); }); socket.on('end', function() { - console.error('[%d] socket.end', id, m); + console.error(`[${id}] socket.end ${m}`); }); // store the unfinished socket @@ -54,27 +54,27 @@ if (process.argv[2] === 'child') { } socket.on('close', function(had_error) { - console.error('[%d] socket.close', id, had_error, m); + console.error(`[${id}] socket.close ${had_error} ${m}`); }); socket.on('finish', function() { - console.error('[%d] socket finished', id, m); + console.error(`[${id}] socket finished ${m}`); }); }); process.on('message', function(m) { if (m !== 'close') return; - console.error('[%d] got close message', id); + console.error(`[${id}] got close message`); needEnd.forEach(function(endMe, i) { - console.error('[%d] ending %d/%d', id, i, needEnd.length); + console.error(`[${id}] ending ${i}/${needEnd.length}`); endMe.end('end'); }); }); process.on('disconnect', function() { - console.error('[%d] process disconnect, ending', id); + console.error(`[${id}] process disconnect, ending`); needEnd.forEach(function(endMe, i) { - console.error('[%d] ending %d/%d', id, i, needEnd.length); + console.error(`[${id}] ending ${i}/${needEnd.length}`); endMe.end('end'); }); }); @@ -107,7 +107,7 @@ if (process.argv[2] === 'child') { connected += 1; socket.once('close', function() { - console.log('[m] socket closed, total %d', ++closed); + console.log(`[m] socket closed, total ${++closed}`); }); if (connected === count) { diff --git a/test/parallel/test-http2-util-headers-list.js b/test/parallel/test-http2-util-headers-list.js index 0bbe1972d07..0ff6b558d9a 100644 --- a/test/parallel/test-http2-util-headers-list.js +++ b/test/parallel/test-http2-util-headers-list.js @@ -5,6 +5,8 @@ // to pass to the internal binding layer. const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); const assert = require('assert'); const { mapToHeaders } = require('internal/http2/util'); diff --git a/test/parallel/test-http2-util-update-options-buffer.js b/test/parallel/test-http2-util-update-options-buffer.js index c150f4767fe..5768ce0204d 100644 --- a/test/parallel/test-http2-util-update-options-buffer.js +++ b/test/parallel/test-http2-util-update-options-buffer.js @@ -1,7 +1,9 @@ // Flags: --expose-internals 'use strict'; -require('../common'); +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); // Test coverage for the updateOptionsBuffer method used internally // by the http2 implementation. diff --git a/test/parallel/test-repl-tab-complete.js b/test/parallel/test-repl-tab-complete.js index c9048d887d5..6485f8bd17f 100644 --- a/test/parallel/test-repl-tab-complete.js +++ b/test/parallel/test-repl-tab-complete.js @@ -544,7 +544,8 @@ editor.completer('var log = console.l', common.mustCall((error, data) => { ['Let', 'Const', 'Klass'].forEach((type) => { const query = `lexical${type[0]}`; - const expected = hasInspector ? [[`lexical${type}`], query] : []; + const expected = hasInspector ? [[`lexical${type}`], query] : + [[], `lexical${type[0]}`]; testRepl.complete(query, common.mustCall((error, data) => { assert.deepStrictEqual(data, expected); })); diff --git a/test/parallel/test-uv-errno.js b/test/parallel/test-uv-errno.js index 223be905805..e4a40f20c84 100644 --- a/test/parallel/test-uv-errno.js +++ b/test/parallel/test-uv-errno.js @@ -20,12 +20,25 @@ keys.forEach((key) => { }); }); -[0, 1, 'test', {}, [], Infinity, -Infinity, NaN].forEach((key) => { +['test', {}, []].forEach((key) => { common.expectsError( () => util._errnoException(key), { code: 'ERR_INVALID_ARG_TYPE', type: TypeError, - message: 'The "err" argument must be of type negative number' + message: 'The "err" argument must be of type number. ' + + `Received type ${typeof key}` + }); +}); + +[0, 1, Infinity, -Infinity, NaN].forEach((key) => { + common.expectsError( + () => util._errnoException(key), + { + code: 'ERR_OUT_OF_RANGE', + type: RangeError, + message: 'The value of "err" is out of range. ' + + 'It must be a negative integer. ' + + `Received ${key}` }); }); diff --git a/tools/eslint-rules/crypto-check.js b/tools/eslint-rules/crypto-check.js index 9d24d3355dc..9570c24c030 100644 --- a/tools/eslint-rules/crypto-check.js +++ b/tools/eslint-rules/crypto-check.js @@ -16,13 +16,18 @@ const utils = require('./rules-utils.js'); const msg = 'Please add a hasCrypto check to allow this test to be skipped ' + 'when Node is built "--without-ssl".'; +const cryptoModules = ['crypto', 'http2']; +const requireModules = cryptoModules.concat(['tls', 'https']); +const bindingModules = cryptoModules.concat(['tls_wrap']); + module.exports = function(context) { const missingCheckNodes = []; const requireNodes = []; var hasSkipCall = false; function testCryptoUsage(node) { - if (utils.isRequired(node, ['crypto', 'tls', 'https', 'http2'])) { + if (utils.isRequired(node, requireModules) || + utils.isBinding(node, bindingModules)) { requireNodes.push(node); } } diff --git a/tools/eslint-rules/rules-utils.js b/tools/eslint-rules/rules-utils.js index f2f5428ed1c..2bfab1c6399 100644 --- a/tools/eslint-rules/rules-utils.js +++ b/tools/eslint-rules/rules-utils.js @@ -12,6 +12,18 @@ module.exports.isRequired = function(node, modules) { modules.includes(node.arguments[0].value); }; +/** + * Returns true if any of the passed in modules are used in + * binding calls. + */ +module.exports.isBinding = function(node, modules) { + if (node.callee.object) { + return node.callee.object.name === 'process' && + node.callee.property.name === 'binding' && + modules.includes(node.arguments[0].value); + } +}; + /** * Returns true is the node accesses any property in the properties * array on the 'common' object.