Skip to content

Commit 6bb6c9e

Browse files
committed
[breaking] limit adapter-node request size
1 parent f1e762b commit 6bb6c9e

File tree

5 files changed

+34
-5
lines changed

5 files changed

+34
-5
lines changed

.changeset/tricky-ducks-kneel.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@sveltejs/adapter-node': patch
3+
'@sveltejs/kit': patch
4+
---
5+
6+
[breaking] limit adapter-node request size

packages/adapter-node/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ Instead, we read from the _right_, accounting for the number of trusted proxies.
6969

7070
> If you need to read the left-most address instead (and don't care about spoofing) — for example, to offer a geolocation service, where it's more important for the IP address to be _real_ than _trusted_, you can do so by inspecting the `x-forwarded-for` header within your app.
7171
72+
### `BODY_SIZE_LIMIT`
73+
74+
The maximum request body size to accept in bytes. Defaults to 512kb. This option does not allow streaming. You can disable this option with a value of 0 and implement a custom check in [`handle`](https://kit.svelte.dev/docs/hooks#server-hooks-handle) if you need something more advanced.
75+
7276
## Options
7377

7478
The adapter can be configured with various options:

packages/adapter-node/src/handler.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ const server = new Server(manifest);
1414
await server.init({ env: process.env });
1515
const origin = env('ORIGIN', undefined);
1616
const xff_depth = parseInt(env('XFF_DEPTH', '1'));
17-
1817
const address_header = env('ADDRESS_HEADER', '').toLowerCase();
1918
const protocol_header = env('PROTOCOL_HEADER', '').toLowerCase();
2019
const host_header = env('HOST_HEADER', 'host').toLowerCase();
20+
const body_size_limit = parseInt(env('BODY_SIZE_LIMIT', '524288'));
2121

2222
const dir = path.dirname(fileURLToPath(import.meta.url));
2323

@@ -49,7 +49,11 @@ const ssr = async (req, res) => {
4949
let request;
5050

5151
try {
52-
request = await getRequest({ base: origin || get_origin(req.headers), request: req });
52+
request = await getRequest({
53+
base: origin || get_origin(req.headers),
54+
request: req,
55+
bodySizeLimit: body_size_limit
56+
});
5357
} catch (err) {
5458
res.statusCode = err.status || 400;
5559
res.end(err.reason || 'Invalid request body');

packages/kit/src/exports/node/index.js

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ import * as set_cookie_parser from 'set-cookie-parser';
22

33
/**
44
* @param {import('http').IncomingMessage} req
5+
* @param {number} [body_size_limit]
56
*/
6-
function get_raw_body(req) {
7+
function get_raw_body(req, body_size_limit) {
78
const h = req.headers;
89

910
if (!h['content-type']) {
@@ -20,6 +21,19 @@ function get_raw_body(req) {
2021
return null;
2122
}
2223

24+
if (body_size_limit) {
25+
if (!length) {
26+
throw new Error(
27+
`Received content-length of ${length}. content-length must be provided when body size limit is specified.`
28+
);
29+
}
30+
if (length > body_size_limit) {
31+
throw new Error(
32+
`Received content-length of ${length}, but only accept up to ${body_size_limit} bytes.`
33+
);
34+
}
35+
}
36+
2337
if (req.destroyed) {
2438
const readable = new ReadableStream();
2539
readable.cancel();
@@ -69,7 +83,7 @@ function get_raw_body(req) {
6983
}
7084

7185
/** @type {import('@sveltejs/kit/node').getRequest} */
72-
export async function getRequest({ request, base }) {
86+
export async function getRequest({ request, base, bodySizeLimit }) {
7387
let headers = /** @type {Record<string, string>} */ (request.headers);
7488
if (request.httpVersionMajor === 2) {
7589
// we need to strip out the HTTP/2 pseudo-headers because node-fetch's
@@ -85,7 +99,7 @@ export async function getRequest({ request, base }) {
8599
return new Request(base + request.url, {
86100
method: request.method,
87101
headers,
88-
body: get_raw_body(request)
102+
body: get_raw_body(request, bodySizeLimit)
89103
});
90104
}
91105

packages/kit/types/ambient.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,7 @@ declare module '@sveltejs/kit/node' {
411411
export function getRequest(opts: {
412412
base: string;
413413
request: import('http').IncomingMessage;
414+
bodySizeLimit?: number;
414415
}): Promise<Request>;
415416
export function setResponse(res: import('http').ServerResponse, response: Response): void;
416417
}

0 commit comments

Comments
 (0)