Closed UncleFirefox closed 1 year ago
Nest does not add req.rawBody
based on the raw income, rather it modifies the body-parser signature for application/json
and application/x-www-form-urlencoded
to take the original raw body and set it to req.rawBody
. This means that if you send a data type that does not match, then req.rawBody
will not be set.
@UncleFirefox feel free to update the docs on raw body to mention the behavior described above.
@jmcdo29 I was thinking about being able to include application/octet-stream
along with the others you mentioned, I believe it would be useful for other people would it be so hard to do so? I could contribute if you tell me where the code resides in nest.
Cheers!
@UncleFirefox
@micalevisk can you say more, please? It's a year later, and I'm encountering this issue but there are zero docs. You've provided two links, but it's unclear what someone needs to do to receive other content types.
@clintonb please use our discord for support
I don't recall neither
I adapted https://stackoverflow.com/a/61416426/592820. This requires installing raw-body. I have rawBody: true
on the NestFactory.create()
call, but have no clue if it's required to get the raw body to the controller. I need it to handle AWS signature verification for the S3 proxy I'm building.
I created a decorator to apply to a controller route's arguments.
import {
BadRequestException,
ExecutionContext,
createParamDecorator,
} from '@nestjs/common';
import getRawBody from 'raw-body';
export const RawBody = createParamDecorator(
async (_, context: ExecutionContext) => {
const req = context.switchToHttp().getRequest<import('express').Request>();
if (!req.readable) {
throw new BadRequestException('Invalid body');
}
return getRawBody(req);
}
);
Here it is in action:
// controller.ts
@Put('*')
@Header('Content-Type', 'application/xml')
async put(@Req() request, @Param() params, @RawBody() body) {
const name = request.params[0];
return this.s3ProxyService.putObject({
bucketName: BUCKET,
name,
content: body,
});
}
this should be enough: https://stackoverflow.com/a/75642036 (as per https://docs.nestjs.com/faq/raw-body)
I tried that. It doesn't seem to work with binary data. body
is set to an empty object ({}
) and rawBody
is undefined
.
I also tried setting app.useBodyParser('raw')
.
Note: I suspect the reason none of the other solutions work in my case is because the S3 client does not set a Content-Type
header automatically, but expects the caller to do so. The parsers aren't triggered because the non-existent content type does not match expectations.
Using something like this sets rawBody
, but causes other issues with my signature verification. I'll share here as I learn more.
app.useBodyParser('raw', {
type: (req) => {
// Apply to *all* requests, regardless of content type.
return true;
},
});
Is there an existing issue for this?
Current behavior
Hi, I'm trying to use the rawBody feature with binary in Postman but it does not work.
I thought passing binary would have the buffer value field on req.rawBody but it does not, is this intended to work with binary? NOTE: I configured the feature correctly and if I pass a raw json I see a buffer there so I guess rawBody works but not for this case?
Some people created this gist but I find it rather ugly: https://gist.github.com/jonilsonds9/efc228e34a298fa461d378f48ef67836
Minimum reproduction code
-
Steps to reproduce
No response
Expected behavior
req.rawBody has the buffer of the attached file
Package
Other package
No response
NestJS version
No response
Packages versions
Node.js version
No response
In which operating systems have you tested?
Other
No response