Skip to content

Commit 0799344

Browse files
committed
Fixes
1 parent b29a913 commit 0799344

6 files changed

Lines changed: 53 additions & 9 deletions

File tree

examples/basic/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
},
1010
"devDependencies": {
1111
"@preact/preset-vite": "^2.9.4",
12+
"@viact/cli": "workspace:*",
1213
"@viact/vite-plugin": "workspace:*",
1314
"preact": "^10.26.9",
1415
"preact-render-to-string": "^6.5.13",

examples/basic/src/middleware/auth.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import type { MiddlewareFn } from "viact";
22

3+
// ⚠️ NOT FOR PRODUCTION — This is a minimal example only.
4+
// A real implementation should:
5+
// - Verify the session token with a cryptographic signature (e.g. HMAC)
6+
// - Check token expiry
7+
// - Set cookie attributes: HttpOnly, Secure, SameSite=Lax, Path=/
38
export const middleware: MiddlewareFn = async ({ request }) => {
49
const hasSession = request.headers.get("cookie")?.includes("session=") ?? false;
510

examples/cloudflare/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
},
1010
"devDependencies": {
1111
"@preact/preset-vite": "^2.9.4",
12+
"@viact/cli": "workspace:*",
1213
"@viact/vite-plugin": "workspace:*",
1314
"preact": "^10.26.9",
1415
"preact-render-to-string": "^6.5.13",

packages/adapter-node/src/index.ts

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,17 @@ export function createNodeRequestHandler<TContext = unknown>(
4343
const staticDir = options.staticDir;
4444

4545
return async (req: IncomingMessage, res: ServerResponse): Promise<void> => {
46-
const request = await createWebRequest(req);
46+
let request: Request;
47+
try {
48+
request = await createWebRequest(req);
49+
} catch (err) {
50+
if (err instanceof Error && err.message === "Request body too large") {
51+
res.statusCode = 413;
52+
res.end("Payload Too Large");
53+
return;
54+
}
55+
throw err;
56+
}
4757
const url = new URL(request.url);
4858

4959
// --- ISG stale-while-revalidate for GET requests ---
@@ -225,16 +235,20 @@ function createHeaders(headers: IncomingMessage["headers"]): Headers {
225235
return result;
226236
}
227237

238+
const MAX_BODY_SIZE = 1024 * 1024; // 1 MB
239+
228240
async function readRequestBody(req: IncomingMessage): Promise<Uint8Array> {
229241
const chunks: Uint8Array[] = [];
242+
let totalSize = 0;
230243

231244
for await (const chunk of req) {
232-
if (typeof chunk === "string") {
233-
chunks.push(Buffer.from(chunk));
234-
continue;
245+
const buf = typeof chunk === "string" ? Buffer.from(chunk) : chunk;
246+
totalSize += buf.byteLength;
247+
if (totalSize > MAX_BODY_SIZE) {
248+
req.destroy();
249+
throw new Error("Request body too large");
235250
}
236-
237-
chunks.push(chunk);
251+
chunks.push(buf);
238252
}
239253

240254
return Buffer.concat(chunks);

packages/cli/bin/viact.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,12 @@ async function preview() {
280280
}
281281

282282
// Try static file first
283-
const filePath = join(clientDir, url);
283+
const filePath = resolve(clientDir, "." + url);
284+
if (!filePath.startsWith(clientDir + "/") && filePath !== clientDir) {
285+
res.statusCode = 403;
286+
res.end("Forbidden");
287+
return;
288+
}
284289
if (existsSync(filePath) && statSync(filePath).isFile()) {
285290
const ext = extname(filePath);
286291
const headers = {

packages/vite-plugin/src/index.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,17 @@ function createDevSSRMiddleware(
262262
server.ssrLoadModule(VIACT_SERVER_MODULE_ID),
263263
]);
264264

265-
const webRequest = await nodeToWebRequest(req);
265+
let webRequest: Request;
266+
try {
267+
webRequest = await nodeToWebRequest(req);
268+
} catch (err) {
269+
if (err instanceof Error && err.message === "Request body too large") {
270+
res.statusCode = 413;
271+
res.end("Payload Too Large");
272+
return;
273+
}
274+
throw err;
275+
}
266276
const response = await framework.handleViactRequest({
267277
app: serverMod.resolvedApp,
268278
registry: serverMod.registry,
@@ -322,9 +332,17 @@ async function nodeToWebRequest(req: IncomingMessage): Promise<Request> {
322332
const init: RequestInit = { method, headers };
323333

324334
if (!BODYLESS_METHODS.has(method.toUpperCase())) {
335+
const MAX_BODY_SIZE = 1024 * 1024; // 1 MB
325336
const chunks: Uint8Array[] = [];
337+
let totalSize = 0;
326338
for await (const chunk of req) {
327-
chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
339+
const buf = typeof chunk === "string" ? Buffer.from(chunk) : chunk;
340+
totalSize += buf.byteLength;
341+
if (totalSize > MAX_BODY_SIZE) {
342+
req.destroy();
343+
throw new Error("Request body too large");
344+
}
345+
chunks.push(buf);
328346
}
329347
const body = Buffer.concat(chunks);
330348
if (body.byteLength > 0) {

0 commit comments

Comments
 (0)