How to get byte size of request?
Five years later, this is Google's first link for this question.
But no npm module is needed here. And req.socket.bytesRead
number cannot be used either, because every byte read by the socket is counted, even the HTTP header. Worse, for the same socket, next requests continue to increment the value.
The best way is to use a simple counter for each chunk of data:
// Set up the byte counter
let byteCount = 0
// Listen the chunk events
req.on('data', (chunk) => {
// Increment the byte counter
byteCount += Buffer.from(chunk).length
// Check the body byte length
if(byteCount > REQ_BYTE_MAX) {
// Return an error to the client
res.writeHead(413, { 'Content-Type': 'text/plain' })
res.end('Request content is larger than the limit.')
}
})
You can not use req.socket.bytesRead
because socket
is reusable, so bytesRead
is a size of total traffic passed over given socket
and not the size of a specific request.
A quick solution that I used - a tiny middleware (I use Express):
const socketBytes = new Map();
app.use((req, res, next) => {
req.socketProgress = getSocketProgress(req.socket);
next();
});
/**
* return kb read delta for given socket
*/
function getSocketProgress(socket) {
const currBytesRead = socket.bytesRead;
let prevBytesRead;
if (!socketBytes.has(socket)) {
prevBytesRead = 0;
} else {
prevBytesRead = socketBytes.get(socket).prevBytesRead;
}
socketBytes.set(socket, {prevBytesRead: currBytesRead})
return (currBytesRead-prevBytesRead)/1024;
}
And then you can use req.socketProgress
in your middlewares.
You can use req.socket.bytesRead
or you can use the request-stats module.
var requestStats = require('request-stats');
var stats = requestStats(server);
stats.on('complete', function (details) {
var size = details.req.bytes;
});
The details object looks like this:
{
ok: true, // `true` if the connection was closed correctly and `false` otherwise
time: 0, // The milliseconds it took to serve the request
req: {
bytes: 0, // Number of bytes sent by the client
headers: { ... }, // The headers sent by the client
method: 'POST', // The HTTP method used by the client
path: '...' // The path part of the request URL
},
res : {
bytes: 0, // Number of bytes sent back to the client
headers: { ... }, // The headers sent back to the client
status: 200 // The HTTP status code returned to the client
}
}
So you can get the request size from details.req.bytes
.
Another option is req.headers['content-length']
(but some clients might not send this header).