Open
Description
The following conditions cause an error event on http2stream
, even though http2stream
received all data and RST_STREAM from a client.
http2stream
is not destroyed(does not consume all data)- goaway frame is not received
- socket error happens
http2stream
received all data and RST_STREAM
Socket error without goaway frame causes a http2session.destroy(err)
.
node/lib/internal/http2/core.js
Lines 2678 to 2688 in 81bc7b3
http2session.destroy(err)
propagate error to http2stream.destroy(err)
.
node/lib/internal/http2/core.js
Lines 1298 to 1323 in 81bc7b3
I thought that http2stream
got RST_STREAM means that there is no error about processing data. So, I thought if http2stream
is closed by RST_STREAM, connection error should not cause http2stream
error.
The codes to reproduce.
'use strict';
const common = require('../common');
const fixtures = require('../common/fixtures');
const http2 = require('http2');
const fs = require('fs');
const net = require('net');
const tmpdir = require('../common/tmpdir');
tmpdir.refresh();
const loc = fixtures.path('person-large.jpg');
const server = http2.createServer();
let session_;
server.on('session', (session)=>{
session_ = session;
});
server.on('stream', common.mustCall((stream) => {
let sum = 0;
stream.pause();
const slowRead = ()=>{
setTimeout(()=>{
const data = stream.read(stream._readableState.highWaterMark/10);
sum += data ? data.length: 0;
console.log('read:' + sum + ' soc:' + socket.bytesWritten + ' closed:' + stream.closed + ' destroyed:' + stream.destroyed);
if(stream.closed){ // Got RST_STREAM and stream was closed but all data isn't processed.
socket.destroy(); // destroy connection without goaway frame.
try{
session_.ping(()=>{}); // activate read.
}catch(err){
console.log(err);
}
}
slowRead();
}, 10)
};
slowRead();
stream.respond();
stream.end();
stream.on('error', (err)=>{
// Stream allready closed, but error event happens.
console.log(err);
});
}));
let socket;
server.listen(0, common.mustCall(() => {
const options = {
createConnection: (authority, options) => {
socket = net.connect(server.address().port, 'localhost');
return socket;
}
}
const client = http2.connect(`http://localhost:${server.address().port}`, options);
const req = client.request({ ':method': 'POST' });
req.on('response', common.mustCall());
req.resume();
const str = fs.createReadStream(loc);
str.on('end', common.mustCall());
str.pipe(req);
}));