Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bin/jss.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ program
.option('--cors-proxy-max-bytes <n>', 'CORS proxy upstream response size cap (default 50MB)', parseInt)
.option('--cors-proxy-timeout-ms <ms>', 'CORS proxy upstream request timeout (default 30s)', parseInt)
.option('--cors-proxy-max-redirects <n>', 'CORS proxy max redirect hops, each re-validated (default 5)', parseInt)
.option('--body-limit <size>', 'Maximum request body size, e.g. 100MB or 1GB (default 10MB). Raise to accept larger `git push`; lower for tighter memory-DoS protection.')
.option('--body-limit <size>', 'Maximum request body size, e.g. 100MB or 1GB (default 20MB). Raise to accept larger `git push`; lower for tighter memory-DoS protection.')
.option('--nostr', 'Enable Nostr relay')
.option('--no-nostr', 'Disable Nostr relay')
.option('--nostr-path <path>', 'Nostr relay WebSocket path (default: /relay)')
Expand Down
11 changes: 6 additions & 5 deletions src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ export const defaults = {
host: '0.0.0.0',
root: './data',
// Maximum request body size in bytes (or a size string when supplied
// via CLI / config file, e.g. "100MB"). Default 10 MiB matches the
// previous hard-coded Fastify limit. Operators hosting personal pods
// may want to raise this so that large `git push` of an established
// app repo doesn't 413 — see #474.
bodyLimit: 10 * 1024 * 1024,
// via CLI / config file, e.g. "100MB"). 20 MiB default (#563) — a
// generous out-of-the-box limit for common workloads (larger `git
// push`, media uploads, bigger RDF documents). Raise via --body-limit
// / JSS_BODY_LIMIT for established app repos (#474); lower it for
// tighter memory-DoS protection.
bodyLimit: 20 * 1024 * 1024,

// SSL
sslKey: null,
Expand Down
4 changes: 2 additions & 2 deletions src/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,8 @@ export function createServer(options = {}) {
// already coerced by parseEnvValue) pass through unchanged; strings
// ("100MB" from CLI / config files) go through parseSize for
// size-shorthand support. The typeof check matters because parseSize
// calls `.match` on its input and would throw on a raw number. Default
// matches the previous hard-coded 10 MiB cap. See #474.
// calls `.match` on its input and would throw on a raw number. Falls
// back to defaults.bodyLimit (20 MiB, #563) when unset. See #474.
const bodyLimit = options.bodyLimit == null
? defaults.bodyLimit
: (typeof options.bodyLimit === 'number' ? options.bodyLimit : parseSize(options.bodyLimit));
Expand Down
14 changes: 12 additions & 2 deletions test/body-limit.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
*
* Tests here verify the surface end-to-end — server actually rejects
* over-size requests with 413, AND the size-string parsing path works
* the same as the numeric path. The default (10 MiB) is covered
* implicitly by every other test in the suite continuing to pass.
* the same as the numeric path. The out-of-the-box default (20 MiB
* since #563) is pinned explicitly via Fastify's initialConfig.
*/

import { describe, it, before, after, afterEach } from 'node:test';
Expand Down Expand Up @@ -102,4 +102,14 @@ describe('configurable bodyLimit (#474)', () => {
assert.notStrictEqual(res.status, 413,
`100-byte body under a 10KB cap should not 413; got ${res.status}`);
});

it('defaults to a 20 MiB body limit when none is configured (#563)', async () => {
await fs.emptyDir(TEST_DATA_DIR);
server = createServer({ logger: false, forceCloseConnections: true, root: TEST_DATA_DIR });
// Pin the EFFECTIVE wired default, not the constant in isolation:
// Fastify freezes resolved options into initialConfig, so this
// exercises config.defaults.bodyLimit → createServer → Fastify.
assert.strictEqual(server.initialConfig.bodyLimit, 20 * 1024 * 1024,
`expected the out-of-the-box default to be 20 MiB; got ${server.initialConfig.bodyLimit}`);
});
});