0

I'm struggling with pretty weird error I'm getting from the Fastify on Node JS.

The server has a post service which is supposed to handle requests of gzipped JSONs body.

When I try to test it using curl or any other http client, I'm getting Request body size did not match Content-Length

My request does provide the Content-Length, the length of compressed file

 curl -v -i http://127.0.0.1:8081/eventproxy/track -H 'Content-Encoding: gzip' -H "Content-Type: application/json" -H "Content-Length:479" --data-binary @sampleBatch.json.gz

I'm pretty sure it's related to the Fastify, but can't figure out what I'm missing. Any idea how to get it working.

Thanks

Denis Voloshin
  • 768
  • 10
  • 32

1 Answers1

3

You need to change approach because the default content parser doesn't manage compression and will try to parse the body.

So to manage the compression you can overwrite the default addContentTypeParser and add the decompression logic:

const zlib = require('zlib')
const port = 8081
var fastify

fastify = require('fastify')({ logger: true })

/**
 * Setup an fastify server and define port to listen all incoming requests for this application
 */
const setUpFastify = () => {
  fastify.addContentTypeParser('application/json', { parseAs: 'buffer' }, function (req, body, done) {
    if (req.headers['content-encoding'] && req.headers['content-encoding'] === 'gzip') {
      zlib.gunzip(body, function (err, dezipped) {
        if (err) {
          done(err, null)
        } else {
          done(err, JSON.parse(dezipped.toString('utf-8')))
        }
      })
    } else {
      done(null, JSON.parse(body.toString('utf-8')))
    }
  })

  fastify.post('/track', function (req, reply) {
    reply.send(req.body)
  })

  fastify.listen(port, 'localhost', () => {
    console.log('Worker listening on ' + port + ` PID: ${process.pid}`)
  })
}

setUpFastify()

Note that fastify uses secure-json-parse to parse the json string.

And the curl, note the --data-binary:

curl --request POST \
  --url http://127.0.0.1:8081/track \
  --header 'Accept: */*' \
  --header 'Accept-Encoding: gzip, deflate' \
  --header 'Connection: keep-alive' \
  --header 'Content-Encoding: gzip' \
  --header 'Content-Length: 739' \
  --header 'Content-Type: application/json' \
  --header 'Host: 127.0.0.1:8081' \
  --data-binary @package.json.gz

PS trying the curl with the @, the payload sent was 1-byte length

Manuel Spigolon
  • 11,003
  • 5
  • 50
  • 73