HTTP/1 request parsing framing error event
- Version: v10.13.0
- Platform: Windows 10
- Subsystem: http
It seems that in Node.js 10+, it's no longer possible to know with a framing error happened during the request transfer to a server. This is evident in request parsing, for example. A framing error could be when the incoming request is coming in Tranfer-Encoding: chunked
and a chunk header is no valid hex.
Here is an example app that shows the error handing in previous Node.js versions working:
var http = require('http')
var net = require('net')
var server = http.createServer(function (req, res) {
var bufs = []
req.on('data', function (chunk) {
console.log('request recv %d bytes', chunk.length)
bufs.push(chunk)
})
req.on('end', function () {
var data = Buffer.concat(bufs)
console.log('request got %d bytes', data.length)
res.end('OK')
server.close()
})
req.socket.on('error', function (e) {
console.log('request error %s', e.toString())
req.destroy()
server.close()
})
})
server.listen(0, function () {
var port = server.address().port
var sock = net.createConnection(port, '127.0.0.1')
sock.on('connect', function () {
sock.write('POST / HTTP/1.1\r\n')
sock.write('Host: localhost\r\n')
sock.write('Transfer-Encoding: chunked\r\n')
sock.write('\r\n')
sock.write('3\r\n')
sock.write('foo\r\n')
sock.write('3\r\n')
sock.write('bar\r\n')
sock.write('ff\r\n')
sock.end()
})
})
setTimeout(function () {
console.log('timeout!')
process.exit(1)
}, 10000).unref()
In Node.js 8 and below it prints the following:
request recv 3 bytes
request recv 3 bytes
request error Error: Parse Error
In Node.js 10+ is prints the following:
request recv 3 bytes
request recv 3 bytes
timeout!
The req.on('close', ...)
fires in both, but I'm just asking about how to know if it closed from a socket error within the normal request / response transaction processing now in Node.js 10+. The best I can see is just if the 'close'
was before 'end'
, then it could have been due to an error. But of course there is no guarantee that 'close'
is actually emitted only after 'end'
: the close
event is emitted whenever the socket is closed, even if the entire request was received without error and was just pased (which is the state that req
starts out in).