undici: How to handle invalid server response?

Consider the following:

const net = require('net')

const socket = net.connect(80, 'feeds.bbci.co.uk')
  .on('data', buf => {
    process.stdout.write(buf)
  })
  
socket.write('GET /news/rss.xml HTTP/1.1\r\n')
socket.write('host: feeds.bbci.co.uk\r\n')
socket.write('connection: keep-alive\r\n')
socket.write('transfer-encoding: chunked\r\n\r\n')

socket.write('7\r\n')
socket.write('Mozilla\r\n')
socket.write('9\r\n')
socket.write('Developer\r\n')
socket.write('7\r\n')
socket.write('Network\r\n')
socket.write('0\r\n')
socket.write('\r\n')

Running this will give two (?!) replies from the server, one HTTP/1.1 200 OK followed by a HTTP/1.0 400 Bad Request.

Seems like the server for whatever reason is parsing the above as two request and provides two responses. This only happens with chunked transfer encoding against this specific (nginx + AkamaiGHost?) server.

I have no idea why it does this.

In undici this will cause either a hard crash if nothing is in the pipeline, or start replying to the next pipelined request, essentially corrupting state.

I’m not sure how to handle this. Any thoughts?

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 17 (17 by maintainers)

Commits related to this issue

Most upvoted comments

If we can’t find a workaround is totally fine for me disallowing body in GET requests 😃

@ronag correct, Elasticsearch does accept GET request with bodies. But unless the user enforces the GET method, the client will send all of them via POST.

A good solution might be to set the content-length header only if a body is present. From my experience having the content-length set to 0 in GET request without a body could cause rejections as well.

They accept POST requests as well.

Yes, what I mean is that we don’t want to break them since they have GET with body as part of their API.