httpxy icon indicating copy to clipboard operation
httpxy copied to clipboard

DELETE requests add a "Content-Length: 0" header, causing undici to error "Request body length does not match content-length header"

Open dan-hammond opened this issue 1 year ago • 6 comments

Environment

  • Operating System: Darwin
  • Node Version: v20.5.1
  • Nuxt Version: 3.7.0
  • CLI Version: 3.7.2
  • Nitro Version: 2.6.2
  • Package Manager: [email protected]
  • Builder: -
  • User Config: -
  • Runtime Modules: -
  • Build Modules: -

Reproduction

I confess I haven't made one up-front. I think the explanation below might be enough, but if not I can try to figure out a reproduction.

Describe the bug

When making a DELETE request, the request has a "Content-Length: 0" header added to it, which causes Node's undici to respond with the following error:

TypeError: fetch failed
    at Object.fetch (node:internal/deps/undici/undici:11576:11)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async sendProxy (file:///myprojectpath/node_modules/h3/dist/index.mjs:1049:20)
    at async Object.handler (file:///myprojectpath/node_modules/h3/dist/index.mjs:1646:19)
    at async Server.toNodeHandle (file:///myprojectpath/node_modules/h3/dist/index.mjs:1857:7) {
  cause: RequestContentLengthMismatchError: Request body length does not match content-length header
      at write (node:internal/deps/undici/undici:10059:41)
      at _resume (node:internal/deps/undici/undici:10037:33)
      at resume (node:internal/deps/undici/undici:9938:7)
      at [dispatch] (node:internal/deps/undici/undici:9286:11)
      at Client.Intercept (node:internal/deps/undici/undici:9017:20)
      at Client.dispatch (node:internal/deps/undici/undici:7772:44)
      at [dispatch] (node:internal/deps/undici/undici:7991:32)
      at Pool.dispatch (node:internal/deps/undici/undici:7772:44)
      at [dispatch] (node:internal/deps/undici/undici:10556:27)
      at Agent.Intercept (node:internal/deps/undici/undici:9017:20) {
    code: 'UND_ERR_REQ_CONTENT_LENGTH_MISMATCH'
  }

More context has been provided here: https://github.com/nodejs/undici/issues/2046#issuecomment-1496932582

Here's the same code in this fork: https://github.com/unjs/httpxy/blob/f8cde141ece42e5a8d243a2963d6644ba3f83212/src/middleware/web-incoming.ts#L10

This is all somewhat beyond me, but I would think it's not the responsibility of the proxy to be adding HTTP headers that weren't provided in the initial request, unless it's intentional behaviour written in middleware or proxy route rules.

I appreciate that Node may end up fixing their underlying behaviour to allow DELETE requests with a Content-Length, but that may not solve the problem for people proxying to other non-JS back-ends.

Similarly, I have read in the linked undici issue that Safari does send Content-Length: 0 with DELETE requests, so it would be useful to know how I can filter those out. I am using extendRouteRules in a Nuxt module to register my proxy rules, and am doing so as a wildcard for a whole path prefix. Is that currently possible?

Additional context

No response

Logs

No response

dan-hammond avatar Aug 31 '23 20:08 dan-hammond