express icon indicating copy to clipboard operation
express copied to clipboard

Getting request size

Open SKFrozenCloud opened this issue 1 year ago • 2 comments

Is this a valid way of recording the request size:

app.use(function logger(req, res, next) {
    req.body._requestSize = 0;

    req.on('data', (chunk) => {
      req.body._requestSize += Buffer.from(chunk).length;
    });

    next();
  });

app.use(bodyParser.json())

My concern is that as soon as the req.on('data', ...) is executed the stream will be in flowing mode and if the rest of the application does not subscribe to the stream fast enough they will miss some data. But I don't know the exact behavior of Node and ExpressJS.

SKFrozenCloud avatar Jun 25 '22 06:06 SKFrozenCloud

Another option is to get the request size through content-length http header. However this content-length is not guaranteed to be included on the request from the client.

const size = req.headers['content-length']

0ss avatar Jun 28 '22 22:06 0ss

~~You can use this middleware I made: express-request-size.~~ Oh, you meant body size. You can make what you've done reliable by awaiting for all the chunks to arrive.

app.use(async function(req, res, next) {
    req.bodySize = await new Promise(function(resolve) {
        let requestSize = 0;
        req.on('data', (chunk) => {
            requestSize += Buffer.from(chunk).length;
        });
        req.on('end', () => {
            resolve(requestSize);
        });
    });
    next();
});

I've tested this and it works fine.

Maytha8 avatar Oct 07 '22 13:10 Maytha8

Is this a valid way of recording the request size:

app.use(function logger(req, res, next) {
    req.body._requestSize = 0;

    req.on('data', (chunk) => {
      req.body._requestSize += Buffer.from(chunk).length;
    });

    next();
  });

app.use(bodyParser.json())

My concern is that as soon as the req.on('data', ...) is executed the stream will be in flowing mode and if the rest of the application does not subscribe to the stream fast enough they will miss some data. But I don't know the exact behavior of Node and ExpressJS.

In Node.js and Express, the code snippet you provided is not a valid way to accurately record the request size. The reason is that the req.on('data', ...) event is used for handling incoming data streams, such as when you're processing file uploads or streaming data from the client. However, for regular JSON data or URL-encoded form data, the req.on('data', ...) event may not capture the entire request body.

So a more reliable approach to accurately record the request size in Express would be to use middleware that runs after the body has been parsed. You can achieve this by modifying the code as follows:

Bhupi2508 avatar Jun 07 '23 11:06 Bhupi2508

~You can use this middleware I made: express-request-size.~ Oh, you meant body size. You can make what you've done reliable by awaiting for all the chunks to arrive.

app.use(async function(req, res, next) {
    req.bodySize = await new Promise(function(resolve) {
        let requestSize = 0;
        req.on('data', (chunk) => {
            requestSize += Buffer.from(chunk).length;
        });
        req.on('end', () => {
            resolve(requestSize);
        });
    });
    next();
});

I've tested this and it works fine.

Im pretty sure this approach will break most body parsers

b1ek avatar Jul 18 '23 03:07 b1ek