Node: Accessing `socket` after HTTP2 session gets destroyed throws an error

Created on 11 Aug 2018  路  5Comments  路  Source: nodejs/node

  • Version: v10.8.0
  • Platform: Windows 10 64bit
  • Subsystem: http2

Example:

const http2 = require('http2')
const session = http2.connect(`https://google.com`);
const socket = session.socket;
const req = session.request({':path': '/', ':method': 'GET' });
req.on('close', () => {
    session.close();

    setTimeout(() => {
        socket['example'];
    }, 1000);
});

req.end();
req.resume();
internal/http2/core.js:678
        const value = socket[prop];
                            ^

TypeError: Cannot read property 'example' of undefined
    at Object.get (internal/http2/core.js:678:29)
    at Timeout.setTimeout [as _onTimeout] (/home/szymon/Desktop/bug/example.js:9:9)
    at ontimeout (timers.js:427:11)
    at tryOnTimeout (timers.js:289:5)
    at listOnTimeout (timers.js:252:5)
    at Timer.processTimers (timers.js:212:10)

ProxySocket assumes socket is available, but it's undefined after the session gets destroyed.

If this line was removed:

https://github.com/nodejs/node/blob/89f483b5c18590235ad55d55842b5a2a0c9fa89c/lib/internal/http2/core.js#L833

it'd work I think.

http2

Most helpful comment

All 5 comments

Could you provide a complete example?

Could you provide a complete example?

It is complete. Please note I metioned http2 as the subsystem, so you need const http2 = require('http2'). The options is free to choose. I've updated the example to https://google.com.

The example reproduces the error for me with the options below.
(From https://github.com/szmarczak/http2-wrapper/issues/2)

'use strict';
const http2 = require('http2');

const options = {
    'hostname': 'nghttp2.org',
    'protocol': 'https:',
    'path': '/httpbin/get',
    'method': 'GET'
};

const session = http2.connect(`${options.protocol}//${options.hostname}`);
const socket = session.socket;
const req = session.request({':path': options.path, ':method': options.method });
req.on('close', () => {
    session.close();

    setTimeout(() => {
        socket['example'];
    }, 1000);
});

req.end();
req.resume();

It arises from the logic here: https://github.com/nodejs/node/blob/89f483b5c18590235ad55d55842b5a2a0c9fa89c/lib/internal/http2/core.js#L684 https://github.com/nodejs/node/blob/89f483b5c18590235ad55d55842b5a2a0c9fa89c/lib/internal/http2/core.js#L685

Assigning to socket['example'] instead of reading from it triggers the same problem a few lines later in core.js https://github.com/nodejs/node/blob/89f483b5c18590235ad55d55842b5a2a0c9fa89c/lib/internal/http2/core.js#L706

investigating... working on a fix

Was this page helpful?
0 / 5 - 0 ratings