mirror of
https://github.com/bookorbit/bookorbit.git
synced 2026-11-03 08:21:39 -06:00
fix(server): accept empty requests with unsupported media types
Inject an empty JSON object for requests that have an unsupported content type but zero content length. Fastify defaults to rejecting these with a 415 error. Closes #348
This commit is contained in:
@@ -1,4 +1,11 @@
|
||||
import { UnsupportedMediaTypeException } from '@nestjs/common';
|
||||
import type { FastifyInstance } from 'fastify';
|
||||
import type { IncomingHttpHeaders } from 'http';
|
||||
import { Readable } from 'stream';
|
||||
|
||||
const DEFAULT_TRUST_PROXY = 'loopback,linklocal,uniquelocal';
|
||||
const EMPTY_JSON_BODY = '{}';
|
||||
const BODY_METHODS = new Set(['DELETE', 'PATCH', 'POST', 'PUT']);
|
||||
|
||||
export function parseTrustProxy(value: string | undefined): string | boolean | number {
|
||||
const raw = value?.trim();
|
||||
@@ -52,3 +59,33 @@ export function buildCspDirectives(options: CspOptions = {}) {
|
||||
upgradeInsecureRequests: null,
|
||||
};
|
||||
}
|
||||
|
||||
export function shouldInjectEmptyJsonBody(method: string, headers: IncomingHttpHeaders): boolean {
|
||||
const contentType = getHeaderValue(headers['content-type'])?.toLowerCase();
|
||||
if (!BODY_METHODS.has(method.toUpperCase()) || !contentType?.startsWith('application/json')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const contentLength = getHeaderValue(headers['content-length'])?.trim();
|
||||
return contentLength === undefined || contentLength === '0';
|
||||
}
|
||||
|
||||
export function buildEmptyJsonBodyStream(headers: IncomingHttpHeaders): Readable {
|
||||
headers['content-length'] = String(Buffer.byteLength(EMPTY_JSON_BODY));
|
||||
return Readable.from([EMPTY_JSON_BODY]);
|
||||
}
|
||||
|
||||
export function registerEmptyBodyContentTypeParser(fastify: FastifyInstance): void {
|
||||
fastify.addContentTypeParser<string>('*', { parseAs: 'string' }, (request, body, done) => {
|
||||
if (BODY_METHODS.has(request.method.toUpperCase()) && body.length === 0) {
|
||||
done(null, {});
|
||||
return;
|
||||
}
|
||||
|
||||
done(new UnsupportedMediaTypeException('Unsupported Media Type'));
|
||||
});
|
||||
}
|
||||
|
||||
function getHeaderValue(value: string | string[] | undefined): string | undefined {
|
||||
return Array.isArray(value) ? value[0] : value;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user