In my express app, I want to check the body length and limit it regardless of content-type. After this, I want to parse the body if content type is json. How can I achieve this? At the moment my code is like the following but server stops at express.json() middle-ware:
const express = require('express')
const contentType = require('content-type')
const getRawBody = require('raw-body')
const app = express()
app.use(function(req, res, next) {
const cType = req.headers['content-type'] || ''
getRawBody(req, {
length: req.headers['content-length'],
limit: '1mb',
encoding: contentType.parse(cType).parameters.charset
}, function(err, string) {
if(err) {
next(err)
}
next()
})
})
app.use(express.json())
CodePudding user response:
You cannot implement things that way. express.json()
expects to read the body contents from the incoming stream. But, raw-body
has already read the body contents from the stream so when express.json()
tries to read it, it gets stuck waiting for there to be something to read.
Since express.json()
does two things, read the body from the stream and then parse it into JSON, it should be easy to replace those two things with your own version. The first is already done (reading the body) so all you have to do is to call JSON.parse()
on the raw body contents that you already read if (and only if), the content-type is "application/json"
. Remove the call to express.json()
:
app.use(function(req, res, next) {
const cType = req.headers['content-type'] || ''
getRawBody(req, {
length: req.headers['content-length'],
limit: '1mb',
encoding: contentType.parse(cType).parameters.charset
}, function(err, string) {
if(err) {
next(err)
} else {
if (req.get('Content-Type').toLowerCase() === "application/json") {
try {
// try parsing the body as JSON
req.body = JSON.parse(req.body);
next();
} catch(e) {
console.log(e);
next(e);
}
} else {
// not JSON, will leave the raw body in req.body
next();
}
}
})
})
Note, if your app is expecting any other content-types (like form data), you will also have to manually parse them since the standard express middleware for those other types will have the same issue.