Browse Source

http2: setting shuttingDown=true after validation

In shutdown(), shuttingDown was set to true before validating options.
If invalid options are passed, error was thrown and server remained in
shuttingDown state. This code change fixes it.

PR-URL: https://github.com/nodejs/node/pull/15676
Fixes: https://github.com/nodejs/node/issues/15666
Refs: https://github.com/nodejs/node/issues/14985
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
v9.x-staging
Trivikram Kamat 8 years ago
committed by Ruben Bridgewater
parent
commit
7f0183e6c3
No known key found for this signature in database GPG Key ID: F07496B3EB3C1762
  1. 6
      lib/internal/http2/core.js
  2. 61
      test/parallel/test-http2-server-shutdown-options-errors.js

6
lib/internal/http2/core.js

@ -983,9 +983,6 @@ class Http2Session extends EventEmitter {
if (this[kState].shutdown || this[kState].shuttingDown)
return;
debug(`[${sessionName(this[kType])}] initiating shutdown`);
this[kState].shuttingDown = true;
const type = this[kType];
if (typeof options === 'function') {
@ -1023,6 +1020,9 @@ class Http2Session extends EventEmitter {
options.lastStreamID);
}
debug(`[${sessionName(this[kType])}] initiating shutdown`);
this[kState].shuttingDown = true;
if (callback) {
this.on('shutdown', callback);
}

61
test/parallel/test-http2-server-shutdown-options-errors.js

@ -0,0 +1,61 @@
'use strict';
const common = require('../common');
if (!common.hasCrypto)
common.skip('missing crypto');
const http2 = require('http2');
const server = http2.createServer();
const optionsToTest = {
opaqueData: 'Uint8Array',
graceful: 'boolean',
errorCode: 'number',
lastStreamID: 'number'
};
const types = {
boolean: true,
number: 1,
object: {},
array: [],
null: null,
Uint8Array: Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5])
};
server.on(
'stream',
common.mustCall((stream) => {
Object.keys(optionsToTest).forEach((option) => {
Object.keys(types).forEach((type) => {
if (type === optionsToTest[option]) {
return;
}
common.expectsError(
() =>
stream.session.shutdown(
{ [option]: types[type] },
common.mustNotCall()
),
{
type: TypeError,
code: 'ERR_INVALID_OPT_VALUE',
message: `The value "${String(types[type])}" is invalid ` +
`for option "${option}"`
}
);
});
});
stream.session.destroy();
})
);
server.listen(
0,
common.mustCall(() => {
const client = http2.connect(`http://localhost:${server.address().port}`);
const req = client.request();
req.resume();
req.on('end', common.mustCall(() => server.close()));
})
);
Loading…
Cancel
Save