プレイグラウンド、サンドボックス、使い捨てスクリプト置き場
0

Configure Feed

Select the types of activity you want to include in your feed.

HTMLリクエストロジックを整理

Kohei Watanabe (Jun 17, 2025, 8:46 AM +0900) 53a7830d 072752c5

+15 -10
+15 -10
deno/server.tsx
··· 1 1 #!/usr/bin/env -S deno run --watch -A 2 2 /* @jsxImportSource npm:hono/jsx */ 3 3 import { writeFile } from "node:fs/promises"; 4 - import { Context, Hono } from "npm:hono"; 4 + import { type Context, Hono } from "npm:hono"; 5 5 import { HTTPException } from "npm:hono/http-exception"; 6 + import type { JSX } from "npm:hono/jsx/jsx-runtime"; 6 7 7 8 if (import.meta.main) { 8 9 const app = new Hono(); 9 10 10 11 app.get("/", (c) => c.redirect("/index.html")); 11 12 app.get("/:file", async (c) => { 12 - const file = new URL(c.req.param("file"), import.meta.url).href; 13 + try { 14 + // INSECURE 15 + const file = new URL(c.req.param("file"), import.meta.url).href; 13 16 14 - try { 15 - if ( 16 - c.req.header("accept")?.match(/\btext\/html\b/) && 17 - (c.req.queries("edit") || file.match(/[.][jt]sx?$/)) 18 - ) { 19 - const path = c.req.queries("edit") ? import.meta.url : file; 20 - const { default: Component } = await import(path); 21 - return c.html(Component(c)); 17 + if (c.req.header("accept")?.match(/\btext\/html\b/)) { 18 + if (c.req.queries("edit")) { 19 + return c.html(EditorPage(c)); 20 + } 21 + if (file.match(/[.][jt]sx?$/)) { 22 + const mod = await import(file); 23 + const res: Response | JSX.Element = mod.default(c); 24 + return res instanceof Response ? res : c.html(res); 25 + } 22 26 } 23 27 24 28 return await fetch(file); ··· 28 32 }); 29 33 30 34 app.post("/:file", async (c) => { 35 + // INSECURE 31 36 const file = c.req.param("file"); 32 37 const body = await c.req.text(); 33 38 await writeFile(file, body);