Skip to content

Commit

Permalink
http2: delay session.receive() by a tick
Browse files Browse the repository at this point in the history
PR-URL: #35985
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
  • Loading branch information
szmarczak authored and codebytere committed Nov 22, 2020
1 parent 1924255 commit 0b40568
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 39 deletions.
23 changes: 14 additions & 9 deletions lib/internal/http2/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -3139,16 +3139,21 @@ function connect(authority, options, listener) {
if (typeof listener === 'function')
session.once('connect', listener);

debug('Http2Session connect', options.createConnection);
// Socket already has some buffered data - emulate receiving it
// https://github.com/nodejs/node/issues/35475
if (socket && socket.readableLength) {
let buf;
while ((buf = socket.read()) !== null) {
debug(`Http2Session connect: injecting ${buf.length} already in buffer`);
session[kHandle].receive(buf);
// Process data on the next tick - a remoteSettings handler may be attached.
// https://github.com/nodejs/node/issues/35981
process.nextTick(() => {
debug('Http2Session connect', options.createConnection);
// Socket already has some buffered data - emulate receiving it
// https://github.com/nodejs/node/issues/35475
if (socket && socket.readableLength) {
let buf;
while ((buf = socket.read()) !== null) {
debug(`Http2Session connect: ${buf.length} bytes already in buffer`);
session[kHandle].receive(buf);
}
}
}
});

return session;
}

Expand Down
46 changes: 16 additions & 30 deletions test/parallel/test-http2-connect-tls-with-delay.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,61 +4,47 @@ const common = require('../common');
if (!common.hasCrypto)
common.skip('missing crypto');

if (!common.hasMultiLocalhost())
common.skip('platform-specific test.');

const http2 = require('http2');
const assert = require('assert');
const tls = require('tls');
const fixtures = require('../common/fixtures');

const serverOptions = {
key: fixtures.readKey('agent1-key.pem'),
cert: fixtures.readKey('agent1-cert.pem')
};
const server = http2.createSecureServer(serverOptions, (req, res) => {
console.log(`Connect from: ${req.connection.remoteAddress}`);
assert.strictEqual(req.connection.remoteAddress, '127.0.0.2');

req.on('end', common.mustCall(() => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end(`You are from: ${req.connection.remoteAddress}`);
}));
req.resume();
const server = http2.createSecureServer(serverOptions, (req, res) => {
res.end();
});

server.listen(0, '127.0.0.1', common.mustCall(() => {
const options = {
ALPNProtocols: ['h2'],
host: '127.0.0.1',
servername: 'localhost',
localAddress: '127.0.0.2',
port: server.address().port,
rejectUnauthorized: false
};

console.log('Server ready', server.address().port);

const socket = tls.connect(options, async () => {

console.log('TLS Connected!');

setTimeout(() => {

socket.once('readable', () => {
const client = http2.connect(
'https://localhost:' + server.address().port,
{ ...options, createConnection: () => socket }
);
const req = client.request({
':path': '/'
});
req.on('data', () => req.resume());
req.on('end', common.mustCall(function() {
client.close();
req.close();
server.close();

client.once('remoteSettings', common.mustCall(() => {
const req = client.request({
':path': '/'
});
req.on('data', () => req.resume());
req.on('end', common.mustCall(() => {
client.close();
req.close();
server.close();
}));
req.end();
}));
req.end();
}, 1000);
});
});
}));

0 comments on commit 0b40568

Please sign in to comment.