fastify / fastify

Fast and low overhead web framework, for Node.js
https://www.fastify.dev
Other
31.42k stars 2.22k forks source link

Custom bodyLimit is not taken into account, so fallback on default limit of 1MiB #5533

Open DamienDeSousa opened 3 weeks ago

DamienDeSousa commented 3 weeks ago

Prerequisites

Fastify version

4.21.0

Plugin version

No response

Node.js version

18.19.0

Operating system

macOS

Operating system version (i.e. 20.04, 11.3, 10)

13.4

Description

I get the following error from Fastify : FastifyError [FST_ERR_CTP_BODY_TOO_LARGE]: Request body is too large.
In the documentation, it says that I have to increase le the bodyLimit to avoid the error.

So I did this:

import Fastify from 'fastify'

const app = Fastify({
  logger: true,
  bodyLimit: 10485760, // 10MiB
})

When I send a 1.7 MiB file, I still have the issue. I've tested with a 129KiB file, and in this case everything works fine.

So I guess, the custom limit is ignored and the default one is effective (1MiB).

Link to code that reproduces the bug

No response

Expected Behavior

Expected behaviour : able to send a payload with a a custom limit set on the server. Current behaviour : unable to send a payload because the custom limit is ignored.

metcoder95 commented 3 weeks ago

Can you provide an Minimum Reproducible Example to support you better?

Tried with the following sample and couldn't reproduce it:

const fastify  = require('fastify')({ logger: true, bodyLimit: 5 * 1024 })

const payload = Buffer.allocUnsafe(5 * 1024).fill('a');

fastify.post('/upload', async (req, reply) => ({ length: req.headers['content-length'] }));

fastify.inject({
  method: 'POST',
  url: '/upload',
  headers: { 'content-type': 'text/plain' },
  payload,
}).then(response => {
  console.log(response.statusCode); // 413
  console.log(response.body); // {"statusCode":413,"error":"Payload Too Large","message":"Payload Too Large"}
}).catch(console.error);
DamienDeSousa commented 3 weeks ago

Hello ! Thank you for answering !

Yes of course, here is my code api/serverless.ts :

'use strict'

// Read the .env file.
import * as dotenv from 'dotenv'
dotenv.config()

// Require the framework
import Fastify, { FastifyReply, FastifyRequest } from 'fastify'

// Instantiate Fastify with some config
const app = Fastify({
  logger: true,
  bodyLimit: 10485760,
})

// Register your application as a normal plugin.
app.register(import('../src/app'))

export const maxDuration = 300

export default async (req: FastifyRequest, res: FastifyReply) => {
  await app.ready()
  app.server.emit('request', req, res)
}

Maybe it is related, I host my project on Vercel.

jsumners commented 3 weeks ago

Please read the link that @metcoder95 provided.

climba03003 commented 2 weeks ago

The author said the bodyLimit is not taken into account, so the reproducible code should try the payload bytes fall between the default limit and specified limit.

The below example shows the bodyLimit work as expected and reply with 200

import Fastify from 'fastify';

const fastify = Fastify({ logger: true, bodyLimit: 5 * 1024 })
const payload = Buffer.allocUnsafe(4 * 1024).fill('a');

fastify.post('/upload', async (req, reply) => ({ length: req.headers['content-length'] }));

const response = await fastify.inject({
  method: 'POST',
  url: '/upload',
  headers: { 'content-type': 'text/plain' },
  payload,
})
console.log(response.statusCode); // 200
console.log(response.body); // {"length":"4096"}

Note that if you are using @fastify/multipart or others plugin. You should specify the limit in the plugin level, because most of them ignore the server specified one.

DamienDeSousa commented 1 week ago

Thank you @climba03003 !
So I guess it is because I host my project on vercel. I should set the bodyLimit in another way.
I don't use @fastify/multipart or other plugin.

Do you have an idea or another way I can achieve this ?

Uzlopak commented 1 week ago

Isnt vercel already body parsing? So if you upload a gzip, then it is already un-gzipped and bigger than you expect?