Skip to content

HTTP/1 request parsing framing error event #24585

Description

@dougwilson
  • 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).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    confirmed-bugIssues and PRs for confirmed bugs.httpIssues and PRs related to the http subsystem.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions